【Java工程师之路】[1-1.3]Java基本语法

Java是面向对象的编程语言,JVM的工作方式决定了Java具有“Write Once,Run Anywhere”的特点。Java数据类型、基本运算、变量和常量等,是构建Java程序的基础。Java程序由顺序、选择和循环三种基本结构组成,是结构化程序。网页设计中的Java程序,可以是Java Application、Java Applet或者JavaBean。Javadoc命令从文档注释语句中提取信息,根据程序结构生成HTML格式的程序文档。Java API对程序设计人员是非常有价值的资源。

1 Java语言的元素

任何编程语言都有组成语言的基本元素,包括数据类型、基本运算、变量和常量等,这些元素是构建程序的基础。Java语言的基本元素是构建Java程序的基础。

1.1  基本数据类型

数据不仅有值,还有类型。数据类型决定着数据的取值范围、及可以对此数据施行的运算。

Java语言定义了四类八种基本数据类型,分别是:

逻辑型:boolean

字符型:char

整型:byte,short,int,和long

浮点型:double和float

逻辑型数据有两个值,true和false。例如:

boolean truth = true; //声明了逻辑型变量truth,并为其赋值为true。

字符型数据描述了单一字符,由一对单引号括起。

例如:

'a'     表示字母a

'\t'    表示tab符,即横向制表符。其中,'\'起转义作用

'\u840c'   表示汉字萌

'\u2211'    表示字符∑

'\u????'    形式中的“????”由四位十六进制数字代替,表示特定的Unicode字符。

Java语言使用Unicode字符集。Unicode为国际字符集标准,由十六位二进制数据表示(人们熟悉的ASCII字符集由八位二进制数据表示),它足够大的字符空间,支持当前世界上使用的主要语言。Unicode字符集中包含了ASCII字符的一个子集(前128个字符)。

Java语言也有字符串型,写为String。String不是基本数据类型,而是一个类。

String型数据用一对双引号括起,可如下方式使用,如:

String greeting = "Hello World! ";

String errorMessage = "Record Not Found !";

整型数据byte,short,int和long,有三种形式:十进制、八进制和十六进制。如:

2           表示十进制整数 2

077         首位为0表示八进制整数值

0xBAAC       首位为0x表示十六进制整数值

整型常数的缺省类型为int。如果特别指定为long整数,需要使用“L”或者“l”后缀。如:27L或者27l。整型数据的取值范围如表1-1。

浮点型存储有小数位的数值,其所能表示的最大或最小值并不确定。参见表1-2。

表1-1  整数型

类型

整数长度

取     值     范     围

byte

8 bit

-27 – 27 -1(-128 – 127, or 256)

short

16 bit

-215 – 215 -1(-32,768 to 32,767, or 65,535)

int

32 bit

-231 – 231 -1(-2,147,483,648 – 2,147,483,647 or 4,294,967,296)

long

64 bit

-263 – 263 -1(-9,223,372,036,854,775,808 to 9,223,372,036854,775,807, or 18,446,744,073,709,551,616)

表1-2  浮点型

类 型

浮点长度

允许的常数值示例

float

32 bits

99F,-327,456,99.01F ,4.2E6F(4.2 * 106的工程记数法)

double

64 bits

-1111,2.1E12,999,701,327,456,99.999

1.2  变量和常量

变量有类型、名字和值。如:

int x, y;   //声明int型变量x和y

float z = 3.414f;  //声明float型变量z,并赋值3.414f

变量的名字,也称变量标识符。

为变量选用标识符,必须遵循Java标识符命名规则,避免使用Java关键字。同时,还应尽量遵循Java技术的命名约定,这些约定使代码更可读,而程序的可读性非常重要。

Java标识符用于命名Java类、方法或者变量等,命名规则为:

● 第一个字符可以是A-Z、a-z、_ 或 $。

● 第二个及其后字符可以是上述所列字符、或者0-9数字。

Java技术关键字参见表1-3。

表1-3  Java关键字

abstract

do

implements

protected

throws

boolean

double

import

public

transient

break

else

instanceof

return

true

byte

extends

int

short

try

case

false

interface

static

void

catch

final

long

strictpf

volatile

char

finally

native

super

while

class

float

new

switch

 

const

for

null

