Java 基础关键字
1. Java 关键字
作用 | 关键字 |
---|---|
访问控制 | private、protected、public |
类、方法和变量修饰符 | abstract、class、extends、static、implements、interface、native、new、final、strictfp、synchronized、 transient、volatile、enum |
程序控制 | break、continue、return、do、while、if、else、for、instanceof、switch、case、default、assert |
错误处理 | try、catch、 throw、 throws、finally |
基本类型 | boolean、byte、char、double、float、 int、 long、short |
变量引用 | super、this、void |
包相关 | import、package |
保留字 | goto、const |
2. static 关键字
static 根据修饰对象的不同作用也不同:
- 属性:在类加载时进行初始化。
- 方法:静态方法不能访问非静态成员。
- 代码块:在类加载时执行,且只执行一次。
- 内部类:内部类可以访问外部类属性和方法,但外部类无法访问内部类属性和方法。
补充:静态代码块可以在第一次 new 对象时执行,也可以通过 Class.forName("类名")
创建对象时执行。
为什么静态方法无法访问非静态成员?
静态方法是属于类的,在类加载时就会分配内存,可直接通过类名访问。非静态方法属于实例对象,只有在对象实例化后才存在,因此需要通过实例去访问。
2. final 关键字
final 根据修饰对象的不同作用也不同:
- 类:该类无法被继承,final 修饰的类中所有成员方法都会被隐式指定为 final 方法。
- 方法:该方法无法被重写。
- 变量:基本类型的变量值无法改变,引用类型变量的地址不饿能改变。
补充:类中所有的 private 方法都会被隐式指定为 final 方法。
3. 8 种数据类型
3.1 基本类型与包装类型
基本类型与包装类型的主要区别:
- 用途:基本类型主要用于常量和局部变量,包装类型主要用于对象属性、方法参数、泛型等。
- 存储方式:基本类型的局部变量在栈的局部变量表,非 static 修饰成员变量在堆中;包装类型对象都存在堆中。
- 占用空间:基本类型占用空间小,包装类型占用空间大。
- 默认值:基本类型有默认值,且不为 null;包装类型成员变量默认值为 null。
- 比较方式:基本类型通过
==
比较是否相等;包装类型通过equals()
比较是否相等。
3.2 自动拆箱与自动装箱
-
自动拆箱:将包装类型转换为对应的基本类型,通过
xxValue()
方法实现。 -
自动装箱:将基本类型转换为对应的包装类型,通过
valueOf()
方法实现。
注意:如果频繁拆装箱的话,也会严重影响系统的性能。
3.3 包装类缓存机制
Byte
,Short
,Integer
,Long
这 4 种包装类默认创建了数值 [-128,127] 的相应类型的缓存数据,Character
创建了数值在 [0,127] 范围的缓存数据,Boolean
直接返回 True
or False
。
如果超出对应范围仍然会去创建新的对象,缓存的范围区间的大小只是在性能和资源之间的权衡。
Integer int1 = new Integer(10);
Integer int2 = 10;
Integer int3 = int1.intValue();
Integer int4 = int3 + new Integer(0);
System.out.println(int1 == int2); // false
System.out.println(int2 == int3); // true
System.out.println(int3 == int4); // true
补充:整形包装类自动装箱时会使用缓存,因此多使用 valueOf() 方法,少使用 parseXX() 方法。
3.4 浮点运算精度问题
计算机中浮点数的表示由 符号位 + 指数 + 尾数
组成,而浮点数的长度有限,且由于十进制转二进制的计算方式原因导致精度问题。
0.2 * 2 = 0.4 -> 0
0.4 * 2 = 0.8 -> 0
0.8 * 2 = 1.6 -> 1
0.6 * 2 = 1.2 -> 1
0.2 * 2 = 0.4 -> 0(发生循环)
《阿里巴巴Java开发手册》:浮点数之间的等值判断,基本类型不能用 == 来比较,包装类不能用 equals() 来比较。
float a = 1.0f - 0.9f;
float b = 0.9f - 0.8f;
a == b; //flase
Float a = new Float(1.0f - 0.9f);
Float b = new Float(0.9f - 0.8f);
Objects.euqal(a, b); //false
正确用法:
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("0.9");
BigDecimal c = new BigDecimal("0.8");
BigDecimal x = a.subtract(b);
BigDecimal y = b.subtract(c);
Objects.equals(x, y); //true
4. try-catch-finally
- try:用于捕获异常。其后可接零个或多个 catch,如果没有 catch,则必须跟一个 finally。
- catch:用于处理 try 捕获到的异常。
- finally:无论是否捕获或处理异常,finally 块里的语句都会被执行。
注意:不要在 finally 中使用 return。当 try 和 finally 都有 return 时,try 中的返回值会先被暂存,直到执行 finally 语句的 return 才会返回。
try-with-resource 的使用:
-
适用场景:任何实现
java.lang.AutoCloseable
或者java.io.Closeable
的对象。 -
执行顺序:任何 cathch 或 finally 语句在声明的资源关闭后执行。