反射

  • Post author:
  • Post category:其他




反射



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



版权声明:本文为qq_29597217原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。