java之反射訪問私有屬性


對於任意一個object實例,只要我們獲取了它的class,就能得到它的一切信息。

Class類聽過了幾個方法獲取字段:

Field getField(name):根據字段名獲取某個public的field(包括父類的public 字段)

Filed getDeckaredField(name):根據字段名獲取當前類的某個field(不包括父類)

Field[] getFields():獲取所有的public 的field(包括父類)

Filed[] getDeclaredFields():獲取當前類的所有field(不包括父類)

獲取字段的值:

先獲取Class實例,在獲取Field實例,再用Field.get(Object)獲取指定實例的指定字段的值:

package reflaction;

import java.lang.reflect.Field;

public class demo1 {

public static void main(String[] argsl) throws Exception {
Class stdClass = Student.class;
System.out.println(stdClass.getField("score"));
//System.out.println(stdClass.getField("name"));
System.out.println(stdClass.getDeclaredField("grade"));

Object p = new Person1("xiao ming");
Class c = p.getClass();
Field f = c.getDeclaredField("name");
f.setAccessible(true);
Object value = f.get(p);
System.out.println(value);
}
}

class Person1 {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Person1() {
}

public Person1(String name) {

this.name = name;
}
}

class Student extends Person1 {
public int score;
private int grade;

Student() {
super();
}

Student(String name) {
super.setName(name);
}
}

寫代碼過程遇到的問題就是private屬性,正常情況下Main類是無法訪問的,例如代碼中的name屬性,
這里會出現一個IllegalAccessException,解決這個問題,我們可以把name屬性設置為public或者是在
調用Object value=f.get(p)之前增加一個設置
f.setAccessible(true);

這個設置的意思就是不管這個字段是不是public,一律允許訪問,
setAccessible(true)有可能會失敗,如果JVM運行期存在SecurityManager,這個就會根據規則進行檢查,有可能會
阻止
setAccessible(true),例如某個SecurityManager可能不允許對java和javax開頭的package的類調用setAccessible(true),
這樣可以保證JVM核心庫的安全。
問題:如果可以通過反射獲取private 字段,那么類的封裝還有什么意義?
正常情況下,我們是通過類的實例來訪問字段的,編譯器會根據public protected,private來決定是否
允許訪問字段,這樣就已經達到了封裝的目的了,
反射是一種特殊的方式,通常反射是給工具或者底層框架來事用的,在不知道實例的任何信息的情況下,獲取
特定字段的值。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM