Java 编程中有 2 个保留字和 50 个关键字
2 个保留字为 :goto 、 const
50 个关键字为 :
我们通过实际运用来了解这些关键字:
一、一些很基础的关键字:
package , import ,
public , protect , private ,
class , extends , implements ,
new ,
byte , short , int , long , float , double , char , boolean
this , super
其中注意,true、false、null 并不是关键字,虽然他们看起来很像关键字,但是他们是显示常量词 ,即 literals。
http://blog.sina.com.cn/s/blog_4ca269070100dify.html
其中说说基本数据类型所占的位数
byte | short | int | long | float | double | char |
8bit | 16bit | 32bit | 64bit | 32bit | 64bit | 16bit |
1. 整型的基本类型(十进制计数法):byte、short、int、long
全都有符号位,这一点与C语言有很大区别,所以在java中 unsigned int m 是错误的变量声明
(1)int 型(有 32 位,即 4 个字节,因此取值范围为 -2^31 ~ 2^31-1 )
常量:123,600(十进制),077(八进制),0x3ABC(十六进制),不用指数表示
变量:int m = 5,n;
(2)byte 型(有 8 位,即 1 个字节,因此取值范围为 -128 ~ 127)
java中不存在 byte 类型的常量,但是可以把一定范围内的 int 常量赋值给 byte 型变量
变量:byte x = -12,y = 1,漂亮 = 98;
如果需要强调一个整数是 byte 型数据时,可以通过强制类型转换运算的结果来表示 byte b = (byte)28;
(3)short 型(有 16 位,即 2 个字节,因此取值范围为 -2^15 ~ 2^15-1 )
关于变量与常量的说明于 byte 数据类似
(4)long 型(有 64 位,即 8 个字节,因此取值范围为 -2^63 ~ 2^63-1 )
常量:long 型常量需要用后缀 L 来表示,例如 18L(十进制),077L(八进制),0x12AB(十六进制)
变量:long width = 77L,height;
整数之间的类型装换运算
(1)将级别低的变量的值赋给级别高的变量时,系统会自动完成数据类型的装换,例如:
float x = 100; // 打印 x 的值为 100.0
int n = 50;
float m = n; //打印 m 的值为 50.0
(2)将级别高的变量的值赋给级别低的变量的时,必须要进行数据类型装换。
int x = (int) 23.45; //打印 x 的值为 23
long y = (long) 56.98F; //打印 y 的值为 56
int z = (int) 1999L; //打印 z 的值为 1999
int m = 19;
byte n = 19; // 不会报错
n = m; // 报错
但是整数之间,将 int 型变量赋值给 byte,short,char 型数据时,不可超过这些变量的取值范围,否则必须进行强制类型装换。
就拿 int 赋给 byte 型数据举例,当 int 数据的大小在 -128 ~ 127 之间,则这个赋值行为没有问题,但是一旦数据不在这个范围就会发生错误
byte a = 127; //打印 a 的值为 127
byte b = (byte) 128; //打印 b 的值为 -128
byte c = (byte) (-129); //打印 c 的值为 127
解释:
1.a 由于 127 并没有超过 byte 数据的取值范围,因此不会出错,
在eclipse中,没有超过 byte 取值范围的值不需要进行类型转换,
而一旦超过就一定要进行类型转换,这个道理 short,char 同
但 long 不同,long 赋给 int 一定要类型转换,否则报错
int d = (int) 1255L;
2.b 128 的二进制编码为 0000...0000 1000 0000
赋值给 byte 数据,即将后八位 1000 0000 赋给 b
1000 0000 对应 byte 型数据的值为 -128,
所以 b 的值为 -128
3.c -129 的二进制编码为 1000...0000 1000 0001
由于是负数,用补码进行存储,也就是 1111...1111 0111 1111
赋值给 byte 数据,即将后八位 0111 1111 赋给 b
0111 1111 对应 byte 型数据的值为 127,
所以 b 的值为 127
2. 浮点型的基本类型(科学计数法): ( 第一个数为符号位数)
(1)float 型 (32 位,共 8 个字节,取值范围为 1.4E-45 ~ 3.4028235E38 和 -3.4028235E38 ~ -1.4E-45)
常量:453.253f , 21379.987F , 231.0f(小数表示法),2e40f(2 乘以 10 的 40 次方,指数表示法),常量后面必须有后缀 f 或 F ,因为没有 f 或 F 会默认为 double 型。
变量:使用关键字 float 来声明的 float 型变量,例如 float x = 22.76f,tom = 1e-12F;
float 变量在存储 float 型数据时保留 8 位有效数字(单精度),例如
float a = 25166.25f; -> 25166.25
float a = 25166.2555555f; -> 25166.256 (共8个数)
(2)double 型 (64 位,共 8 个字节,
取值范围为 4.9E-324 ~ 1.7976931348623157E308 或 -1.7976931348623157E308 ~ - 4.9E-324)
常量:2389.539d , 23118908.987 , 0.059(小数表示),1e-90(指数表示)。对于 double 常量,后面可以有后缀 d 或 D ,但允许省略该后缀。
变量: 使用关键字 doublet 来声明的 double 型变量。(保留 16 位有效数字,双精度)
double c =2562425.25; -> 2562425.25
double c =256242511.255555555555555555555555555555; -> 2.562425112555555E8
需要特别注意的是,比较 float 和 double 型数据时必须注意数据的实际精度,例如
float x = 0.4f;
double y = 0.4;
那么在实际存储在变量 x 中的数据是(这里我们将小数点保留到 16 位)0. 4000 0000 5960 4645 ,存储在 y 中的数据是(小数点保留 16 位)0.4000 0000 0000 0000 ;因此,y 中的值小于 x 中的值
将 double 型数据赋值给 float 型数据,一定要进行类型转换
3. 字符型 char 没有符号位,且 char 有16位,即 2 个字符,所以char的取值范围为 0~65535 (0 ~ 2^16)
常量:'A' , 'b' , '!' , '9' , '好' , 'き' , '\t' 等,即用单引号(英文输入法输入)括起来的 Unicode 表中的一个字符。
其中,有些字符(如回车符)不能通过键盘输入到字符串或程序中,这时就需要转义字符常量。
例如: \n(回车),\b(退格),\t(水平制表),\'(单引号),\"(双引号),\\(反斜杠)
例如:" 我喜欢使用双引号 \" " 中含有双引号字符,但是 " 我喜欢使用双引号 " " ,就是一个非法字符串。
变量:使用关键字 char 来声明的变量。关于赋值的方式:
(1)直接将字符常量赋值给 char 型变量:
char x = 'a';
char home = '家';
char enter = '\n';
(2)在上面的例子中,内存 x 中储存的是 97 ,97 是字符 a 在 Unicode 表中的排序顺序,因此允许将上面的变量声明写成
char x = 97;//一定是char型变量
由此,我们可以知道,char y = 'a' + 1 ; 在内存中存储的是 98,即97 + 1,所以 char 型变量 y 表示的是 ' b '。
(3)上面(2)的表示很像数据类型装换,实际上 char 型数据也可以通过将 int 数据强制类型转换成 char 型进行赋值。与(2)不同的是,这种方式进行的赋值,是将一个字符常量赋值给字符变量。
char y = (char) 98 ; // 即 char y = 'b' ;
但是,需要注意的是,下面这种赋值方式会报错,“可能损失精度,找到 int 需要 char”
int x = 1;
char m = 'a' + x; // 错误 Type mismatch: cannot convert from int to char
char n = (char) ('a' + x); //没有错
因为,在 java 中,int 型数据占 4 个字节,char 型数据占 2 个字节,将 int 数据赋给 char 型,只能取后 16 位。可能会损失精度,因而报错,如想使用,必须进行强制类型转换。
(4)可以用字符在 Unicode 表中排序位置的十六进制转义(需要用 u 做前缀)来表示该字符,其一般格式为 '\u****',(只有四位数)
例如,b 的排序为 98 ,它的二进制表示是 0000 0000 0110 0001 ,所以它的十六进制表示为 0062,因此 十六进制转义为 '\u0062',
所以 y 还可以表示为 char y = '\u0062' ;
另外,char 型数据也可以转换成 int 型数据
例如,
int i = (int)'b' ; // 即 i = 98 ;
二、 static 关键字
1. 只要加了static关键字,就会在实例化对象前,优先执行static修饰的部分
2. 静态内存:
所有用static关键字修饰的内容,都会被放置在静态内存中
所有用static关键字修饰的内容只用唯一的一份
例如,下列两个属性声明没有加static时的储存位置为:
private Test test = new Test(); private int a = 1;
test 储存在栈内存 new Test() 储存在堆内存
a 储存在栈内存 1 储存在栈内存
Java中所有的基本数据类型的值都是存储在栈内存中
3. static 除了能修饰下列黑线画出,还可以修饰 常量 ,请自行回忆 接口中的常量定义
4. (自行理解的) 普通类不能使用static :a. 在Java中,这个类本来就只能有一个,再用static定义会有重复
b. 因为加了static后,会优先在实例化前执行,普通类的操作与此有矛盾
5. (自行理解的) 构造方法不能使用static可能是b 解释
三、 final 关键字
1. final 最终的,即不可改变
属性、变量、形参 : 表示值不能改变,所以第19 行出现了错误。
(如果是指数组、数组队列、对象等存放的是地址的,表示该地址 不可改变,但数组等中的内容可以改变)
普通方法 : 表示方法不可以重写
类、内部类 : 表示类不可以被继承
2. final 还可修饰常量,也请自行回忆 接口中的常量定义
3. static 、final 总结:static和final可以用来一起修饰属性(常量)、普通方法、内部类
四、循环的相关关键字
五。条件关键字
if else 这两个关键字经常组合使用,当if中的条件为ture时,执行if语句的内容,否则执行else中的语句
switch(key) key值的类型要与下面 case 后 的类型相同,defaul 语句,当 key 的内容与 case 每一个都不相符的时候就会执行defau语句的内容。
记得在 case 和 defau 语句后要加上 break 关键字,即退出这个 switch 语句,接下来的语句都不会再执行,如果没有 break 关键字,加入key的值为0,那么执行完 System.out.println("key的值为0"); 后会继续向下执行 System.out.println("key的值为1"); 等语句,直到遇到 break 后 switch 语句结束。
六、 异常类及其处理的关键字
七、检查一个对象是否是另一个类的实例
八、 线程中有关的关键字
1. volatile 主要是指数据同步
在Java内存模型中,有 main memory 和 memory(例如寄存器) 两种内存,当不同的线程在运行时,可能会出现main memory 中的值和memory 中的值不同的现象,这时在数据的应用上可能就会出现问题。volatile告诉jvm, 它所修饰的变量不保留拷贝,直接访问主内存中,所以使用volatile 使得这个数据的值会被线程随时进行修改,让数据同步。
例如,你在主线程运行的程序中有 boolean stopFlag = true 值,你在另一个线程的 run() 方法中可能需要这个值来进行判断。如果你没有使用 volatile 关键字,run() 方法中又没有像 输出语句 一样会使得数据更新的代码执行的话, stopFlag 在第一次改变数值后,后面将不会进行更新,就会造成错误。
volatile的更详细作用可以参照下面这篇博客: https://blog.csdn.net/orzorz/article/details/4319055
//这是我自己的某一个程序中的部分代码,主要挑着看就好了
public class BallListener implements Runnable, KeyListener {
public volatile boolean stopFlag = true; //这个是在主线程中运行的代码
public void keyPressed(KeyEvent e) { //改变 stopFlag 的值
if (e.getKeyCode() == e.VK_ENTER) { // 遇到换行键时执行操作
stopFlag = !stopFlag;
System.out.println(stopFlag);
}
}
public void run() {
while (true) { //此方法让进程不会结束
//System.out.println("hello"); //这条输出语句会让数据更新
if (stopFlag) { //用if来判断
try {
Thread.sleep(30);
} catch (Exception e) {
}
for (int i = 0; i < list2.size(); i++) { // 移动气泡的位置
list2.get(i).move(bf, list2, i);
}
bf.paint(bf.getGraphics());
}
}
}
}
2. synchronized 线程同步
Java语言的关键字,可以用来给对象、方法、代码块加锁。当一个方法或代码块被加锁后,意味着,在同一个时间内只有一个线程可以运行这个方法或代码块。
例如,当线程A执行到这段synchronized代码时,它必须检查此时是否有其它进程(例如可能为线程B或C或D)正在执行这段代码,如果有的话就必须等其它线程(B或C或D)执行完这段代码后,A 才能执行;没有的话,锁定调用者(A),然后直接执行。
如果 B 正在执行某一对象的 synchronized 的加锁方法或代码块,那么其它线程 (例如A)同样可以访问该类中的非 synchronized 方法或代码块。
synchronized 的四种用法可以参见下面这篇博客: http://sakyone.iteye.com/blog/668091
九、还有两个其他的关键字
1. native 关键字
native主要用于调用C和C+的代码。因为Java语言本身不能对操作系统底层进行访问和操作,但是可以通过JNI接口调用其他语言来实现对底层的访问。native调用的文件为C或C++文件,并不是java 文件,是通过接口调用的。
native的更详细说明可以参见下面这个博客:https://www.cnblogs.com/Qian123/p/5702574.html
2. transient 关键字
不好意思,我现在还不太会,等我会了再补充补充吧。
transient 的详细用法可以参见下面这个博客: https://www.cnblogs.com/szlbm/p/5504166.html