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
case后面的常量表达式实际上只起语句标号作用,而不起条件判断作用,即"只是开始执行处的入口标号".
因此,一旦与switch后面圆括号中表达式的值匹配,就从此标号处开始执行,而且执行完一个case后面的语句后,若没遇到break语句,就自动进入下一个case继续执行,而不在判断是否与之匹配,直到遇到break语句才停止执行。
=====================================================================
java 序列化
代码:
public class Main { public static void main(String[] args) { User user = new User(); user.setUsername("Alexia"); user.setPasswd("123456"); user.sex="female"; System.out.println("read before Serializable: "); System.out.println("username: " + user.getUsername()); System.out.println("password: " + user.getPasswd()); System.out.println("sex: " + user.sex); try { ObjectOutputStream os = new ObjectOutputStream( new FileOutputStream("C:/user.txt")); os.writeObject(user); // 将User对象写进文件 os.flush(); os.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } try { ObjectInputStream is = new ObjectInputStream(new FileInputStream( "C:/user.txt")); user = (User) is.readObject(); // 从流中读取User的数据 is.close(); System.out.println(" read after Serializable: "); System.out.println("username: " + user.getUsername()); System.out.println("password: " + user.getPasswd()); System.out.println("sex: " + user.sex); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } } class Person { private String city="shanghai"; public String sex="male"; } class User extends Person implements Serializable { private static final long serialVersionUID = 8294180014912103005L; private String username; private transient String passwd; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPasswd() { return passwd; } public void setPasswd(String passwd) { this.passwd = passwd; } }
结果:
read before Serializable: username: Alexia password: 123456 sex: female read after Serializable: username: Alexia password: null sex: male
1)一旦变量被transient修饰,变量将不再是对象持久化的一部分,该变量内容在序列化后无法获得访问。
2)transient关键字只能修饰变量,而不能修饰方法和类。注意,本地变量是不能被transient关键字修饰的。变量如果是用户自定义类变量,则该类需要实现Serializable接口。
3)被transient关键字修饰的变量不再能被序列化,一个静态变量不管是否被transient修饰,均不能被序列化
可以发现sex属性没有被序列化,这是因为父类没有继承Serializable接口,如果继承接口就可以序列化。
===================================================================================
public class Main { public static void main(String[] args) { System.out.println("X = " + A.X + ", Y = " + B.Y); //System.out.println("Y = " + B.Y + ", X = " + A.X); } } class A { public static int X; static { X = B.Y + 1; } } class B { public static int Y = A.X + 1; static { } }
结果:
X = 2, Y = 1
首先加载类A,然后调用B.Y,加载类B,调用A.X,此时A.X为0
可以取消注释再运行试试。
============================================================
http://www.cnblogs.com/lanxuezaipiao/p/3369962.html