在研究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