synchronized

 

continue

goto

package

this

 

default

if

private

throw

 

Java技术约定,变量标识符以小写字母开头。如果标识符由两个或者两个以上单词组成,则除标识符第一个字母外,大写每个单词的首字母。单词之间不用分隔符(如:下划线)。

使用变量目的是引用值,为便于了解变量值的含义,应该为变量选择既简单、又具有描述性的名字,尽量做到“顾名识义”。下面为一些好的标识符示例:

isFull、price、studentName

Java是区分大、小写字母,如:“order”与“Order”代表不同的标识符。

Java语言通过关键词“final”定义赋值后不能再更改的值,使其成为常量。如:

final double SALES_TAX = 6.25;

final double  PI = 3.14159;

试图改变常量的值,将引起编译错误。也就是说,除非在定义之初,否则不能为常量赋值。

命名常量标识符也要尽量做到“顾名识义”,同时遵循Java技术约定:常量的标识符全部使用大写字母,可以有下划线。

1.3  基本运算

运算符连接数据形成表达式,实现对数据的运算。基本运算包括赋值运算、算术运算、逻辑运算、关系运算、位运算和位移位运算等。

在表达式中,运算符与操作数间遵守结合性规则,各运算符间按照优先级进行运算。基本运算符的结合性和优先级参见表7-4,其中,“R”代表“Right”;“L”代表“Left”,表中出现在同一行的各运算符具有相同的优先级;出现在不同行的运算符优先级从上到下依次递减。

表1-4  运算符

结合性规则

运  算  符

R to L

++   --   +   -   ~   !(数据类型)

L to R

*   /   %

L to R

+   -

L to R

<<   >>   >>>

L to R

<   >   <=   >=   instanceof

L to R

==   !=

L to R

&

L to R

^

L to R

|

L to R

&&

L to R

||

R to L

?:

R to L

=    *=    /=    %=    +=    -=   <<=  
>>=     >>>=     &=      ^=       |=    

 

表1-4中,<<、>>和>>>是整数移位运算符。

<<(左移)的运算规则是:将运算分量的每个二进制位向左移动指定位数,被移出的高位部分将丢弃,右边空出的低位部分补0。

>>(右移),也称算术右移或带符号右移,运算规则是:将运算分量的每个二进制位向右移动指定位数,右边被移出的低位部分将丢弃,左边空出的高位部分用符号填充。

>>>为逻辑右移、也称无符号右移,运算规则是:将运算分量的每个二进制位向右移动指定位数,右边被移出的低位部分将丢弃,左边空出的高位部分用0填充。

赋值运算符将运算符右边表达式的值赋给左边的变量。而*=、/=、%=、+=、-=、<<=、>>=、>>>=、&=、^=、|=等称为复合赋值运算符,是对赋值表达式的简写。如:

a=a+2   等价于   a+=2

value >>>= 1等价于value = value>>>1

instanceof用于判断对象的类型。

例1-1  位的“与”运算,文件名BitDemo.java。

//引自“The Java Tutorial”

class BitDemo {

     public static void main(String[] args){

        int bitmask = 0x000F;

        int val = 0x2222;

        System.out.println(val & bitmask);

     }

}

运行结果:

2

Java语言规定源文件名是与类名绑定的,必须为类名加扩展名java,上例即BitDemo.java。因此,本书Java板块的实例,无须再专门指出每个Java类的源文件名。

1.4  赋值类型转换

数据类型的长度越长,即占用二进制位数越多,就认为其精度越高。无论是运算还是赋值,当数据类型不相同时,就会引起类型转换。在需要和允许的情况下,系统总是自动将变量向着更高精度类型的方向进行转换,避免引起信息丢失,这个过程也称类型提升(Promotion)。系统实现类型提升的重要前提条件是不会丢失信息。

在进行赋值时,只要被赋值变量的数据类型精度不低于赋值表达式的数据类型精度,就符合类型提升的条件,将是合法的赋值运算,并称表达式是赋值兼容的。如:

long bigval = 6; // 合法,6 为int型, 赋值兼容

int smallval = 99L; // 非法,99L是long型,无法实现类型提升

double z = 12.414F; //合法,12.414F为float型, 赋值兼容

float z1 = 12.414; // 非法,12.414为double型, 无法实现类型提升

