Java基本语法

一、基本语法

1.1 关键字和保留字

  • 关键字(keyword)的定义和特点:
    • 定义:被Java语言赋予了特殊含义,用做专门用途的字符串(单词)。
    • 特点:关键字中所有字母都为小写。
  • 保留字(reserved word)
    • Java保留字:现有Java版本尚未使用,但以后版本可能会作为关键字使用。自己命名标识符时要避免使用这些保留字:goto 、const。

1.2 标识符

  • Java 对各种变量方法等要素命名时使用的字符序列称为标识符。
  • 技巧:凡是自己可以起名字的地方都叫标识符。
  • 定义合法标识符规则:
    • 由26个英文字母大小写,0-9 ,_或 $ 组成。
    • 数字不可以开头。
    • 不可以使用关键字和保留字,但能包含关键字和保留字。
    • Java中严格区分大小写,长度无限制。
    • 标识符不能包含空格。
  • Java中的名称命名规范:
    • 包名:多单词组成时所有字母都小写:xxxyyyzzz。
    • 类名、接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz。
    • 变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz。
    • 常量名:所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ。

1.3 变量

  • 变量的概念

    • 内存中的一个存储区域。
    • 该区域的数据可以在同一类型范围内不断变化。
    • 变量是程序中最基本的存储单元。包含变量类型、变量名和存储的值。
  • 变量的作用

    • 用于在内存中保存数据。
  • 使用变量注意

    • Java中每个变量必须先声明,后使用。
    • 使用变量名来访问这块区域的数据。
    • 变量的作用域:其定义所在的一对{ }内。
    • 变量只有在其作用域内才有效。
    • 同一个作用域内,不能定义重名的变量。
  • 声明变量

    • 语法:<数据类型> <变量名称>。
    • 例如:int var。
  • 变量的赋值

    • 语法:<变量名称> = <值>。
    • 例如:var = 10。
  • 声明和赋值变量

    • 语法: <数据类型> <变量名> = <初始化值>。
    • 例如:int var = 10。
  • 变量的分类

    • 按数据类型分

      • 对于每一种数据都定义了明确的具体数据类型(强类型语言),在内存中分配了不同大小的内存空间。
    • 按声明的位置的不同分

      • 在方法体外,类体内声明的变量称为成员变量。
      • 在方法体内部声明的变量称为局部变量。
      • 注意:二者在初始化值方面的异同:
        • 同:都有生命周期 异:局部变量除形参外,需显式初始化。

    整数类型:byte、short、int、long

    • Java各整数类型有固定的表数范围和字段长度,不受具体OS的影响,以保证java程序的可移植性。

    • java的整型常量默认为 int 型,声明long型常量须后加‘l’或‘L’。

    • java程序中变量通常声明为int型,除非不足以表示较大的数,才使用long。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class VariableTest {
public static void main(String[] args) {
//整型:byte(1字节=8bit) \ short(2字节) \ int(4字节) \ long(8字节)
//① byte范围:-128 ~ 127
byte b1 = 12;
byte b2 = -128;
//b2 = 128;//编译不通过
System.out.println(b1);//12
System.out.println(b2);//-128
// ② 声明long型变量,必须以"l"或"L"结尾,否则其范围还是int的范围,但能进行隐式转换,编译通过(当该数没超过int的范围时)
// ③ 通常,定义整型变量时,使用int型。
short s1 = 128;
int i1 = 1234;
long l1 = 3414234324L;
System.out.println(l1);//3414234324
}
}
  • 浮点类型:float、double

    • 与整数类型类似,Java 浮点类型也有固定的表数范围和字段长度,不受具体操作系统的影响。

    • 浮点型常量有两种表示形式:

      • 十进制数形式:如:5.12、512.0f、0.512 (必须有小数点)
      • 科学计数法形式:如:5.12e2、512E2、100E-2
