歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java安全模型(沙箱or策略)和transient變量

Java安全模型(沙箱or策略)和transient變量

日期:2017/3/1 9:28:54   编辑:Linux編程

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

Copyright © Linux教程網 All Rights Reserved