如果将计算所得高精度的数据值赋给较低精度的变量,将会引起信息丢失,因此是系统所不允许的。需要程序员通过类型转换运算符“()”强制转换变量的数据类型,称为显式类型转换(cast)。如:

long bigValue = 99L; //合法,赋值运算符两边的数据类型相同

int squashed = bigValue; //非法,编译错误:可能会损失精度

int squashed =(int)bigValue; // 合法,对变量bigValue进行显式类型转换

int squashed = 99L; //非法,编译错误:可能会损失精度

int squashed =(int)99L; // 合法,但是不合理

int squashed = 99; // 合法,整型常量值的缺省类型为int

注意,在进行赋值运算时,Java语言与C语言不相同。在C语言中,将高精度数值赋给低精度变量是系统所允许的,不会出现编译错误。

在运算时,如果表达式所含各分量的数据类型不相同,系统将自动提升各变量到更高的精度类型,以避免信息丢失。例如:

long bigValue = 99L;

int squashed = 97;

bigValue =(squashed > bigValue)?squashed:bigValue;

//合法,bigValue的值为99

 squashed =(squashed < bigValue)?squashed:bigValue;

//非法,编译错误:(赋值运算)可能会引起精度损失

int a = 1;

double d = 1.5;

long l = 2l;

System.out.println(d=(a+l)*d); // 合法,输出4.5

// 表达式d=(a+l)*d 可简写为(d*=(a+l))

System.out.println(d*=(a+l*1.5)); //合法,输出6.0

System.out.println(l=(a+l)*d);

//非法,编译错误:(赋值运算)可能会引起精度损失


Java语句 

 Java语句含基本语句和控制流语句。基本语句完成一些基本操作,如声明、赋值等。控制流语句用于控制程序流程,决定语句执行的顺序,包括选择语句和循环语句。

Java是结构化的程序设计语言,其程序有顺序、选择和循环三种基本结构组成。Java语言没有goto 语句。

2.1  语句、空语句和块

Java中的每条语句均以分号(;)结束,可以是单行或多行代码。

只有一个分号(;)的语句称为空语句,用在语法上需要出现一个语句,但语义上并不需要任何行为的情况。这种情况在if、for或 while、do-while这样的控制流语句中常会发生。Java程序中允许使用任意数量的空语句。

块是以左大括号和右大括号为边界的语句集合。块在语法上等价于单个语句,能用在单个语句可以出现的任何地方。语句块可以嵌套。

Java是面向对象的语言,Java程序以类的形式模块化。在类声明中必须使用块,如:

public class Dog {

  private int weight;

}

2.2  选择语句

选择语句又称分支语句,用于改变程序顺序执行的流程,有选择地执行程序的不同部分。Java语言用于实现选择结构的语句有if和switch语句,可以实现单分支、双分支和多分支选择。

if语句的一般语法形式如下:

if(布尔表达式){

语句1或语句块1;

} else {

语句2或语句块2;

}

执行流程分别如图2.2和图2.3所示,其中else语句可缺省。

【Java工程师之路】[1-1.3]Java基本语法_第1张图片

图2.2  if语句:单分支结构                图2.3  if-else语句:双分支结构

if-else语句可以嵌套,并经常用于处理多分支选择的问题。各个布尔表达式依次求值,一旦某个布尔表达式值为true,那么就执行与之相关的语句,从而终止整个语句序列的执行。如果所有表达式值为false,就执行最后一个else的相关部分。其语法形式如下:

if(布尔表达式1)

  语句1或语句块1

else  if(布尔表达式2)

  语句2或语句块2

else  if(布尔表达式3)

  语句3或语句块3

  ……

else  if(布尔表达式n)

  语句n或语句块n

else

  语句n+1或语句块n+1

switch语句是一种多分支选择语句,常用来实现多选择程序结构。其一般语法形式为:

switch(表达式){

case  常量表达式1: 语句或语句块1;break;

case  常量表达式2:  语句或语句块2;break;

……

case  常量表达式n:  语句或语句块n;break;

default: 语句或语句块n+1 break;

}

switch语句中的

case 常量表达式:

只起到标号的作用,用来指定语句执行的入口位置。如果case标号与switch表达式的值相匹配,就将从这个case标号的相关语句开始,执行包括其后所有case标号的语句序列以及default的语句序列。因此,为了实现正确的控制流程,需要使用break语句。

需要注意,每个case标号的常量表达式值各不相同。也就是说,case标号应该唯一。

switch语句中的default部分是任选的。如果所有case标号与switch表达式的值均不匹配,那么执行default的语句序列。虽然default部分可出现在switch语句的任何位置,但通常将其放在最后。

2.3  循环语句

Java语言的while、for和do-while语句都提供实现行为重复的功能,称为循环语句。while循环语句的一般语法形式为:

while(布尔表达式){

  语句或语句块;

}

while语句的执行流程如图2.4所示,for语句的执行流程如图2.5所示。

【Java工程师之路】[1-1.3]Java基本语法_第2张图片【Java工程师之路】[1-1.3]Java基本语法_第3张图片

 图2.4  while 语句执行流程                图2.5  for 语句的执行流程

for循环语句的一般语法形式为:

for(初始化表达式; 布尔表达式; 增量表达式){

  语句或语句块;

}

for(初始化表达式; 布尔表达式; 增量表达式)的三个表达式中,语法上任何一个都可以省略,但分号必须保留。缺省初始化表达式和增量表达式的for语句,其功能相当于while。

while与for这两个循环语句是先测试循环条件,再执行循环体。而do- while循环语句则是先执行循环体,再测试循环条件。只要条件为真,do-while循环就重复进行。区别在于,while与for语句可能出现不执行循环体的情况,而do- while语句的循环体至少要被执行一次,其条件测试语句在循环的底部。

do - while循环语句的一般语法形式为:

do{

语句或语句块

}while(布尔表达式)

无论for语句、while语句,还是do-while 语句,如果只有一条语句重复,那么大括号不是必需的。但是使用大括号程序结构更清楚,是良好的编程习惯。

例2-2  对int数据进行移位运算,并输出移位后的数值及位模式。

public class TestShift {

  // bitPattern(int)方法用于建立位模式

  public static String bitPattern(int value){

    int BIT1_MASK = 1;

    final char[] bits = new char[32];

    for(int i = 31; i >= 0; i--){

      if((value & BIT1_MASK)== 1){

            bits[i] = '1';

      } else {

            bits[i] = '0';

      }

      value >>>= 1;

    }

    return new String(bits);

  }

  public static void main(String[] args){

    int num1 = 1234;

    int num2 = -1234;

    System.out.println("num1(" + num1 + ")的位模式: " + bitPattern(num1));

    System.out.println("num2(" + num2 + ")的位模式: " + bitPattern(num2));

    System.out.println("" + num1 + " >> 5 =(" +(num1 >> 5)+ ")" + bitPattern(num1 >> 5));

    System.out.println("" + num2 + " >> 5 =(" +(num2 >> 5)+ ")" + bitPattern(num2 >> 5));

    System.out.println("" + num1 + " >>> 5 =(" +(num1 >>> 5)+ ")" + bitPattern(num1 >>> 5));

    System.out.println("" + num2 + " >>> 5 =(" +(num2 >>> 5)+ ")" + bitPattern(num2 >>> 5));

    System.out.println("" + num1 + " << 5 =(" +(num1 << 5)+ ")" + bitPattern(num1 << 5));

    System.out.println("" + num2 + " << 5 =(" +(num2 << 5)+ ")" + bitPattern(num2 << 5));

  }

}

运行结果:

num1(1234)的位模式: 00000000000000000000010011010010

num2(-1234)的位模式: 11111111111111111111101100101110

1234 >> 5 =(38)00000000000000000000000000100110

-1234 >> 5 =(-39)11111111111111111111111111011001

1234 >>> 5 =(38)00000000000000000000000000100110

-1234 >>> 5 =(134217689)00000111111111111111111111011001

1234 << 5 =(39488)00000000000000001001101001000000

-1234 << 5 =(-39488)11111111111111110110010111000000

2.4  break语句、continue语句和标号

在循环语句执行过程中,除了通过测试循环条件从循环语句的顶部或底部正常退出外,有时需要根据情况提前退出循环。正如break语句可以立即终止switch语句的执行,将控制流程转移到switch的下一条语句一样,break语句可用于中断循环,从for、while或do - while语句中提前退出。