1
2
3
4
5
6
7
8
9
10
11
12
13
class VariableTest {
public static void main(String[] args) {
//浮点型:float(4字节) \ double(8字节)
//① 浮点型,表示带小数点的数值
//② float表示数值的范围比long还大
double d1 = 123.3;
System.out.println(d1 + 1);//124.3
//③ 定义float类型变量时,变量要以"f"或"F"结尾,否则其默认为double型,无法进行隐式转换,编译出错
float f1 = 12.3F;
System.out.println(f1);//12.3
//④ 通常,定义浮点型变量时,使用double型。
}
}
  • 字符类型:char

    • char 型数据用来表示通常意义上“字符”(2字节)。

    • Java中的所有字符都使用Unicode编码,故一个字符可以存储一个字母,一个汉字,或其他书面语的一个字符。

    • 字符型变量的三种表现形式:

      • 字符常量是用单引号(‘ ’)括起来的单个字符。例如:char c1 = ‘a’; char c2 = ‘中’; char c3 = ‘9’。
      • Java中还允许使用转义字符‘\’来将其后的字符转变为特殊字符型常量。例如:char c3 = ‘\n’; // ‘\n’表示换行符。
      • 直接使用 Unicode 值来表示字符型常量:‘\uXXXX’。其中,XXXX代表一个十六进制整数。如:\u000a 表示 \n。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class VariableTest {
public static void main(String[] args) {
//字符型:char (1字符=2字节)
//① 定义char型变量,通常使用一对'',内部只能写一个字符
char c1 = 'a';
//编译不通过
//c1 = 'AB';
System.out.println(c1);//a

char c2 = '1';
char c3 = '中';
char c4 = 'ス';
System.out.println(c2);//1
System.out.println(c3);//中
System.out.println(c4);//ス

//② 表示方式:1.声明一个字符 2.转义字符 3.直接使用 Unicode 值来表示字符型常量
char c5 = '\n';//换行符
c5 = '\t';//制表符
System.out.print("hello" + c5);
System.out.println("world");//hello world

char c6 = '\u0043';
System.out.println(c6);//C
}
}
  • 布尔类型:boolean

    • boolean 类型用来判断逻辑条件,一般用于程序流程控制:
      • if条件控制语句。
      • while循环控制语句。
      • do-while循环控制语句。
      • for循环控制语句。
    • boolean类型数据只允许取值true和false,无null。
      • 不可以使用0或非 0 的整数替代false和true,这点和C语言不同。
      • Java虚拟机中没有任何供boolean值专用的字节码指令,Java语言表达所操作的boolean值,在编译之后都使用java虚拟机中的int数据类型来代替:true用1表示,false用0表示。———《java虚拟机规范 8版》
  • 字符串类型:String

    • String不是基本数据类型,属于引用数据类型。

    • 使用方式与基本数据类型一致。例如:String str = “abcd”。

    • String可以和8种基本数据类型变量做运算,且运算只能是连接运算:+,运算的结果仍然是String类型。

    • 一个字符串可以串接另一个字符串,也可以直接串接其他类型的数据。例如:

      • str = str + “xyz” 。
      • int n = 100。
      • str = str + n。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
class StringTest {
public static void main(String[] args) {

String s1 = "Hello World!";

System.out.println(s1);

String s2 = "a";
String s3 = "";

//char c = '';//编译不通过

int number = 1001;
String numberStr = "学号:";
String info = numberStr + number;// +:连接运算
boolean b1 = true;
String info1 = info + b1;// +:连接运算
System.out.println(info1);

//练习1
char c = 'a';//97 A:65
int num = 10;
String str = "hello";
System.out.println(c + num + str);//107hello
System.out.println(c + str + num);//ahello10
System.out.println(c + (num + str));//a10hello
System.out.println((c + num) + str);//107hello
System.out.println(str + num + c);//hello10a

//练习2
//* *
System.out.println("* *");//* *
System.out.println('*' + '\t' + '*');//93
System.out.println('*' + "\t" + '*');//* *
System.out.println('*' + '\t' + "*");//51*
System.out.println('*' + ('\t' + "*"));//* *
}
}

1.4 编码集

