java反射應用-獲取對象自身的屬性和值

1 反射原理(來源於網絡):

1.1主要是指程序可以訪問,檢測和修改它本身狀態或行爲的一種能力,並能根據自身行爲的狀態和結果,調整或修改應用所描述行爲的狀態和相關的語義。
1.2反射是java語言的一個特性,它允程序在運行時(注意不是編譯的時候)來進行自我檢查並且對內部的成員進行操作。例如它允許一個java的類獲取他所有的成員變量和方法並且顯示出來。Java 的這一能力在實際應用中也許用得不是很多,但是在其它的程序設計語言中根本就不存在這一特性。例如,Pascal、C 或者 C++ 中就沒有辦法在程序中獲得函數定義相關的信息。 (來自Sun)

2 具體實現:

2.1反射機制獲取類有三種方法,以獲取Employee類型爲例子:

// 第一種方式:  test.User必須是全類名
Class u1 = Class.forName("test.User");  

// 第二種方式:   
Class u2 = User.class;  

// 第三種方式:  
// java語言中任何一個java對象都有getClass 方法  
User u = new User();  
Class u3 = u.getClass(); //u3是運行時類 (u的運行時類是User)  

System.out.println(u1); // class test.User
System.out.println(u2); // class test.User
System.out.println(u3); // class test.User

User.java

package test;

public class User {

    private String name;
    private protected age;
    public String sex;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
}

2.2 獲取類以後就可以利用newInstance創建它的對象:

// 創建此Class 對象所表示的類的一個新實例  
Class u1 = Class.forName("test.User");  
Object o = u1.newInstance(); //調用了Employee的無參數構造方法.
System.out.println(o); // test.User@3853cb28

2.3其他操作方法

這裏寫圖片描述

2.3.1 獲取所有的屬性的寫法:

//獲取所有的屬性?  
Class u1 = Class.forName("test.User");  
Field[] fs = u1.getDeclaredFields(); 
// 定義可變長的字符串,用來存儲屬性  
StringBuffer sb = new StringBuffer();  
// 通過追加的方法,將每個屬性拼接到此字符串中  
// 最外邊的public定義  
sb.append(Modifier.toString(u1.getModifiers()) + " class " + u1.getSimpleName() +"{\n");  
// 裏邊的每一個屬性  
for(Field field:fs){  
    sb.append("\t");// 空格  
    sb.append(Modifier.toString(field.getModifiers())+" ");// 獲得屬性的修飾符,例如public,static等等  
    sb.append(field.getType().getSimpleName() + " ");// 屬性的類型的名字  
    sb.append(field.getName()+";\n");// 屬性的名字+回車  
}  
sb.append("}");  
System.out.println(sb);  
/*sb結果
public class User{
    private String name;
    protected int age;
    public String sex;
}*/

2.3.2操作特定的屬性:

Class u1 = Class.forName("test.User");
// 獲取name屬性  
Field idF = u1.getDeclaredField("name");  // name屬性不存在時候報錯java.lang.NoSuchFieldException: name
// 實例化這個類 
Object o1 = u1.newInstance();  
// 把私有Field變成可訪問的  ,公有和保護字段原本就是可訪問的
// 缺少報錯java.lang.IllegalAccessException: Class test.ReflectedTest can not access a member of class test.User with modifiers "private"
idF.setAccessible(true);   
// 給o對象的id屬性賦值"110"  
idF.set(o1, "110"); 
System.out.println(idF.get(o1));  // 110

Field sexF = u1.getDeclaredField("sex");
sexF.set(o1, "女"); 
System.out.println(sexF.get(o1));  // 女

Field ageF = u1.getDeclaredField("age");
ageF.set(o1, 18); 
System.out.println(ageF.get(o1));  // 18

3 應用:

3.1把未知屬性pojo對象轉化爲

Class u1 = Class.forName("test.User");
// 獲取name屬性  
Field idF = u1.getDeclaredField("name");  // name屬性不存在時候報錯java.lang.NoSuchFieldException: name
// 實例化這個類 
Object o1 = u1.newInstance();  
// 把私有Field變成可訪問的  ,公有和保護字段原本就是可訪問的
// 缺少報錯java.lang.IllegalAccessException: Class test.ReflectedTest can not access a member of class test.User with modifiers "private"
idF.setAccessible(true);   
// 給o對象的id屬性賦值"110"  
idF.set(o1, "110"); 
System.out.println(idF.get(o1));  // 110

Field sexF = u1.getDeclaredField("sex");
sexF.set(o1, "女"); 
System.out.println(sexF.get(o1));  // 女

Field ageF = u1.getDeclaredField("age");
ageF.set(o1, 18); 
System.out.println(ageF.get(o1));  // 18

Map<String, Object> mapValue = new HashMap<>();
for (Field field : fs) {
    field.setAccessible( true );
    mapValue.put(field.getName(), field.get(o1));
}
System.out.println(mapValue);  // {sex=女, age=18, name=110}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章