反射

反射

1.反射定義

動態獲取的信息以及動態調用對象的方法的功能

2.反射學習

2.1獲取Class的三種方式

    @Test
    public void  demo1(){
        try {
            //1.通過路徑來獲得class對象
           Class clzz = Class.forName("test反射.Person");
           System.out.println(clzz.getName());
           //2.通過類名.class來獲取class對象
           Class clzz1 = Person.class;
           System.out.println(clzz1.getName());
           //3.通過對象.getClass來獲得
           Person p = new Person();
           Class clzz2 = p.getClass();
           System.out.println(clzz2.getName());

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

後臺打印

test反射.Person
test反射.Person
test反射.Person

Process finished with exit code 0

2.2獲取構造器

獲取指定參數類型的構造器

clzz.getDeclaredConstructor(Class<?>... parameterTypes);

獲取指定參數類型公有構造器


clzz.getConstructor(Class<?>... parameterTypes)

獲取所有的公有的構造方法

Constructor[] conArray = clzz.getConstructors();

獲取所有的構造方法

Constructor[] conArray = clzz.getDeclaredConstructors();

2.2.1獲取指定參數的構造器

先看實體類代碼構造器部分:

public class Person {
    public String name;
    private String phoneNum;
    private static Integer age;

    public Person(){

    }

    public Person(String name, String phoneNum) {
        this.name = name;
        this.phoneNum = phoneNum;
    }



    private Person(String phoneNum) {
        this.name = name;
        this.phoneNum = phoneNum;
    }
    ...

代碼部分:

    @Test
    public void demo2() throws IllegalAccessException, InvocationTargetException, InstantiationException {
        try {
            Class clzz = Class.forName("test反射.Person");
            Constructor con1 = null;
            try {
                con1 = clzz.getDeclaredConstructor(String.class,String.class);
                Person p= (Person) con1.newInstance("nima","4312");
                p.setAge(18);
                System.out.println("獲取指定參數類型的構造方法並生成對象\n"+p.toString());

            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

運行結果:

獲取指定參數類型的構造方法並生成對象
Person{name='nima', phoneNum='4312', age='18'}

Process finished with exit code 0

2.2.2獲取無參構造並調用

    @Test
    public void demo3() throws IllegalAccessException, InvocationTargetException, InstantiationException {
        try {
            Class clzz = Class.forName("test反射.Person");
            Constructor con1 = null;
            try {
                //獲取所有的公有的構造方法
                //Constructor[] conArray = clzz.getConstructors();
                //獲取所有的構造方法
                //Constructor[] conArray = clzz.getDeclaredConstructors();
                con1 = clzz.getConstructor(null);
                Person p= (Person) con1.newInstance();
                p.setAge(18);
                p.setName("rnm");
                p.setPhoneNum("43124265");
                System.out.println("獲取無參構造\n"+p.toString());

            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

後臺運行結果

獲取無參構造
Person{name='rnm', phoneNum='43124265', age='18'}

2.2.3構造器的調用說明

構造器的調用:

有參構造器:
Person p = constructor.newInstance(params ...);

無參構造器:
Person p = constructor.newInstance();

2.3獲取屬性與賦值

2.31獲取所有屬性

    Class clzz = Class.forName("test反射.Person");
    //獲取所有的屬性
    Field[] fieds = clzz.getDeclaredFields();
    for (Field field:fieds) {
        System.out.println(field.getName());
    }

實體類屬性部分:

    public String name;
    private String phoneNum;
    private static Integer age;

後臺打印:

name
phoneNum
age

2.32獲取所有公有屬性

    //獲取所有的屬性
    Field[] fieds = clzz.getFields();

2.33獲取指定公有屬性

    Field fied = clzz.getField("name");

2.33獲取指定公有、私有、無限制屬性

    Field fied = clzz.getDeclaredField("name");

2.34 屬性賦值

    Field feldName =  clzz.getField("name");
    Field feldPhoneNum =  clzz.getDeclaredField("phoneNum");
    Field feldAge =  clzz.getDeclaredField("age");
    //屬性賦值
    // 1.field.set(obj,value)
    feldName.set(p,"mignzi");
    // 2.直接賦值
    //p.setPhoneNum("41234324");
    //私有的所有屬性賦值
    feldPhoneNum.setAccessible(true);//暴力賦值
    feldPhoneNum.set(p,"432532");
    feldAge.setAccessible(true);
    feldAge.set(p,12);//age屬於靜態的屬性
    //獲取name屬性的值
    System.out.println(feldName.get(p));
    //打印 p 對象的toString()方法返回值
    System.out.println(p);

後臺輸出:

mignzi
Person{name='mignzi', phoneNum='432532', age='12'}

2.4 獲取方法並調用

Person類的方法代碼:

    public String getName() {
        return name;

    }

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

    public String getPhoneNum() {
        return phoneNum;
    }

    public void setPhoneNum(String phoneNum) {
        this.phoneNum = phoneNum;
    }

    private static Integer getAge(String pram) {
        System.out.println("getAge:"+ pram);
        return age;
    }

    public static void setAge(Integer age) {
        Person.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", phoneNum='" + phoneNum + '\'' +
                ", age='" + age + '\'' +
                '}';
    }
    Class clzz = Class.forName("test反射.Person");
    Person p = (Person)clzz.getDeclaredConstructor().newInstance();
    //獲取所有公有方法
    Method []methodPublics = clzz.getMethods();
    //獲取所有方法
    Method [] methods = clzz.getDeclaredMethods();
    //獲取指定的公有方法
    Method methodPublic = clzz.getMethod("toString");
    String aa = (String) methodPublic.invoke(p);
    System.out.println(aa);
    //獲取指定的所有方法
    Method method = clzz.getDeclaredMethod("getAge",String.class);
    method.setAccessible(true);
    method.invoke(p,"12");

後臺打印:

Person{name='null', phoneNum='null', age='null'}
getAge:12

2.5 獲取父類Class對象

    Class clzz = Class.forName("test反射.Person");
    Class superClzz = clzz.getSuperclass();
    System.out.println(superClzz.getName());

後臺打印:

java.lang.Object
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章