1.4.1 ASCII码

  • 在计算机内部,所有数据都使用二进制表示。每一个二进制位(bit)有 0 和 1 两种状态,因此 8 个二进制位就可以组合出 256 种状态,这被称为一个字节(byte)。一个字节一共可以用来表示 256 种不同的状态,每一个状态对应一个符号,就是 256 个符号,从0000000 到 11111111。
  • ASCII码:上个世纪60年代,美国制定了一套字符编码,对英语字符与二进制位之间的关系,做了统一规定。这被称为ASCII码。ASCII码一共规定了128个字符的编码,比如空格“SPACE”是32(二进制00100000),大写的字母A是65(二进制01000001)。这128个符号(包括32个不能打印出来的控制符号),只占用了一个字节的后面7位,最前面的1位统一规定为0。
  • 缺点:
    • 不能表示所有字符。
    • 相同的编码表示的字符不一样:比如,130在法语编码中代表了é,在希伯来语编码中却代表
      (ג) 了字母Gimel。

1.4.2 Unicode编码

  • 乱码:世界上存在着多种编码方式,同一个二进制数字可以被解释成不同的符号。因此,要想打开一个文本文件,就必须知道它的编码方式,否则用错误的编码方式解读,就会出现乱码。
  • Unicode:一种编码,将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码,使用 Unicode 没有乱码的问题。
  • Unicode 的缺点:Unicode 只规定了符号的二进制代码,却没有规定这个二进制代码应该如何存储:无法区别 Unicode 和 ASCII:计算机无法区分三个字节表示一个符号还是分别表示三个符号。另外,我们知道,英文字母只用一个字节表示就够了,如果unicode统一规定,每个符号用三个或四个字节表示,那么每个英文字母前都必然有二到三个字节是0,这对于存储空间来说是极大的浪费。

1.4.3 UTF-8编码

  • UTF-8 是在互联网上使用最广的一种 Unicode 的实现方式。
  • UTF-8 是一种变长的编码方式。它可以使用 1-6 个字节表示一个符号,根据不同的符号而变化字节长度。
  • UTF-8的编码规则:
    • 对于单字节的UTF-8编码,该字节的最高位为0,其余7位用来对字符进行编码(等同于ASCII码)。
    • 对于多字节的UTF-8编码,如果编码包含 n 个字节,那么第一个字节的前 n 位为1,第一个字节的第 n+1 位为0,该字节的剩余各位用来对字符进行编码。在第一个字节之后的所有的字节,都是最高两位为”10”,其余6位用来对字符进行编码。

1.5 基本数据类型转换

  • 自动类型提升:

    • 当容量小的数据类型的变量与容量大的数据类型的变量做运算时,结果自动提升为容量大的数据类型。

      • byte 、char 、short –> int –> long –> float –> double
    • 特别的:当byte、char、short三种类型的变量做运算时,结果为int型。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class VariableTest {
public static void main(String[] args) {

byte b1 = 2;
int i1 = 129;
//编译不通过
//byte b2 = b1 + i1;
int i2 = b1 + i1;
long l1 = b1 + i1;
System.out.println(i2);//131

float f = b1 + i1;
System.out.println(f);//131.0

short s1 = 123;
double d1 = s1;
System.out.println(d1);//123.0

//***************特别地*********************
char c1 = 'a';//97
int i3 = 10;
int i4 = c1 + i3;
System.out.println(i4);//107

short s2 = 10;
//char c2 = c1 + s2;//编译不通过

byte b2 = 10;
//char c3 = c1 + b2;//编译不通过

//short s3 = b2 + s2;//编译不通过

//short s4 = b1 + b2;//编译不通过
}
}
  • 强制类型转换

    • 需要使用强转符:()
    • 注意点:强制类型转换,可能导致精度损失。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class VariableTest {
public static void main(String[] args) {

double d1 = 12.9;
//精度损失举例1
int i1 = (int)d1;//截断操作,12
System.out.println(i1);//12

//没有精度损失
long l1 = 123;
short s2 = (short)l1;

//精度损失举例2
int i2 = 128;
byte b = (byte)i2;
System.out.println(b);//-128
}
}

1.6 运算符

  • 运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。

1.6.1 算术运算符

  • 如果对负数取模,可以把模数负号忽略不记,如:5%-2=1。 但被模数是负数则不可忽略。此外,取模运算的结果不一定总是整数。
  • 对于除号“/”,它的整数除和小数除是有区别的:整数之间做除法时,只保留整数部分而舍弃小数部分。
  • “+”除字符串相加功能外,还能把非字符串转换成字符串。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
