反射詳解加案例


java注解

image.png
image.png

反射

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

類初始化時(shí)機(jī)

1. 創(chuàng)建類的實(shí)例
2. 訪問類的靜態(tài)變量,或者為靜態(tài)變量賦值
3. 調(diào)用類的靜態(tài)方法
4. 使用反射方式來強(qiáng)制創(chuàng)建某個(gè)類或接口對應(yīng)的java.lang.Class對象
5. 初始化某個(gè)類的子類
6. 直接使用java.exe命令來運(yùn)行某個(gè)主類

類加載器

1.負(fù)責(zé)將.class文件加載到內(nèi)在中,并為之生成對應(yīng)的Class對象
2. 雖然我們不需要關(guān)心類加載機(jī)制,但是了解這個(gè)機(jī)制我們就能更好的理解程序的運(yùn)行。
3. Bootstrap ClassLoader 根類加載器
4. Extension ClassLoader 擴(kuò)展類加載器
5. Sysetm ClassLoader 系統(tǒng)類加載器
實(shí)例
package com.the151suggestions.reflect;

/**
 * Created by wanggs on 2017/7/23.
 * 所有類的對象其實(shí)都是Class的實(shí)例。
 * 1. 反射就是通過Class文件對象,去使用文件中的成員變量,構(gòu)造方法,成員方法
 * 2. 首先得到Class文件對象,其實(shí)就是得到Class類的對象
 * Class:
 * 成員變量: Field
 * 構(gòu)造方法: Construction
 * 成員方法: Method
 * 獲取class對象的方式
 *      A:Object類的getClass()
 *      B:數(shù)據(jù)類型的靜態(tài)屬性
 *      C: Class類中的靜態(tài)方法
 *          Public static Class forNmae(String className)// 類的全路徑
 */
public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException {
        // 獲取Class文件對象
        //  方式 1
        Person person = new Person();
       Class c   = person.getClass();
       // 方式 2
       Class c1 = Person.class;
       // 方式 3
        Class c2 = Class.forName("com.the151suggestions.reflect.Person");

        System.out.println(c1 == c2); // true
        System.out.println(c2); // 輸出 class com.the151suggestions.reflect.Person


    }
}


class Person {
    private String name;
    public int age;
    public String address;

    public Person() {
    }

    public Person(String name, int age, String address) {
        this.name = name;
        this.age = age;
        this.address = address;
    }

    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 getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }

    // 方法
    public void show() {
        System.out.println("Person.show");
    }

    public void method(String s) {
        System.out.println("s = " + s);

    }

    public String getString(String s, int i) {
        return "s = " + s + "i = " + i;

    }

    private void function() {
        System.out.println("Person.function");
    }
}

通過反射獲取構(gòu)造方法并使用

  • 獲取構(gòu)造方法
getConstructors

getDeclaredConstructors

實(shí)例
public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException {
        // 獲取Class文件對象
        Class c2 = Class.forName("com.the151suggestions.reflect.Person");

        // 獲取構(gòu)造方法
        Constructor[] classes = c2.getConstructors(); // 私有拿不到
        for (Constructor constructor : classes){
            System.out.println(constructor);
        }
    }
}

/**
 * public com.the151suggestions.reflect.Person(java.lang.String,int,java.lang.String)
 public com.the151suggestions.reflect.Person(int)
 public com.the151suggestions.reflect.Person(java.lang.String)
 public com.the151suggestions.reflect.Person()
 */

public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException {
        // 獲取Class文件對象
        Class c2 = Class.forName("com.the151suggestions.reflect.Person");

        // 獲取構(gòu)造方法
        Constructor[] classes = c2.getDeclaredConstructors(); // 獲取所有
        for (Constructor constructor : classes){
            System.out.println(constructor);
        }
    }
}

  • 創(chuàng)建對象
newInstance()
con.newInstance(“zhangsan", 20);

實(shí)例
public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        // 獲取Class文件對象
        Class c2 = Class.forName("com.the151suggestions.reflect.Person");

      // 獲取單個(gè) public Constructor<T> getConstructor(Class<T>... args)
        Constructor constructor = c2.getConstructor(String.class); // 構(gòu)造方法對象

       // Person p = new Person("tom);
        // public T newInstance(object... arg) 獲取構(gòu)造方法
        Person person = (Person) constructor.newInstance("tom");
        System.out.println(person );


    }
}

私有構(gòu)造暴力訪問
public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        // 獲取Class文件對象
        Class c2 = Class.forName("com.the151suggestions.reflect.Person");

      // 獲取單個(gè) public Constructor<T> getConstructor(Class<T>... args)
        Constructor constructor = c2.getDeclaredConstructor(String.class); // 私有構(gòu)造方法對象

        // 暴力訪問
        constructor.setAccessible(true); // 取消java語言檢查
        Person person = (Person) constructor.newInstance("tom");
        System.out.println(person );
        person.show();


    }
}

