java的基本语法
Java基本语法格式
编写Java程序代码必须先声明一个类,然后在类中编写实现需求的业务代码。类需要使用class关键字定义,在class前面可以有一些修饰符,其语法格式如下:
[修饰符] class 类名 {
程序代码
}
在编写Java程序代码时,需要特别注意几个关键点,具体如下:
1.Java中的程序可分为结构定义语句和功能执行语句。其中,结构定义语句用于声明一个类或方法,功能执行语句用于实现具体的功能。每条功能执行语句的结尾都必须用英文分号(;)结束。如下面的语句:
System.out.println("这是第一个Java程序!");
值得注意的是,在程序中不要将英文的分号(;)误写成中文的分号(;)。如果写成中文的分号,编译器会报告“Invalid Character(无效字符)”这样的错误信息。
2.Java语言是严格区分大小写的。例如,在程序中定义一个computer的同时,还可以定义一个Computer,computer和Computer是两个完全不同的符号,在使用时务必注意。
3.在编写Java代码时,为了便于阅读,通常会使用一种良好的格式进行排版,但这并不是必须的,也可以在两个单词或符号之间任意的换行,例如下面这段代码的编排方式也是可以的:
public class HelloWorld {public static void
main(String [
] args){System.out.println("这是第一个Java程序!");}}
虽然Java没有严格要求用什么样的格式来编排程序代码,但是,出于程序可读性和美观性的考虑,应该让自己编写的程序代码整齐美观、层次清晰,通常会使用下面这种形式:
public class HelloWorld {
public static void main(String[] args) {
System.out.println("这是第一个Java程序!");
}
}
4.Java程序中一个连续的字符串不能直接分开在两行中书写,例如,下面这条语句在编译时将会出错:
System.out.println("这是第一个
Java程序!");
如果为了便于阅读,想将一个太长的字符串分开在两行中书写,可以先将这个字符串分成两个字符串,然后用加号(+)将这两个字符串拼接起来,在加号(+)处断行,上面的语句可以修改成如下形式:
System.out.println("这是第一个" +
"Java程序!");
小提示:
关于本节介绍Java代码基本格式中涉及到的类、修饰符、编译器等专业性的词汇,读者可以先不必深究其具体含义,在本节只需要重点掌握Java代码的基本格式即可,在后续学习Java的过程中,会对这些专业词汇进行详细讲解。
Java中的注释
在编写程序时,为了使代码易于阅读,通常会在实现功能的同时为代码添加一些注释。注释是对程序的某个功能或者某行代码的解释说明,它能够让开发者在后期阅读和使用代码时能更容易理解代码的作用。
注释只在Java源文件中有效,在编译程序时编译器会忽略这些注释信息,不会将其编译到class字节码文件中。
Java中的注释有三种类型,具体如下:
1.单行注释
单行注释通常用于对程序中的某一行代码进行解释,用符号“//”表示,“//”后面为被注释的内容,具体示例如下:
int c = 10; // 定义一个整型变量c
2.多行注释
多行注释顾名思义就是可以同时为多行内容进行统一注释,它以符号“/”开头,并以符号“/”结尾,具体示例如下:
/* 定义一个整形变量x
将5赋值给变量x */
int x;
x = 5;
3.文档注释
文档注释通常是对程序中某个类或类中的方法进行的系统性的解释说明,开发人员可以使用JDK提供的javadoc工具将文档注释提取出来生成一份API帮助文档。文档注释以符号“/”开头,并以符号“/”结尾,具体示例如下:
/**
* Title:HelloWorld类
* @author srx
* @version 1.0
*/
public class HelloWorld {
/**
* 这是一个main()方法入口
* @param args 参数名
*/
public static void main(String[] args){
System.out.println("这是第一个Java程序!");
}
}
脚下留心:注释嵌套
在Java中,有的注释可以嵌套使用,有的则不可以,下面列举两种具体的情况。
1.多行注释“/…/”中可以嵌套使用单行注释“//”,具体示例如下:
/* int c = 10; // 定义一个整型的c
int x = 5; */
2.多行注释“/…/”中不能嵌套使用多行注释“/…/”,具体示例如下:
/*
/*int c = 10;*/
int x=5;
*/
上面第二种情况的代码就无法通过编译,原因在于第一个 “/”会和第一个“/”进行配对,而第二个“*/”则找不到匹配,就会编译失败。
针对在使用嵌套注释时可能出现编译异常这一问题,通常在实际开发中都会避免对代码注释进行嵌套使用,只有在特殊情况下才会在多行注释中嵌套使用单行注释。
Java中的关键字
关键字(Keyword)是编程语言里事先定义好并赋予了特殊含义的单词,也称作保留字。和其他语言一样,Java中保留了许多关键字,例如,class、public等。JDK 8中有50个关键字,这些关键字都是小写的,具体如表1所示。
表1 Java关键字
abstract | assert | boolean | break | byte |
---|---|---|---|---|
case | catch | char | class | const |
continue | default | do | double | else |
enum | extends | final | finally | float |
for | goto | if | implements | import |
instanceof | int | interface | long | native |
new | package | private | protected | public |
return | strictfp | short | static | super |
switch | synchronized | this | throw | throws |
transient | try | void | volatile | while |
上面列举的关键字中,每个关键字都有特殊的作用,例如package关键字用于包的声明,import关键字用于引入包,class关键字用于类的声明。在本书后面的章节将逐步对使用到的关键字进行讲解,在此没有必要对所有关键字进行记忆,只需要了解即可。
Java中的标识符
在编程过程中,经常需要在程序中定义一些符号来标记一些名称,如包名、类名、方法名、参数名、变量名等,这些符号被称为标识符。标识符可以由任意顺序的大小写字母、数字、下划线()和美元符号($)组成,但标识符不能以数字开头,也不能是Java中的关键字。
下面的这些标识符都是合法的:
username
username123
user_name
_userName
$username
下面的这些标识符都是不合法的:
123username // 不能以数字开头
class // 不能是关键字
Hello World // 不能包含空格特殊字符
在Java程序中,定义的标识符必须严格遵守上面列出的规范,否则程序在编译时会报错。
为了增强代码的可读性和美观性,除了要求初学者要严格按照上面列出的规范来定义标识符外,还建议初学者在定义标识符时要遵循以下几点规范:
1.包名所有字母一律小写。例如:com.itheima.example01。
2.类名和接口名每个单词的首字母都要大写。例如:ArrayList、Iterator。
3.常量名所有字母都大写,单词之间用下划线连接。例如:DAY_OF_MONTH。
4.变量名和方法名的第一个单词首字母小写,从第二个单词开始每个单词首字母大写。例如:lineNumber、getLineNumber。
5.在程序中,应该尽量使用有意义的英文单词来定义标识符,使得程序便于阅读。例如:使用userName表示用户名,password表示密码。
java中的变量与常量
变量的定义
在程序运行期间,随时可能产生一些临时数据,应用程序会将这些数据保存在一些内存单元中,每个内存单元都用一个标识符来标识。这些内存单元我们称之为变量,定义的标识符就是变量名,内存单元中存储的数据就是变量的值。
定义变量的语法非常简单,只需要指定变量的类型和变量名即可,其语法格式如下:
变量类型 变量名 [= 初始值];
上述定义变量的语法中,变量类型决定了变量的数据性质、范围、存储在内存中所占的字节数以及可以进行的合法操作,变量名必须是一个合法的标识符,而[]中的内容是可选项,即在定义变量的同时,可以对该变量进行初始化赋值。
接下来,通过具体的代码来学习变量的定义:
int x = 0,y;
y = x+3;
上述代码中,第一行代码的作用是定义了两个int类型的变量x和y,也就相当于分配了两块内存单元,在定义变量的同时为变量x分配了一个初始值0,而变量y没有分配初始值,变量x和y在内存中的状态如图1所示。
图1 x、y变量在内存中的状态
第二行代码的作用是为变量y赋值,在执行第二行代码时,程序首先从内存中取出变量x的值,然后与3相加后,最后将结果赋值给变量y,此时变量x和y在内存中的状态发生了变化,如图2所示。
图2 x、y变量在内存中的状态
变量的数据类型
va是一门强类型的编程语言,它对变量的数据类型有严格的限定。在定义变量时必须先声明变量的数据类型,在为变量赋值时必须赋予和变量同一种类型的值,否则程序在编译期间就会出现类型匹配错误的问题。
在Java中变量的数据类型分为两种:基本数据类型和引用数据类型。Java中所有的数据类型如图1所示。
图1 数据类型
其中,8种基本数据类型是Java语言内嵌的,在任何操作系统中都具有相同大小和属性,而引用数据类型是在Java程序中由编程人员自己定义的数据类型。本章此处重点介绍的是Java中的基本数据类型,引用数据类型会在以后的章节中进行详细地讲解。
1.整数类型变量
整数类型变量用来存储整数数值,即没有小数部分的值。在Java中,为了给不同大小范围内的整数合理地分配存储空间,整数类型分为4种不同的类型:字节型(byte)、短整型(short)、整型(int)和长整型(long),四种类型所占存储空间的大小以及取值范围如表1所示。
表1 整数类型
类型名 | 占用空间 | 取值范围 |
---|---|---|
byte | 8位(1个字节) | -27 ~ 27-1 |
short | 16位(2个字节) | -215 ~ 215-1 |
int | 32位(4个字节) | -231 ~ 231-1 |
long | 64位(8个字节) | -263 ~ 263-1 |
表1中,列出了4种整数类型变量所占的空间大小和取值范围。其中,占用空间指的是不同类型的变量分别占用的内存大小,如一个int类型的变量会占用4个字节大小的内存空间。取值范围是变量存储的值不能超出的范围,如一个byte类型的变量存储的值必须是-27 ~ 27-1之间的整数。
在为一个long类型的变量赋值时需要注意一点,所赋值的后面要加上一个字母“L”(或小写“l”),说明赋值为long类型。如果赋的值未超出int型的取值范围,则可以省略字母“L”(或小写“l”)。具体示例如下:
long num = 2200000000L; // 所赋的值超出了int型的取值范围,后面必须加上字母L
long num = 198L; // 所赋的值未超出int型的取值范围,后面可以加上字母L
long num = 198; // 所赋的值未超出int型的取值范围,后面可以省略字母L
2.浮点数类型变量
浮点数类型变量用来存储小数数值。在Java中,浮点数类型分为两种:单精度浮点数(float)和双精度浮点数(double)。double型所表示的浮点数比float型更精确,两种浮点数所占存储空间的大小以及取值范围如表2所示。
表2 浮点类型
类型名 | 占用空间 | 取值范围 |
---|---|---|
float | 32位(4个字节) | 1.4E-45 ~ 3.4E+38,-1.4E-45 ~ -3.4E+38 |
double | 64位(8个字节) | 4.9E-324 ~ 1.7E+308,-4.9E-324 ~ -1.7E+308 |
表2中,列出了两种浮点数类型变量所占的空间大小和取值范围,在取值范围中,E表示以10为底的指数,E后面的“+”号和“-”号代表正指数和负指数,例如1.4E-45表示1.4*10-45。
在Java中,一个小数会被默认为double类型的值,因此在为一个float类型的变量赋值时,所赋值的后面一定要加上字母“F”(或者小写“f”),而为double类型的变量赋值时,可以在所赋值的后面加上字符“D”(或小写“d”),也可以不加。具体示例如下:
float f = 123.4f; // 为一个float类型的变量赋值,后面必须加上字母f或F
double d1 = 199.3d; // 为一个double类型的变量赋值,后面可以加上字母d或D
double d2 = 100.1; // 为一个double类型的变量赋值,后面可以省略字母d或D
在程序中也可以为一个浮点数类型变量赋予一个整数数值,例如下面的写法也是可以的。
float f = 100; // 声明一个float类型的变量并赋整数值
double d = 100; // 声明一个double类型的变量并赋整数值
3.字符类型变量
字符类型变量用于存储一个单一字符,在Java中用char表示。Java中每个char类型的字符变量都会占用2个字节。在给char类型的变量赋值时,需要用一对英文半角格式的单引号(' ')把字符括起来,如'a',也可以将char类型的变量赋值为0~65535范围内的整数,计算机会自动将这些整数转化为所对应的字符,如数值97对应的字符为'a'。下面的两行代码可以实现同样的效果。
char c = 'a'; // 为一个char类型的变量赋值字符'a'
char ch = 97; // 为一个char类型的变量赋值整数97,相当于赋值字符'a'
4.布尔类型变量
布尔类型变量用来存储布尔值,在Java中用boolean表示,该类型的变量只有两个值,即true和false。具体示例如下:
boolean flag = false; // 声明一个boolean类型的变量,初始值为false
flag = true; // 改变flag变量的值为true
变量的类型转换
在程序中,当把一种数据类型的值赋给另一种数据类型的变量时,需要进行数据类型转换。根据转换方式的不同,数据类型转换可分为两种:自动类型转换和强制类型转换。
1.自动类型转换
自动类型转换也叫隐式类型转换,指的是两种数据类型在转换的过程中不需要显式地进行声明。当把一个类型取值范围小的数值直接赋给另一个取值范围大的数据类型变量时,系统就会进行自动类型转换,否则需要进行强制类型转换。
Java中的自动类型转换就好比将小瓶水倒入到大瓶的换装过程。我们将小瓶水倒入到大瓶中时,由于小瓶的容量比大瓶的容量小,所以倒入的水永远不可能溢出大瓶。同样,在Java中,将取值范围小的数据类型的变量值赋值给取值范围大的数据类型的变量时,程序也不会出现任何问题。
Java中支持的不同数据类型之间的自动转换如图1所示。
图1 自动类型转换图
从图1可以看出,Java中取值范围小的byte、short、char等类型数据都可以自动转换为取值范围大的数据类型(如int类型),并最终都可以自动转换为双精度浮点数类型。例如:
byte b = 3;
int x = b; // 程序把byte类型的变量b转换成了int类型,无需特殊声明
double y = x; // 将int类型的变量x转换成double类型,无需特殊声明
上面的语句中,首先将byte类型的变量b的值赋给了int类型的变量x,然后将int类型的变量x赋值给了double类型的y。由于int(double)类型的取值范围大于byte(int)类型的取值范围,编译器在赋值过程中不会造成数据丢失,所以编译器能够自动完成这种转换,在编译时不报告任何错误。
2.强制类型转换
强制类型转换也叫显式类型转换,指的是两种数据类型之间的转换需要进行显式地声明。当两种类型彼此不兼容,或者目标类型取值范围小于源类型时,自动类型转换无法进行,这时就需要进行强制类型转换。
Java中的强制类型转换就好比将大瓶水倒入到小瓶中一样,如果大瓶中的水的容量小于小瓶的大小,那么水是可以完全倒入的;如果大瓶水过多,其容量超过了小瓶的大小,那么多出来的水就会溢出,从而造成损失。同理,将取值范围大的数据类型的变量值赋值给取值范围小的数据类型的变量时,就可能造成数据的丢失,所以系统默认不支持这种行为,只能由开发者自己决定是否进行强制类型转换。
接下来先演示一个错误类型转换的例子,如文件1所示。
文件1 Example01.java
1 public class Example01 {
2 public static void main(String[] args) {
3 int num = 4;
4 byte b = num;
5 System.out.println(b);
6 }
7 }
程序编译时报错,结果如图2所示。
图2 运行结果
在进行Java代码编写时,Eclipse开发工具会自动对已编写的代码进行检测,如果发现问题,它会以红色波浪线和红叉的形式进行提醒。将鼠标悬停在出现红色波浪线错误的位置时,会出现一个悬浮框,悬浮框内将提示错误信息以及快速解决方案。
从图2可以看出,程序编译过程中出现了类型转换异常,提示“cannot convert from int to byte(无法将int类型转换为byte类型)”。出现这样错误的原因是将一个int型的值赋给byte类型的变量b时,int类型的取值范围大于byte类型的取值范围,这样的赋值可能会导致数值溢出,也就是说一个字节的变量无法存储四个字节的整数值。
在这种情况下,就需要进行强制类型转换,其语法格式如下:
目标类型 变量名 = (目标类型)值;
将文件1中的第4行代码修改为下面的代码:
byte b = (byte) num;
修改后保存源文件,Eclipse中的程序将不再报错。程序的运行结果如图3所示。
图3 运行结果
需要注意的是,在对变量进行强制类型转换时,会发生取值范围较大的数据类型向取值范围较小的数据类型的转换情况,如将一个int类型的数转为byte类型,这样做极容易造成数据精度的丢失。接下来通过一个案例来说明,如文件2所示。
文件2 Example02.java
1 public class Example02 {
2 public static void main(String[] args) {
3 byte a; // 定义byte类型的变量a
4 int b = 298; // 定义int类型的变量b,其表现形式是十六进制
5 a = (byte) b;
6 System.out.println("b=" + b);
7 System.out.println("a=" + a);
8 }
9 }
运行结果如图4所示。
>图4 运行结果
文件2中,第5行代码进行了强制类型转换,将一个int类型的变量b强制转换成byte类型,然后再将强转后的结果赋值给byte类型的变量a。从图2-7可以看出,变量b本身的值为“298”,然而在赋值给变量a后,变量a的值却为42,这说明在强制转换过程中丢失了精度。出现这种现象的原因是,变量b为int类型,在内存中占用4个字节,而byte类型的数据在内存中占用1个字节,当将变量b的类型强转为byte类型后,前面3个高位字节的数据已经丢失,这样数值就发生了改变。int类型转byte类型的过程如图5所示。
图5 int类型变量强制转换为byte类型
多学一招:表达式类型自动提升
所谓表达式是指由变量和运算符组成的一个算式。变量在表达式中进行运算时,也有可能发生自动类型转换,这就是表达式数据类型的自动提升,如byte、short和char类型的变量在运算期间类型会自动提升为int,然后再进行运算。下面通过一个具体的案例来演示,如文件3所示。*
文件3 Example03.java
1 public class Example03 {
2 public static void main(String[] args) {
3 byte b =3;