class AriTest {
public static void main(String[] args) {

//除号:/
int num1 = 12;
int num2 = 5;
int result1 = num1 / num2;
System.out.println(result1);//2

int result2 = num1 / num2 * num2;
System.out.println(result2);//10

double result3 = num1 / num2;
System.out.println(result3);//2.0

double result4 = num1 / num2 + 0.0;//2.0
double result5 = num1 / (num2 + 0.0);//2.4
double result6 = (double)num1 / num2;//2.4
double result7 = (double)(num1 / num2);//2.0
System.out.println(result5);
System.out.println(result6);

// %:取余运算
//结果的符号与被模数的符号相同
//开发中,经常使用%来判断能否被除尽的情况。
int m1 = 12;
int n1 = 5;
System.out.println("m1 % n1 = " + m1 % n1);//2

int m2 = -12;
int n2 = 5;
System.out.println("m2 % n2 = " + m2 % n2);//-2

int m3 = 12;
int n3 = -5;
System.out.println("m3 % n3 = " + m3 % n3);//2

int m4 = -12;
int n4 = -5;
System.out.println("m4 % n4 = " + m4 % n4);//-2


//(前)++ :先自增1,后运算
//(后)++ :先运算,后自增1
int a1 = 10;
int b1 = ++a1;
System.out.println("a1 = " + a1 + ",b1 = " + b1);//11 11

int a2 = 10;
int b2 = a2++;
System.out.println("a2 = " + a2 + ",b2 = " + b2);//11 10

int a3 = 10;
++a3;//a3++;
int b3 = a3;

//注意点:
short s1 = 10;
//s1 = s1 + 1;//编译失败
//s1 = (short)(s1 + 1);//正确的
s1++;//自增1不会改变本身变量的数据类型
System.out.println(s1);

//问题:
byte bb1 =127;
bb1++;
System.out.println("bb1 = " + bb1);//-128

//(前)-- :先自减1,后运算
//(后)-- :先运算,后自减1

int a4 = 10;
int b4 = a4--;//int b4 = --a4;
System.out.println("a4 = " + a4 + ",b4 = " + b4);//9 10
}
}

1.6.2 赋值运算符

  • 符号:=
    • 当“=”两侧数据类型不一致时,可以使用自动类型转换或使用强制
      类型转换原则进行处理。
    • 扩展赋值运算符: +=, -=, *=, /=, %=
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
class SetValueTest {
public static void main(String[] args) {
//赋值符号:=
int i1 = 10;
int j1 = 10;

int i2,j2;
//连续赋值
i2 = j2 = 10;

int i3 = 10,j3 = 20;

//*********************
int num1 = 10;
num1 += 2;//num1 = num1 + 2;
System.out.println(num1);//12

int num2 = 12;
num2 %= 5;//num2 = num2 % 5;
System.out.println(num2);//2

short s1 = 10;
//s1 = s1 + 2;//编译失败
s1 += 2;//结论:不会改变变量本身的数据类型
System.out.println(s1);//12

//开发中,如果希望变量实现+2的操作,有几种方法?(前提:int num = 10;)
//方式一:num = num + 2;
//方式二:num += 2; (推荐)

//开发中,如果希望变量实现+1的操作,有几种方法?(前提:int num = 10;)
//方式一:num = num + 1;
//方式二:num += 1;
//方式三:num++; (推荐)

//练习1
int i = 1;
i *= 0.1;
System.out.println(i);//0
i++;
System.out.println(i);//1

//练习2
int m = 2;
int n = 3;
n *= m++; //n = n * m++;
System.out.println("m=" + m);//3
System.out.println("n=" + n);//6

//练习3
int n1 = 10;
n1 += (n1++) + (++n1);//n1 = n1 + (n1++) + (++n1);=10+10+12
System.out.println(n1);//32
}
}

1.6.3 比较运算符

  • 比较运算符的结果都是boolean型,也就是要么是true,要么是false。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class CompareTest {
public static void main(String[] args) {
int i = 10;
int j = 20;

System.out.println(i == j);//false
System.out.println(i = j);//20,即先把j的值赋值给i再输出i

boolean b1 = true;
boolean b2 = false;
System.out.println(b2 == b1);//false
System.out.println(b2 = b1);//true
}
}

