反射

1:什么是反射?
JAVA反射機制是在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意一個方法和屬性;這種動態(tài)獲取的信息以及動態(tài)調(diào)用對象的方法的功能稱為java語言的反射機制。
要想解剖一個類,必須先要獲取到該類的字節(jié)碼文件對象。而解剖使用的就是Class類中的方法.所以先要獲取到每一個字節(jié)碼文件對應的Class類型的對象.

2:三種拿取字節(jié)碼文件的方式
Person person = new Person();//原來創(chuàng)建對象的方式
//拿取字節(jié)碼文件對象(第一種)
Class alz = person.getClass();
//拿取字節(jié)碼文件對象(第二種)
Class alzs =Person.class;
//數(shù)據(jù)庫里拿字節(jié)碼文件,通過反射(第三種)
Class aClass = Class.forName("com.pp.Person");


Person 實例類代碼如下圖所示:

package com.pp;

public class Person {
    //成員變量
    public String name;
    public int age;

    private String address;
    //構(gòu)造方法
    public Person() {
        System.out.println("空參數(shù)構(gòu)造方法");
    }
    public Person(String name) {
        this.name = name;
        System.out.println("帶有String的構(gòu)造方法");
    }
    //私有的構(gòu)造方法
    private Person(String name, int age){
        this.name = name;
        this.age = age;
        System.out.println("帶有String,int的構(gòu)造方法");
    }
    public Person(String name, int age, String address){
        this.name = name;
        this.age = age;
        this.address = address;
        System.out.println("帶有String, int, String的構(gòu)造方法");
    }
    //成員方法
    //沒有返回值沒有參數(shù)的方法
    public void method1(){
        System.out.println("沒有返回值沒有參數(shù)的方法");
    }
    //沒有返回值,有參數(shù)的方法
    public void method2(String name){
        System.out.println("沒有返回值,有參數(shù)的方法 name= "+ name);
    }
    //有返回值,沒有參數(shù)
    public int method3(){
        System.out.println("有返回值,沒有參數(shù)的方法");
        return 123;
    }
    //有返回值,有參數(shù)的方法
    public String method4(String name){
        System.out.println("有返回值,有參數(shù)的方法");
        return "哈哈" + name;
    }
    //私有方法
    private void method5(){
        System.out.println("私有方法");
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + ", address=" + address+ "]";
    }
}

3:通過反射拿構(gòu)造方法
a:拿取所有

  Class c = Class.forName("com.pp.Person");//稱C為字節(jié)碼對象
        //拿取多個構(gòu)造方法
        Constructor[] cons = c.getDeclaredConstructors();
        //遍歷每一個構(gòu)造方法
        for(Constructor con :cons){
            System.out.println(con);
 四個構(gòu)造方法如下圖所示:
public com.pp.Person(java.lang.String,int,java.lang.String)
private com.pp.Person(java.lang.String,int)
public com.pp.Person(java.lang.String)
public com.pp.Person()

b:只拿其中一個構(gòu)造方法(比如拿取上面第一條)

       Class c = Class.forName("com.pp.Person");
 Constructor con = c.getDeclaredConstructor(String.class,int.class,String.class);
        System.out.println(con);

結(jié)果如下:

public com.pp.Person(java.lang.String,int,java.lang.String)

4:創(chuàng)建對象(Public)

       Class c = Class.forName("com.pp.Person");
Constructor con = c.getDeclaredConstructor(String.class,int.class,String.class);

        Object instance = con.newInstance("張三", 12,"北京");
        System.out.println(instance);

運行結(jié)果如下:

帶有String, int, String的構(gòu)造方法
Person [name=張三, age=12, address=北京]

5:私有構(gòu)造方法創(chuàng)建對象

       Class c = Class.forName("com.pp.Person");
 Constructor con = c.getDeclaredConstructor(String.class,int.class);
        //暴力反射
       con.setAccessible(true);//取消語言檢查
        Object instance = con.newInstance("李四", 22);
        System.out.println(instance);

運行結(jié)果:

帶有String,int的構(gòu)造方法
Person [name=李四, age=22, address=null]

6:拿取成員變量
A:拿取所有公開字段

 Class c = Class.forName("com.pp.Person");
 Field[] fields = c.getFields();
        for(Field field:fields){
            System.out.println(field);

運行結(jié)果如下圖:
只可以拿到公開字段name和age,因為address是私有的,所以看不到。

public java.lang.String com.pp.Person.name
public int com.pp.Person.age

B:拿取一個字段

Class c = Class.forName("com.pp.Person");
Field age= c.getField("age");
 System.out.println(age);

結(jié)果如下:

 public int com.pp.Person.age

7:通過反射創(chuàng)建對象獲取指定成員變量進行賦值操作
a:public字段

 Class c = Class.forName("com.pp.Person");
 Constructor declaredConstructor = c.getDeclaredConstructor(String.class);
        Object instance = declaredConstructor.newInstance("王五");
        Field age= c.getField("age");//public
        //獲取值
        age.get(instance);
        //賦值
        age.set(instance,12);
        System.out.println( age.get(instance));

運行結(jié)果:

12

b:private字段
強制暴力反射拿到private字段

   Class c = Class.forName("com.pp.Person");
  Constructor Constructor = c.getDeclaredConstructor(String.class);
        Object instance = Constructor.newInstance("王五");
        Field address= c.getDeclaredField("address");//public
        address.setAccessible(true);//跳過訪問權(quán)限
        address.set(instance,"北京");
        System.out.println( address.get(instance));

運行結(jié)果:

帶有String的構(gòu)造方法
北京

8:通過反射拿方法
a:public

   Class c = Class.forName("com.pp.Person");
 Constructor con= c.getDeclaredConstructor(String.class);//獲取單個構(gòu)造方法
        Object instance = con.newInstance("lisi");
        Method method = c.getMethod("method4", String.class);
        Object invoke = method.invoke(instance,"王芝洋");
        System.out.println(invoke);

運行結(jié)果如下圖所示:

帶有String的構(gòu)造方法
有返回值,有參數(shù)的方法
哈哈王芝洋

b:private

   Class c = Class.forName("com.pp.Person");
 Constructor con= c.getDeclaredConstructor(String.class);//獲取單個構(gòu)造方法
        Object instance = con.newInstance("lisi");
        Method method= c.getDeclaredMethod("method5");
        method.setAccessible(true);//跳過訪問權(quán)限
        Object invoke = method.invoke(instance,null);
        System.out.println(invoke);

運行結(jié)果如下圖:

帶有String的構(gòu)造方法
私有方法
null
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容