continue语句绕过循环的剩余代码部分,强制执行循环条件测试。在 while与do-while语句中,continue语句的执行意味着控制流程转至测试循环条件部分;在for循环语句中,continue语句的执行则意味着控制流程转至增量表达式部分。continue语句只能用于循环语句,不能用于switch语句。

break和continue语句的区别在于,break中断整个循环的执行,而continue仅中断本次循环的执行,开始下一次循环。

特别要注意的是,break语句常出现在循环体包含的if-else结构中,但它的作用是退出循环,而不是跳出if-else结构。同时,break语句只终止包含它的for、while、do-while或者switch语句,它不会跳出嵌套的循环或者嵌套的switch语句。

标号是以冒号结尾的一个字符串,它的作用是指示程序中的一个位置点。如果需要一次退出多重循环,可以使用带标号的break语句。语法形式为:

break  标号;

其作用是跳出标号指示的循环,执行该循环的后续语句。

除带标号的break语句之外,还可以使用带标号的continue语句,其语法形式为:

continue  标号;

作用是中断本次循环,控制流程转向标号指定循环的条件判断,开始下一次循环。

一般来说,只建议将标号用于多重循环的外循环句首,目的是一次跳出多重循环,开始标号指定的循环语句的下一条语句(break)、或者下一次循环(continue)。

无论是break、continue语句,还是标号,都会影响程序的结构化,导致程序可读性下降。因此,Java语言中不只没有goto语句,也严格限制了标号的使用方式,并建议要尽量避免使用break或continue语句,除非这种做法极有效率和有必要,而通常情况下,总能找到解决问题的其他替代方式。

2.5  return语句和System.exit()方法

return语句从一个方法强制返回,并且可以为调用它的方法携带一个返回值。例如,下面的方法返回它的两个参数的乘积。

public int multiply(int a,int b){

  return a*b

}

如果当前方法是main主方法,则执行return语句将会退出应用程序。

要想从程序的任意地方直接一步到位地退出程序,可以使用System.exit()方法。

2.6  注释语句和javadoc

Java有三种注释语句。

//   单行注释

/*   */   一行或多行注释

/**   */   文档注释

注释语句与程序的缩进书写风格一样,对Java编译器不会产生更多的信息,但是有助于理解程序,增加程序的可读性。

Java的文档注释语句,可用于产生注释文档。

文档对于程序来说非常重要。尤其对于中型、大型程序来说,文档是协作开发以及进行维护的重要依据。传统方式需要手工编写程序文档,是一项极为枯燥、繁琐的工作,质量难以保证,效率也很低。当程序修改时,必须及时更新文档,这一点往往容易被编程人员忽略,实际操作时也有很多困难。

Java系统提供的javadoc工具可以根据程序结构自动产生文档。当程序修改时,方便及时更新文档。

javadoc命令从文档注释语句中提取文档,生成的程序文档十分专业。所输出的文件是HTML格式的,可以通过Web浏览器查看,参见例2-3。

例2-3  用javadoc生成下面程序HelloDate.java的文档。

import java.util.*;

/** 引自Thinking in Java的实例程序

 * Displays a string and today's date.

 * @author Bruce Eckel

 * @author www.MindView.net

 * @version 4.0

*/

public class HelloDate {

  /** Entry point to class & application.

   * @param args array of string arguments

   * @throws exceptions No exceptions thrown

  */

  public static void main(String[] args){

    System.out.println("Hello, it's: ");

    System.out.println(new Date());

  }

} /* Output:(55% match)

Hello, it's:

Wed Oct 05 14:39:36 MDT 2007

*/

运行结果:

Hello, it's:

Thu May 18 16:07:03 CST 2006

运行命令,为程序自动生成文档:

javadoc  HelloDate.java

【Java工程师之路】[1-1.3]Java基本语法_第4张图片

图2.6  运行javadoc的过程

javadoc在当前目录下生成了许多HTML文件,这些就是程序文档。其中,index.html文件是起始文档。打开该文件,显示内容如图2.7所示。

【Java工程师之路】[1-1.3]Java基本语法_第5张图片

图2.7  javadoc生成的HelloDate.java程序文档部分页面