1.6.4 逻辑运算符

  • 逻辑运算符用于连接布尔型表达式,在Java中不可以写成3<x<6,应该写成x>3 & x<6 。
  • “&”和“&&”的区别:
    • 单&时,左边无论真假,右边都进行运算。
    • 双&时,如果左边为真,右边参与运算,如果左边为假,那么右边不参与运算。
  • “|”和“||”的区别同理,||表示:当左边为真,右边不参与运算。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
class LogicTest {
public static void main(String[] args) {

//区分& 与 &&
//相同点1:& 与 && 的运算结果相同
//相同点2:当符号左边是true时,二者都会执行符号右边的运算
//不同点:当符号左边是false时,&继续执行符号右边的运算。&&不再执行符号右边的运算。
//开发中,推荐使用&&
boolean b1 = true;
b1 = false;
int num1 = 10;
if(b1 & (num1++ > 0)){
System.out.println("我现在在北京");
}else{
System.out.println("我现在在南京");
}

System.out.println("num1 = " + num1);


boolean b2 = true;
b2 = false;
int num2 = 10;
if(b2 && (num2++ > 0)){
System.out.println("我现在在北京");
}else{
System.out.println("我现在在南京");
}

System.out.println("num2 = " + num2);

// 区分:| 与 ||
//相同点1:| 与 || 的运算结果相同
//相同点2:当符号左边是false时,二者都会执行符号右边的运算
//不同点3:当符号左边是true时,|继续执行符号右边的运算,而||不再执行符号右边的运算
//开发中,推荐使用||
boolean b3 = false;
b3 = true;
int num3 = 10;
if(b3 | (num3++ > 0)){
System.out.println("我现在在北京");
}else{
System.out.println("我现在在南京");
}
System.out.println("num3 = " + num3);


boolean b4 = false;
b4 = true;
int num4 = 10;
if(b4 || (num4++ > 0)){
System.out.println("我现在在北京");
}else{
System.out.println("我现在在南京");
}
System.out.println("num4 = " + num4);
}
}

1.6.5 位运算符

  • 位运算是直接对整数的二进制进行的运算。

1.6.6 三元运算符

  • 表达式1和表达式2为同种类型。
  • 三元运算符与if-else的联系与区别:
    • 三元运算符可简化if-else语句。
    • 三元运算符要求必须返回一个结果。
    • if后的代码块可有多个语句。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class SanYuanTest {
public static void main(String[] args) {

//获取两个整数的较大值
int m = 12;
int n = 5;

int max = (m > n)? m : n;
System.out.println(max);

double num = (m > n)? 2 : 1.0;

//(m > n)? 2 : "n大";//编译错误

//**************************
n = 12;
String maxStr = (m > n)? "m大" : ((m == n)? "m和n相等" : "n大");
System.out.println(maxStr);

//*****************************
//获取三个数的最大值
int n1 = 12;
int n2 = 30;
int n3 = -43;

int max1 = (n1 > n2)? n1 : n2;
int max2 = (max1 > n3)? max1 : n3;
System.out.println("三个数中的最大值为:" + max2);

//不建议
//int max3 = (((n1 > n2)? n1 : n2) > n3)? ((n1 > n2)? n1 : n2) : n3;
System.out.println("三个数中的最大值为:" + max3);
}
}

1.6.7 运算符的优先级

1.7 程序流程控制

1.7.1 顺序结构

1.7.2 分支结构

  • if-else结构
  • switch-case结构

1.7.3 循环结构

  • for循环
    • for (①初始化部分; ②循环条件部分; ④迭代部分){
      ③循环体部分;
    • 执行过程为①-②-③-④-②-③-④-②-③-④-…..-②
  • while循环
    • ①初始化部分
      while(②循环条件部分){
      ③循环体部分;
      ④迭代部分;
      }
    • 执行过程为①-②-③-④-②-③-④-②-③-④-…-②
  • do-while循环
    • ①初始化部分;
      do{
      ③循环体部分
      ④迭代部分
      }while(②循环条件部分);
    • 执行过程为①-③-④-②-③-④-②-③-④-…②