Java反射

反射

框架设计的灵魂

反射:将类的各个组成部分封装为其他对象,这就是反射机制

好处:1、可以在程序运行过程中,操作这些对象
2、可以解耦合,提高程序的可扩展性

大致意思:把一个类.class经过类加载器处理,把其中的成员变量,构造方法,成员方法,都存在一个数组中
形成一个Class类对象;

获取Class类的方式

1、Class.forName(“全类名”):将字节码文件加载进内存,返回Class对象
*多用于配置文件,将类名定义在配置文件中
2、类名.class:通过类名的属性class获取
*多用于参数的传递
3、对象.getClass:getClass()方法在Object类中定义着
*多用于对象获取字节码的方式


public class Persion {
    private String name;
    private int age;
    public String a;
    protected String b;
    String  c;
    private  String d;

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

    public Persion() {
    }

    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 void eat(){
        System.out.println("吃的方法");
    }
    public void eat(String name){
        System.out.println("吃了"+name);
    }

    @Override
    public String toString() {
        return "Persion{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", a='" + a + '\'' +
                ", b='" + b + '\'' +
                ", c='" + c + '\'' +
                ", d='" + d + '\'' +
                '}';
    }
}


public class Mytest {
    @Test
    public void test01() throws ClassNotFoundException {
        Class<?> aClass = Class.forName("com.zww.domain.Persion");
        System.out.println(aClass);

        Class<Persion> persionClass = Persion.class;
        System.out.println(persionClass);
        Persion persion = new Persion();

        Class<? extends Persion> aClass1 = persion.getClass();
        System.out.println(aClass1);

        // 注意三个值最后运行出来的结果是一样的,*.class在一次程序运行过程中,只会被加载一次
    }
}

使用Class对象功能

获取功能:
   1、获取成员变量 
   
Field getField(String name) 
返回一个 Field对象,它反映此表示的类或接口的指定公共成员字段 类对象。  
Field[] getFields() 
返回包含一个数组 Field对象反射由此表示的类或接口的所有可访问的公共字段 类对象。

Field getDeclaredField(String name) 
返回一个 Field对象,它反映此表示的类或接口的指定已声明字段 类对象。  
Field[] getDeclaredFields() 
返回的数组 Field对象反映此表示的类或接口声明的所有字段 类对象。  

   2、获取构造方法
   
Constructor<T> getConstructor(类<?>... parameterTypes) 
返回一个 Constructor对象,该对象反映 Constructor对象表示的类的指定的公共 类函数。  
Constructor<?>[] getConstructors() 
返回包含一个数组 Constructor对象反射由此表示的类的所有公共构造 类对象。 
Constructor<T> getDeclaredConstructor(类<?>... parameterTypes) 
返回一个 Constructor对象,该对象反映 Constructor对象表示的类或接口的指定 类函数。  
Constructor<?>[] getDeclaredConstructors() 
返回一个反映 Constructor对象表示的类声明的所有 Constructor对象的数组 类 。 

   3、获取成员方法
方法 getMethod(String name, 类<?>... parameterTypes) 
返回一个 方法对象,它反映此表示的类或接口的指定公共成员方法 类对象。  
方法[] getMethods() 
返回包含一个数组 方法对象反射由此表示的类或接口的所有公共方法 类对象,包括那些由类或接口和那些从超类和超接口继承的声明。 
方法 getDeclaredMethod(String name, 类<?>... parameterTypes) 
返回一个 方法对象,它反映此表示的类或接口的指定声明的方法 类对象。  
方法[] getDeclaredMethods() 
返回包含一个数组 方法对象反射的类或接口的所有声明的方法,通过此表示 类对象,包括公共,保护,默认(包)访问和私有方法,但不包括继承的方法。  

   4、获取类的名字
   getName() 
所有的测试类的情况

public class Mytest {
    @Test
    public void test01() throws ClassNotFoundException {
        Class<?> aClass = Class.forName("com.zww.domain.Persion");
        System.out.println(aClass);
        Class<Persion> persionClass = Persion.class;
        System.out.println(persionClass);
        Persion persion = new Persion();

        Class<? extends Persion> aClass1 = persion.getClass();
        System.out.println(aClass1);

        // 注意三个值最后运行出来的结果是一样的,*.class在一次程序运行过程中,只会被加载一次
    }

    /**
     * 获取成员变量的
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    @Test
    public void test02() throws NoSuchFieldException, IllegalAccessException {
        // 0、获取person的Class对象
        Class<Persion> persionClass = Persion.class;
        // 1-获取成员变量
        //      1-1: Field[] getFields() , 获取所有public修饰的
        Field[] fields = persionClass.getFields();
        for (Field field:fields ) {
            System.out.println(field);
        }
        System.out.println("----------");
        //      1-2: Field getField(String name)
        //   获取成员变量之后,可以来进行get和set操作
        Field a = persionClass.getField("a");
        Persion p = new Persion();
        // 设置a的值
        a.set(p,"张三");
        System.out.println(p); // 获取出来就是张三
        System.out.println("----------");

        //     1-3:Field getDeclaredField(String name)
        Field declaredField = persionClass.getDeclaredField("d");
        declaredField.setAccessible(true);   // 暴力反射
        System.out.println("这里是get处理p的="+declaredField.get(p));
        //      1-4:Field[] getDeclaredFields() 获取所有的成员变量
        Field[] declaredFields = persionClass.getDeclaredFields();
        for (Field field1: declaredFields) {
            System.out.println(field1);
        }
    }

    /**
     * 获取构造方法的测试类
     */
    @Test
    public void test03() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//        Constructor<T> getConstructor(类<?>... parameterTypes),构造方法用来创建对象的时候使用
        Class<Persion> persionClass = Persion.class;
        Constructor<Persion> constructor = persionClass.getConstructor(String.class, int.class);
        System.out.println(constructor);
        // 创建对象,采用使用构造器的方式
        Persion persion = constructor.newInstance("张三", 12);
        System.out.println(persion);
        System.out.println("----------------------");
        // 空参构造器演示
        Constructor constructor1 = persionClass.getConstructor();
        System.out.println("空参演示"+constructor1);
//        Constructor<?>[] getConstructors()
//        Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
//        Constructor<?>[] getDeclaredConstructors()

    }

    /**
     * 获取成员方法,也是分属性的
     */
    @Test
    public void test04() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        // 1-使用空参的方法
        Class<Persion> persionClass = Persion.class;
        // 获取指定的方法名
        Method eat = persionClass.getMethod("eat");
        Persion persion = new Persion();
        // 执行方法
        eat.invoke(persion);

        // 2-有参数的方法
        Method eat1 = persionClass.getMethod("eat", String.class);
        eat1.invoke(persion, "苹果");   // 输出吃了苹果


        // 3-获取所有的方法
        Method[] methods = persionClass.getMethods();
        for (Method method:methods){
            System.out.println(method);
            System.out.println(method.getName());
        }

        //获取类名
        String name = persionClass.getName();
        System.out.println("获取的类名"+name);
    }


}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值