通過反射獲取成員變量并使用

  • 獲取所有成員
getFields,getDeclaredFields


  • 獲取單個(gè)成員
getField,getDeclaredField

- 修改成員的值
set(Object obj,Object value) //將指定對象變量上此 Field 對象表示的字段設(shè)置為指定的新值。
實(shí)例
public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        // 獲取Class文件對象
        Class c2 = Class.forName("com.the151suggestions.reflect.Person");

        // 獲取所有成員變量
        Field[] fields = c2.getDeclaredFields();// 包含私有
        for (Field field : fields) {
            System.out.println(field);
/**
 * public int com.the151suggestions.reflect.Person.age
 public java.lang.String com.the151suggestions.reflect.Person.address
 */
        }

        Constructor constructor = c2.getConstructor();
        Object object = constructor.newInstance();

        // 獲取單個(gè)
        Field field = c2.getField("address");
        // 設(shè)置值 public void set(Object obj, Object value)
        field.set(object,"鄭州");
        // Person p = new Person("鄭州");
        System.out.println(object);


    }
}

通過反射獲取成員方法并使用

  • 獲取所有方法
getMethods
getDeclaredMethods

實(shí)例
public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        // 獲取Class文件對象
        Class c2 = Class.forName("com.the151suggestions.reflect.Person");
        Method[] methods = c2.getMethods(); // 包括父親的公共方法
        for(Method method : methods){
            System.out.println(method);

        }

    }
}
  • 獲取單個(gè)方法
getMethod
getDeclaredMethod

實(shí)例
public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        // 獲取Class文件對象
        Class c2 = Class.forName("com.the151suggestions.reflect.Person");
        Constructor constructor = c2.getConstructor();
         Object object = c2.newInstance();
        /**
         * Person p = new Person();
         * p.show();
         */
        // 獲取單個(gè)  public Method getMethod(String name,Class<?> args);
        Method method = c2.getMethod("show");
        // 調(diào)用方法 public Object invoke(Object object,Object...args );
        method.invoke(object); // 調(diào)用object對的show方法

    }
}

方法多個(gè)參數(shù)
public class ReflectDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        // 獲取Class文件對象
        Class c2 = Class.forName("com.the151suggestions.reflect.Person");
        Constructor constructor = c2.getConstructor();
         Object object = c2.newInstance();
        /**
         * Person p = new Person();
         * p.show();
         */
        // 獲取單個(gè)  public Method getMethod(String name,Class<?> args);
        Method method = c2.getMethod("show");
        // 調(diào)用方法 public Object invoke(Object object,Object...args );
        method.invoke(object);

        Method method1 = c2.getMethod("method", String.class);
        method1.invoke(object,"tom");

        Method method2 = c2.getMethod("getString",String.class,int.class);

        String s  = (String) method2.invoke(object,"jack",12);
        System.out.println(s);


    }
}
  • 暴力訪問
method.setAccessible(true);

案例

public class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        // 加載數(shù)據(jù)
        Properties properties = new Properties();
        FileReader reader = new FileReader("1.txt");
        properties.load(reader);
        reader.close();

        // 獲取數(shù)據(jù)
        String className = properties.getProperty("className");
        String methodName = properties.getProperty("methodName");

        // 反射
        Class c  = Class.forName(className);
        // 無參構(gòu)造
        Constructor constructor = c.getConstructor();
        // 創(chuàng)建對象
        Object object = c.newInstance();

        // 調(diào)用方法
        Method method = c.getMethod(methodName);
        method.invoke(object);
    }
}
案例操作集合
/**
 * Created by wanggs on 2017/7/23.
 */
public class ArrayListDemo {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        /**
         * ArrayList<Integer> 中添加字符串
         */
        ArrayList<Integer> arrayList = new ArrayList<Integer>();
        arrayList.add(12);
        Class c = arrayList.getClass();

        Method method = c.getMethod("add", Object.class);
        method.invoke(arrayList, "tom");
        System.out.println(arrayList);
        
    }
}
案例
package com.the151suggestions.reflect01;

import java.lang.reflect.Field;

/**
 * Created by wanggs on 2017/7/23.
 * public void setProperty(Object obj, String propertyName, Object value){}
 * 此方法可將obj對象中名為propertyName的屬性的值
 */