javadoc命令可以带参数,下面的javadoc命令可以将版本和作者信息写入文档,更新后的文档如图2.8所示。

javadoc  HelloDate.java -version  -author

javadoc还可以一次性为整个包生成文档,命令形式为:

javadoc 包名

需要了解javadoc命令的更多用法,可以通过如下命令获得帮助。

javadoc –help

【Java工程师之路】[1-1.3]Java基本语法_第6张图片

图2.8  javadoc更新后的文档部分页面


3 Java API 

Java包含了许多预定义的类,用不同的目录将这些类归入相关集合,从而构成包,这些包的总和称为Java应用程序编程接口,即Java API。其中,每个包都提供了相对独立、相对完整和相对专用的功能,编程时可以根据功能需要导入相应包,或者导入包中的有关类和接口。借助API的预编写代码,程序员能够省时省力地编写出高品质的代码。Java API是Java最显著的优点之一,Java API文档对于程序设计人员是非常有价值的资源。在学习Java时,应该多花时间阅读Java API文档,

在程序需要使用Java API定义的包、类和接口时,通过import语句导入,使编译器知道从什么位置装入所需类和接口。图3.9基于功能分类示意了常用API包概图,详细资料请查阅Java API文档。

【Java工程师之路】[1-1.3]Java基本语法_第7张图片

图3.9  Java包的分类概图

Web中使用Java程序 

Java起源于Internet,适合编写基于Internet和基于WWW的应用程序,是有效的网络编程语言。事实上,Java具有更大的潜力,不仅用于网络编程,也适合创建大型应用程序。Java迅速发展成为一种功能强大而有效的编程工具,成为世界上重要的具有通用目的的一种编程语言。

Web中使用Java主要有以下几种方式:

(1)使用JDK自带的appletviewer.exe调用

这种方式使用Java程序,首先要编制扩展了Applet类的应用程序,基本形式为:

Import java.applet.*;

Public class className extends Applet

{

//Java程序体

}

然后要编制一个调用上述类的HTML页面文件(如为testApplet.htm),插入这个对象,即在其中写上:

<applet code=className.class height=givenHeight width=givenWidth>

</applet>

这里className是类名,givenHeight和givenWidth分别为给定的applet作为插件在网页中的高度和宽度。

最后在命令提示符下用appletviewer.exe运行:

appletviewer testApplet.htm

(2)采用基本JSP方式

夹在HTML网页中的Java语句组或程序,只要用开始符“<%”和结束符“%>”隔开,在页面任意地方都可以运行,可以犬牙交错与HTML互相穿插。这种页面需要用“.jsp”作为扩展名,不能直接点击运行,需要放在在Web服务器中以网址的形式访问。第1章中的三个例子即如此。详见本书JSP板块的第13章至第15章。

(3)采用Servlet方式

Servlet是用Java编写的服务器端小程序,与客户端的applet小程序对应。Servlet和applet分别在处于服务器和客户机两端。Servlet没有main方法,要继承特定的类,编写特定的方法。详见本书JSP板块的第17章。

(4)采用JavaBean方式

JavaBean作为Java语言写成的可重用组件,是一种特殊的类,在Web编程中广泛使用。很多重复使用的算法或业务逻辑都编写成JavaBean,然后在JSP页面中通过<useBean>标记引用。详见本书JSP板块的第18章和第26章。


小 结

Java是面向对象的编程语言。

Java语言定义了四类八种基本数据类型,分别是boolean、char、byte、short、int、long、double和float。Java使用Unicode字符集。

不同类型的数据之间实现计算或赋值,将发生类型转换。类型提升(promotion)由系统自动实现,类型转换(cast)需要程序员通过类型转换运算符“()”强制进行。

Java技术约定,变量标识符以小写字母开头。常量的标识符全部使用大写字母,可以有下划线。

Java控制流语句实现选择和循环结构。return语句返回调用方法,并可携带一个返回值。System.exit()方法从程序的任意地方直接退出程序。

Java语言有单行、多行和文档注释三种注释语句。javadoc命令从文档注释语句中提取信息,生成HTML格式的程序文档。

Java API包中含有大量的类和接口,程序员可以根据需要使用这些类。

你可能感兴趣的:(【Java工程师之路】[1-1.3]Java基本语法)