一、基本语法元素
什么是语句?什么是块?
语句是java程序执行最小的单位,程序的各语句间以 " ; " 分隔.大括号" { } "包含的一系列的语句称为语句块,简称为块,语句块可以嵌套,一个语句块中可以有多个子语句块,从语法上看,块可以被看作以一个语句.
什么是注释?
注释可理解成为代码程序进行解释说明,提高程序的可读性.且注释不影响程序的执行结果,编译器会忽略注释.
但是注释也有规范:注释不能随意的插在一个标识符或关键字之中,要保证程序中最基本元素的完整性,所以注释最好在程序段的空白处插入 .
注释 3 种形式:
// 在一行内的注释 -----> 一般用于对声明的变量、一行程序的作用做解释说明
/* 一行或多行的注释 */ -----> 多用于说明方法的功能、设计逻辑、基本思想
/** 文档注释 */
什么是标识符?
标识符是由字母、数字、下划线(_)、或美元符($)组成的字符串,其中数字不能作表示符的开头,且标识符要区分大小写.
标识符可用作变量名、方法名、接口名、类名.
For example: Username username UserName 根据标识符区分大小写的原则可以得出 此三种标识符为不同的标识符.
对于各类名的命名规则:
类名或接口名:多为名词,每个单词的首字母都要大写: UserName;
方法名:多为动词,含有大小写,首字母小写,其后的各单词首字母大写: setName;
常量名:每个单词所有字母全部大写,并且两个单词之间要用 _ 分隔开: MIX_AGE;
变量名:首字母小写,后单词首字母大写.
二、基本数据类型
八大基本数据类型
数据类型 | 字节数 | 表示范围 | 最大值 | 最小值 | 类型 |
byte | 1 | -128 ~ 127 | 整数类型 | ||
short | 2 | -32768 ~ 32767 | |||
int | 4 | -2147483648 ~ 2147483647 | Integer.MAX_VALUE | Integer.MIN_VALUE | |
long | 8 | Long.MAX_VALUE | Long.MIN_VALUE | ||
float | 4 | Float.MAX_VALUE | Float.MIX_VALUE | 浮点类型 | |
double | 8 | Double.MAX_VALUE | Double.MIX_VALUE | ||
char | 2 | 字符类型 | |||
boolean | 1 | 布尔类型 |
注: 当想使用长整数类型 long 时需要在数后写出字母L : long l = 155444441L;
当想使用单精度浮点类型 float 时需要在数后面写出字母f: float f = 1.36f;
关于二进制、八进制与十六进制转换在程序中中如何使用:
通常我们人类是使用十进制的数,但总有特殊情况,所以在特殊情况下进行八进制转化十进制时需要以0开头: int i = 077;
十六进制转化十进制时需要以0X开头: int i = 0X77;
二进制化十进制时需要以0B开头: int = 0B100;
1 1 public class Test02 { 2 2 3 3 public static void main(String[] args) { 4 4 5 5 int i = 077; 6 6 int j = 0XBABE; 7 7 int k = 0b100; 8 8 System.out.println(i); // 63 9 9 10 10 System.out.println(j); // 47806 11 11 12 12 System.out.println(k); // 4 13 13 } 14 14 }
整数类型与浮点数类型的语法注意事项:
1 package ChapterOne; // 包类 2 3 public class BasicData{ 4 5 public static void main(String[] args){ // 程序入口 6 7 int i = 1; // 整数类型 8 9 // int i = 1.6; 10 // error; 错误点有两点: 1、在成员变量中变量名不能取相同的名字; 11 // 2、 1.6 是浮点类型,只能使用 flaot 与 double 类型; 12 // byte b = 128; // error : 超过取值范围, byte 的取值范围在-128~127; 13 // float f = 1.6; /* 不建议这样做,因为float 是单精度浮点数,而系统默认输 14 入的浮点数是双精度浮点数,有警告所以正确的语法如下:*/ 15 float fl = 1.6f; 16 17 18 } 19 }
字符类型 char:
char 类型 可以分为普通字符常量 和 转义字符常量
1 1 package TestIf; 2 2 /** 3 3 * 本程序整体输出结果: 4 4 * test 5 5 * test 6 6 * 7 7 *test 8 8 * 9 9 *test 10 10 *\ 11 11 *瑨 12 12 */ 13 13 14 14 public class Test01 { 15 15 16 16 public static void main(String[] args) { 17 17 char c ='\t'; // 水平制表符(Tab) 18 18 char b = 'a'; // 常量值必须用一对单引号 " '' " 括起来; 19 19 char r = '\n'; 20 20 char ch = '\\'; 21 21 char cha = '\u7468'; 22 22 // 用十六进制表示一个具体的 Unicode,由此可得 '\141' 表示用八进制表示一个具体的 Unicode 23 23 // char a = 'avc'; // Invalid character constant:无效的字符常数; 24 24 String s = "test"; 25 25 26 26 System.out.println(c + s); 27 27 System.out.println('\t' + s); // 也可以用这种法师添加水平制表符 28 28 // output result: test; 29 29 30 30 System.out.println(r + s); 31 31 System.out.println('\n' + s); 32 32 /* output result: 33 33 换行 34 34 test 35 35 */ 36 36 System.out.println(ch); // output result: \ 37 37 System.out.println(cha); // output result: 香 38 38 } 39 39 }
常用的转义字符及其含义
转义字符 | 含义 | 转义字符 | 含义 | |
\b | 退格符(Backspace) | \\ | 反斜杠\ | |
\n | 换行符 | \' | 单引号' | |
\r | 回车符 | \" | 双引号'' | |
\t | 水平制表符(Tab) |
boolean类型
布尔类型只有两种状态 1---> true ; 0----> false;
三、表达式
声明变量有两处:
1、在方法或语句块内 ---- 局部变量 (生命周期---从声明到方法或语句块执行完毕);
2、在类中----->成员变量 / 实例变量 (生命周期---永远伴随着类,从类加载到卸载);
重点说明变量的作用域:
成员变量的作用域是整个类;
局部变量的作用域是-从声明到方法或语句块执行完毕,块外是不可使用的;
重点: 块内声明的变量将屏蔽其所在类定义的同名变量.但同一个块中如果定义两个同名变量,则会引起冲突;注意:java允许屏蔽,但冲突将会发生编译错误.
如何去理解官方的说明呢?
看下面的程序:(首先要永远的记牢程序是按照从上到下的方式依次运行的)
成员变量就如同字面意思,整个类都有被作用到,但是有意思的事情发生了:当我们在方法体中或者语句块中声明的局部变量名与(静态)成员变量名相同时,则屏蔽掉(静态)成员变量;但在局部变量名之前先调用(静态)成员变量,成员变量没有被屏蔽
然后我们看看局部变量之间同名会发生什么奇妙的事情:
还是看下面的程序:
当一个方法体中还有一个语句块时,我们来试试有可能发生的几种情况,看看有什么样的结果
1、当两个同名局部变量都在方法体中,显而易见,这两个局部变量互相屏蔽,造成冲突,出现错误,所以这种情况在程序中不能发生;
2、当一个同名局部变量在语句块前面,一个同名局部变量在语句块中,通过编译,程序还是出现了错误,这个程序告诉了我们在一个方法体中,当在方法体中先声明了一个变量,那么后面的任何语句块中都不能再出现同名的局部变量,所以这种情况在程序中也不能发生;
3、当两个同名局部变量同时出现在语句块中呢? 其实他们会出现的结果和第一种结果是一样的,,所以这种情况在程序中也不能发生;
4、当一个同名局部变量先出现在语句块中,然后在这个语句块的块外并且是这个语句块后再声明了一个同名局部变量,奇妙的事情发生了,这个程序居然正常运行了.而这是什么原因?
通过验证调试才发现,当一个同名局部变量先出现在语句块中并运行时,根据块内的变量作用域原理,当语句块运行结束时,块内的局部变量也随之消失,而在运行的过程中后一个同名局部变量虽然在块外,但是根据程序是按照从上到下顺序执行的原理,这个同名变量在前一个同名变量在运行阶段根本没有声明,更不要说运行使用了,所以既没有发生屏蔽,更没有发生冲突,
但是这种方法也很不建议使用,因为取个名字可以无穷无尽,完全没有必要取相同的名字.
1 public class Test01 { 2 3 public static void main(String[] args) { 4 5 Test01 t = new Test01(); // 创建对象 6 7 // name = "ccc"; // Cannot make a static reference to the non-static field name: 不能对非静态字段名进行静态引用 8 /* 在第 8 行中创建了对象,并在第 9 中直接调用 Test01 的成员变量的变量名 name01 进行赋值, 但是第 9 行明显出现了语法错误: 9 * 对于 73 行的成员变量他是一个非静态的变量,所以要使用 引用. 的方式来对其进行调用 --> t.name01; 10 */ 11 t.name01 = "Dad"; 12 name02 = "Mum"; // 如 74 行所示 成员变量变成了静态变量,所以我们可以直接进行调用其变量名复制 13 14 // String name01 = "Tom"; ① 15 // 根据相同块中不能定义相同的变量名,说明此 name01 变量与成员变量 name01 并不相等, 而这个变量是属于 main 方法中的局部变量 16 17 { 18 // String name01 = "Granddad"; ② // Duplicate local variable name01 :复制本地变量name01 19 // 也就是说这个 name01 与 main 方法中的局部变量 name01 重名了,说明了这两个变量都是 main 方法中的局部变量, 20 // 所以相同的方法中定义的局部变量不能取相同的变量名 21 // 修改的正确方式: 22 // name01 = "Granddad"; 23 // 那为何第 25 行这样方式是可以的呢? 24 /* 1、没有使用 String name01 的方式去定义与第 17 行相同的成员变量; 25 * 2、由 17 行不难看出这里的 name01 我们将它重新赋值了,并且结合第 31 行的运算关系,可以得出: name01 重新赋值后,又将其value 26 * 赋给了 t.name01; 27 * 最后的结果就是所有的 t.name01 or name01 的 output value:Granddad 28 * */ 29 30 // t.name01 = name01; 31 32 System.out.println("the name is " + t.name01); 33 } 34 35 // System.out.println(name01); 36 System.out.println(t.name01); 37 System.out.println(name02); 38 39 System.out.println("------------------"); 40 41 { 42 String name = "Jack"; 43 t.name = name; 44 System.out.println("The t's name:" + t.name); 45 } 46 { 47 String name = "Amy"; 48 t.name = name; 49 System.out.println("The t's name:" + t.name); 50 } 51 52 String name = "Kaka"; 53 t.name = name; 54 System.out.println("The t's name:" + t.name); 55 56 /** 看到 44 - 52 行的程序是否产生了疑惑,为什么相同的形式,只不过是将其中一个变量名从块的上方搬到了块的下方产生的结果却大不相同: 57 * 这就是一个变量的作用域的问题: 58 * 首先上代码 (17-36) 先定义了一个 main 方法的局部变量 ①,然后在又子块中定义了一个相同的局部变量名 ②, 59 * 可以看出来 ① 的作用域是整个方法体,而 ② 的作用域只有子块,所以当子块想使用 ② 的变量时会发生想用 ②, ① 不给使用的冲突局面,最后语法错误 60 * 61 * 而程序(44-52)就表现了出了一个变量作用域的局限性问题: 62 * 如果一个方法体中定义两个相同的局部变量,其中一个在方法体中的子块中,一个在块外 63 * 根据两个局部变量的位置,我们就可以判断他的作用域的使用情况: 64 * 1、在一个方法体的块外先声明第一个局部变量,后面的任何一个局部变量(块外与子块内)都不能与 1th 局部变量重名; 65 * 2、在一个方法体的块内先声明第一个局部变量,除了本块内的其他变量不能与 1th 变量重名 ,其块外与其他块中的局部变量都可重名(但不建议这么做); 66 * 3、在一个方法体的块内声明了一个局部变量,其块内不能有与其相同的局部变量名 67 * */ 68 69 } 70 private String name01; 71 private static String name02; 72 private String name; 73 }
四、运算符
1、算术运算符
算数运算符通常包含 加( + )、 减( - )、 乘( * )、 除( / )、 取模( % )
但是值得注意的是在java中部分运算符与我们平常使用的规则是不同的;
除( / ): 在java中两个数进行除运算,所得到的结果只有商,如果有余数则抛弃余数 ,其正负规则与数学相同.
1 public class Test03 { 2 3 public static void main(String[] args) { 4 5 6 int a = 10,b = 2; 7 int sum; 8 sum = a / b; 9 System.out.println(sum); // output result : 5; 10 11 int i = 11,j = 2; 12 int c; 13 c = i / j; 14 System.out.println(c); // output result : 5; 15 } 16 }
取模( % ):在java中不仅可以对整型运算,还可对浮点型运算,其结果是两数除尽后取余数,这里值得注意的一点就是正负数的问题: -5 % 2 = -1; 5 % -2 = 1; -5 % -2 = -1;
1 public class Test03 { 2 3 public static void main(String[] args) { 4 5 6 int i = 11, j = 2,sum; 7 sum = i % j; 8 System.out.println(sum); // output result : 1; 9 10 double q = 10.1; 11 double c; 12 c = q % j; 13 System.out.println(String.format("%.2f", c)); // output result : 0.1; 14 15 double z = -10.1; 16 c = z % j; 17 System.out.println(String.format("%.2f", c)); // output result : -0.1; 18 19 double k = -2; 20 c = q % k; 21 System.out.println(String.format("%.2f", c)); // output result : 0.1; 22 23 c = z % k; 24 System.out.println(String.format("%.2f", c)); // output result : -0.1 25 } 26 }
还有一些奇妙的运算符 ++ 与 --; 它们的含义分别是加1 减 1; 而且这种运算符有前缀与后缀形式,含义略有不同,如 ++i 与 i++ 执行顺序是不一样的: ++i 是先自增再使用, i++ 是先使用 i 再自增:
1 public class Test03 { 2 3 public static void main(String[] args) { 4 5 int i = 0; int j = 0; 6 j = i++; 7 System.out.println(j); // output result : 0; 8 i = 0; j = 0; 9 j = ++i; 10 System.out.println(j); // output result : 1; 11 } 12 }
由此类推,-- 的运算规则与 ++ 相同.
2、关系运算符
关系运算符的主要作用是比较两个值,包括 >、 >=、 <、 <=、 ==、 != 这些运算符都是二元运算符
其中的 == 与 = 不是同一种运算符, == 是判断双方的数据是否相等, 而 = 是右方的数据赋值给左方;并且 == 与 != 可以运算于任何数据类型
1 public class Test04 { 2 3 public static void main(String[] args) { 4 5 int i = 5, j = 4; 6 7 if (i == j) { // output result false; 8 System.out.println(true); 9 }else { 10 System.out.println(false); 11 } 12 13 i = j; 14 System.out.println(i); // output result 4; 15 } 16 }
3、逻辑运算符
逻辑运算有 与( && )、 或( || )、 非( ! ) 前两者为二元运算符 后者为一元的
& ----> 只要两个操作数都是 true 输出 true 否则为 false;
| ----> 只要一个操作数都是 true 输出 true;
&& ----> 只要一个是 false 则输出 false;
|| ----> 只要一个是 true 则输出 true;
! ----> 取反; false 为 true , true 为 false;
^ ----> 相同为 false 不同 为 true;
1 public class Test05 { 2 3 public static void main(String[] args) { 4 5 boolean a = true; 6 boolean i = true; 7 boolean j = false; 8 boolean b = false; 9 10 if (i && j) { // output result false; 11 System.out.println(true); 12 }else { 13 System.out.println(false); 14 } 15 16 if (a && i) { // output result true; 17 System.out.println(true); 18 }else { 19 System.out.println(false); 20 } 21 22 if (a || j) { // output result true; 23 System.out.println(true); 24 }else { 25 System.out.println(false); 26 } 27 28 if (j || b) { // output result false; 29 System.out.println(true); 30 }else { 31 System.out.println(false); 32 } 33 34 if (a || b && (j && i)) { // output result true; 35 System.out.println(true); 36 }else { 37 System.out.println(false); 38 } 39 40 /** 41 * & ----> 只要两个操作数都是 true 输出 true 否则为 false 42 * | ----> 只要一个操作数都是 true 输出 true 43 * && ----> 只要一个是 false 则输出 false; 44 * || ----> 只要一个是 true 则输出 true; 45 * ! ----> 取反; false 为 true , true 为 false; 46 * ^ ----> 相同为 false 不同 为 true; 47 */ 48 49 } 50 }
短路: 从左到右计算,如果只通过运算符左边的操作数就能确定该逻辑表达式的值,就不用继续算右边的;
& 和 | 即是逻辑运算符又是位运算符,当两侧操作数是 boolean 类型则为逻辑运算符,两侧操作数为整数类型则为位运算符
逻辑运算符的优先级: (! > && > ||)
4、条件运算符
格式: x ? y :z
其中 x 为 boolean 类型表达式,先计算 x 的值,如果为真 则输出 y 的值, 否则输出 z 的值
5、强制类型转化
格式: (double) var
6、位运算符
>> : 右移,每移一位,每个操作数被2整除一次,移动的次数由第二个操作数决定
<< : 左移,每移一位,每个操作数被2整乘一次,移动的次数由第二个操作数决定
来源:https://www.cnblogs.com/evething-begins-with-choice/p/12573372.html