public class Main { public static void main(String[] args) { ((NULL)null).haha(); } } class NULL { public static void haha(){ System.out.println("haha"); } }
结果:
haha
输出为haha,因为null值可以强制转换为任何java类类型,(String)null也是合法的。但null强制转换后是无效对象,其返回值还是为null,而static方法的调用是和类名绑定的,不借助对象进行访问所以能正确输出。反过来,没有static修饰就只能用对象进行访问,使用null调用对象肯定会报空指针错了。这里和C++很类似。
如果haha方法不是静态方法,那么编译器报错
Exception in thread "main" java.lang.NullPointerException
======================================================================
public class Main { public static void main(String[] args) { System.out.println("-------main start-------"); new HelloB(); new HelloB(); System.out.println("-------main end-------"); } } class HelloA { public HelloA() { System.out.println("HelloA"); } { System.out.println("I'm A class"); } { System.out.println("I'm AAA class"); } static { System.out.println("static A"); } } class HelloB extends HelloA { public HelloB() { System.out.println("HelloB"); } { System.out.println("I'm B class"); } { System.out.println("I'm BBB class"); } static { System.out.println("static B"); } }
结果:
-------main start------- static A static B I'm A class I'm AAA class HelloA I'm B class I'm BBB class HelloB I'm A class I'm AAA class HelloA I'm B class I'm BBB class HelloB -------main end-------
考查静态语句块、构造语句块(就是只有大括号的那块)以及构造函数的执行顺序。
对象的初始化顺序:(1)类加载之后,按从上到下(从父类到子类)执行被static修饰的语句;
(2)如果有语句new了自身的对象,将从上到下执行构造代码块、构造器(两者可以说绑定在一起)。
=========================================================================================
public class Main { public static void main(String[] args) { getValue(); } public static void getValue() { char x = 'B'; switch (x){ case 'A': System.out.printf("A"); case 'B': System.out.printf("B"); case 'C': System.out.printf("C"); default: System.out.printf("D"); } } }
结果:
BCD