在研究enum類的源碼時,跟蹤到Class類的如下代碼:
T[] getEnumConstantsShared() { if (enumConstants == null) { if (!isEnum()) return null; try { final Method values = getMethod("values"); java.security.AccessController.doPrivileged( new java.security.PrivilegedAction<Void>() { public Void run() { values.setAccessible(true); return null; } }); enumConstants = (T[])values.invoke(null); } // These can happen when users concoct enum-like classes // that don't comply with the enum spec. catch (InvocationTargetException ex) { return null; } catch (NoSuchMethodException ex) { return null; } catch (IllegalAccessException ex) { return null; } } return enumConstants; } private volatile transient T[] enumConstants = null;
在上述代碼中有兩處標紅的代碼:
1、java.security.AccessController.doPrivileged...這段代碼可參考:《基於 Java 2 運行時安全模型的線程協作》 http://www.ibm.com/developerworks/cn/java/j-lo-rtsecurity/
可惜看完一遍還是暈菜,什麼必須要簽名之類的,平時也沒有遇到過啊,汗啊~~~
2、volatile是解決線程可見性問題的,transient是臨時性的變量不會被串行化。
transient的問題可參考如下的代碼:
package com.study.java.core.serializable; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.OutputStream; import java.io.Serializable; import com.study.java.core.Employee; public class Person implements Serializable{ private transient Employee employee=null; private String id=null; private transient String pwd=null; public Person( Employee employee ){ this.employee=employee; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } @Override public String toString() { return this.getClass().getName()+":id="+id+",pwd="+pwd+",employee:"+employee; } public static void main(String[] args) { Employee employee=new Employee(); employee.setId("員工1"); employee.setName("員工姓名"); Person person=new Person(employee); person.setId("001"); person.setPwd("password"); try { OutputStream os=new FileOutputStream("f:"+File.separator+"a.txt"); ObjectOutputStream oos=new ObjectOutputStream(os); oos.writeObject(person); oos.flush(); oos.close(); InputStream is=new FileInputStream("f:"+File.separator+"a.txt"); ObjectInputStream ois=new ObjectInputStream(is); Person person1=(Person)ois.readObject(); System.out.println(person1.toString()); } catch (Exception e) { // TODO: handle exception } } }
從輸出結果可以看出:pwd和employee都為null,因為它們都被設置為transient