美文网首页TWT Studio - Android 组培训 & 技术分享
傻瓜教你反射(二)——Constructor

傻瓜教你反射(二)——Constructor

作者: 吃啥呀 | 来源:发表于2018-07-18 16:57 被阅读27次

反射基础 构造器 铺垫动态代理


阅读此文章需要先了解[Class类]:https://www.jianshu.com/p/45f080232551

1.Class -> Constructor

API 列出所有成员 列出继承成员 私有成员
getDeclaredConstructor() n n y
getDeclaredConstructors() y n y
getConstructors() y n n
getConstructor() n n n

Declared的可以访问私有(私有比较特殊,具体怎么访问后面会将)
s的返回的是数组(即所有能访问的),没有s的返回的是一个对象(即某种能访问的方法)

package com.company;
//创建一个类A
public class A{
    private String s;
    public int b;

    public A(){
        System.out.println("A类无参数构造");
    }
    public A(String s){
        System.out.println("A类有参数构造:s:"+s);
    }
    private A(int a){
        System.out.println("A类有参数 私有构造:a:"+a);
    }

    public void show(){
    }
}
//获得构造器
package com.company;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

public class ConstructorTest {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InvocationTargetException {

        //反射第一步:获取类的Class实例
        Class cls = A.class;
        //获取A类所有 公共 构造
        Constructor [] conarr = cls.getConstructors();

        for(Constructor con :conarr){
            System.out.println(con);
        }

        //获取指定构造方法
        //无参数
        Constructor constructor = cls.getConstructor();
       
        //有参数
        Constructor constructor2 = cls.getConstructor(String.class);

        //获取私有构造方法
        Constructor constructor3 = cls.getDeclaredConstructor(int.class);
     
    }
}

注意含参构造,需要传入参数,应传入参数类型.class

2. Constructor的方法

区别 java.lang.reflect.Constructor.newInstance() Class.newInstance()
修饰符 在某些情况下可以调用private构造器 只用使用public、protect构造器
参数 可以接收多个参数 只能调用无参数的
异常 使用InvocationTargeException包装 抛出原生异常

注意

第二种方法已经被抛弃了,推荐使用第一种——先获得构造器,再使用构造器带的方法获得构造方法对应的类(java.lang.object)的实例化对象

使用newInstance()创建对象的类的实例

package com.company;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

public class ConstructorTest {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, InvocationTargetException {
        // 使用反射第一步:获取操作类所对应的Class对象
        Class cls = A.class;

       //第二步:利用Class中的方法获得构造器

        //获取A类所有 公共 构造
        Constructor [] conarr = cls.getConstructors();

        for(Constructor con :conarr){
            System.out.println(con);
        }

        //获取指定构造方法
        //无参数
        Constructor constructor = cls.getConstructor();
       //第三步:再利用构造器中的newInstance获得具体的构造方法,转换成需要的对象的类的实例
        Object object1 = constructor.newInstance();//返回的实际上是Object类的实例化对象
        A a = (A)constructor.newInstance();//类型转换成类A

        //有参数
        Constructor constructor2 = cls.getConstructor(String.class);
        Object object2 = constructor2.newInstance("机灵鬼");


        //获取私有构造方法
        Constructor constructor3 = cls.getDeclaredConstructor(int.class);
        constructor3.setAccessible(true);
        //暴力访问setAccessible(true);
        Object object3 = constructor3.newInstance(4);
    }
}

运行结果

public com.company.A(java.lang.String)
public com.company.A()
A类无参数构造
A类有参数构造:s:机灵鬼
A类有参数 私有构造:a:4

注意 要使用私有构造器,必须先设置 constructor.setAccessible(true)

相关文章

网友评论

    本文标题:傻瓜教你反射(二)——Constructor

    本文链接:https://www.haomeiwen.com/subject/wctapftx.html