public class Tool {
    public void setProperty(Object object, String propertyName, Object value) throws NoSuchFieldException, IllegalAccessException {
        Class c = object.getClass();

        // 獲取成員變量
        Field field = c.getDeclaredField(propertyName);
        // 防止私有方法暴力訪問
        field.setAccessible(true);

        field.set(object,value);

    }

    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        Dog dog = new Dog();
        Tool tool = new Tool();
        tool.setProperty(dog,"name","花花");
        System.out.println(dog);
    }

}
class Dog{
    String name;

    public Dog() {
    }

    public Dog(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                '}';
    }
}

動(dòng)態(tài)代理

package com.the151suggestions.reflect01;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * Created by wanggs on 2017/7/23.
 */
public class MyinvocationHandler implements InvocationHandler {
    private Object target; // 目標(biāo)對象

    public MyinvocationHandler(Object target) {
        this.target = target;

    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// Object proxy: 被代理對象  Method method: 要調(diào)用的方法 Object[] args: 方法調(diào)用說填入的參數(shù)
        System.out.println("權(quán)限認(rèn)證");
        Object o = method.invoke(target, args); // 調(diào)用方法傳入真實(shí)主題和參數(shù)
        System.out.println("日志記錄");
        return o; // 代理對象
    }
}


package com.the151suggestions.reflect01;

import java.lang.reflect.Proxy;

/**
 * Created by wanggs on 2017/7/23.
 */
public class UserDaoTest {
    public static void main(String[] args) {
        StudentDao studentDao = new StudentDaoImpl();
        MyinvocationHandler myinvocationHandler = new MyinvocationHandler(studentDao);
       StudentDao studentDao1 = (StudentDao) Proxy.newProxyInstance(studentDao.getClass().getClassLoader(),studentDao.getClass().getInterfaces(),myinvocationHandler);
       studentDao1.login();
    }
}


package com.the151suggestions.reflect01;

/**
 * Created by wanggs on 2017/7/23.
 */
public interface UserDao {
    public abstract void add();
    public abstract void edit();
    public abstract void delete();
}


package com.the151suggestions.reflect01;

/**
 * Created by wanggs on 2017/7/23.
 */
public class UserDaoImpl implements UserDao {
    @Override
    public void add() {
        System.out.println("權(quán)限校驗(yàn)");
        System.out.println("UserDaoImpl.add");
        System.out.println("日志記錄");
    }

    @Override
    public void edit() {
        System.out.println("UserDaoImpl.edit");
    }

    @Override
    public void delete() {
        System.out.println("UserDaoImpl.delete");
    }
}

1.接口定義一個(gè)人類的統(tǒng)稱

/**
 * Created by wanggs on 2017/7/14.
 */
public interface Human {
    public abstract void laugh();
    public abstract void cry();
    public abstract void talk();
}

2.然后定義具體的人種:

package com.wanggs.factory;

/**
 * Created by wanggs on 2017/7/14.
 */
public class WhiteHuman implements Human {
    @Override
    public void laugh() {
        System.out.println("WhiteHuman.laugh");
    }

    @Override
    public void cry() {
        System.out.println("WhiteHuman.cry");
    }

    @Override
    public void talk() {
        System.out.println("WhiteHuman.talk");
    }
}

package com.wanggs.factory;

/**
 * Created by wanggs on 2017/7/14.
 */
public class YellowHuman implements Human  {
    @Override
    public void laugh() {
        System.out.println("YellowHuman.laugh");
    }

    @Override
    public void cry() {
        System.out.println("YellowHuman.cry");
    }

    @Override
    public void talk() {
        System.out.println("YellowHuman.talk");
    }
}

3.人的工廠

package com.wanggs.factory;

/**
 * Created by wanggs on 2017/7/14.
 */
public class HumanFactory {

    // 第一版
   /* public static Human produceHuman(String type) {
        if ("yellow".equals(type)) {
            return new YellowHuman();

        } else if ("white".equals(type)) {
            return new WhiteHuman();

        } else if ("black".equals(type)) {
            return new BlackHuman();

        }
        System.out.println("有誤");
        return null;

    }*/
    //第二版
   /* public static Human produceYellow() {
        return new YellowHuman();
    }

    public static Human produceBlack() {
        return new BlackHuman();
    }*/
    //第三版 使用反射
    public static Human createHuman(Class c) {
        Human human = null;
        try {
            human = (Human) Class.forName(c.getName()).newInstance();
        } catch (InstantiationException e) {
            System.out.println("顏色");
        } catch (IllegalAccessException e) {
            System.out.println("人定義錯(cuò)誤");
        } catch (ClassNotFoundException e) {
            System.out.println("null");
        }
        return human;
    }


}

4. 測試

package com.wanggs.factory;

/**
 * Created by wanggs on 2017/7/14.
 */
public class NvWa {
    public static void main(String[] args) {

    Human human = HumanFactory.createHuman(YellowHuman.class);
    human.laugh();
    }
}

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

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

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