面试题分享
- public class A {public static void fun1() {
- System.out.println("fun1");
- }
- public void fun2() {
- System.out.println("fun2");
- }
- public static void main(String[] args) {
- ((A) null).fun1();
- ((A) null).fun2();
- }
- }
题目:
以上代码是否可以编译通过?
如可以通过, 结果是什么?
答案:
代码可以编译通过, null 可以强制转为任意类型, 调用其类中的静态方法不报异常, 调用其类中的非静态方法会报空指针异常
理解
执行下面代码打印结果为 null:
- A a = (A) null;
- System.out.println(a);
由于将 null 强转为 A 的对象, 编译上可以通过,
但是实际值仍然为 null, 非静态方法是属于对象的方法,
所以调用非静态方法会报空指针异常
执行以下代码不报异常:
- A a2 = null;
- a2.fun1();
由于 fun1 是静态方法, 静态方法数随着类加载而加载的,
所以 java 编译器在编译的过程中对我们的代码进行的了优化,
我们通过查看 class 文件即可看出, 这两行代码改变成为了下面的样式:
- A a2 = null;
- fun1();
原因
java 编译器对于 使用对象调用类中的静态方法进行了优化. 对于 a2.fun1() 给优化为 fun1()
java 推荐使用类名直接调用静态方法, 从而减少了编译器的工作, 提高了编译效率.
如图: 左侧为 java 源文件, 右侧为编译后的 class 文件
来源: https://www.cnblogs.com/upuptop/p/11229146.html