美文网首页JAVA学习Java学习笔记Java学习笔记
通过反射获取类的构造方法并且创建对象

通过反射获取类的构造方法并且创建对象

作者: 老勇 | 来源:发表于2016-09-22 11:18 被阅读900次

    本篇文章将分为两部分:
    1、通过反射获取类的构造方法
    获取某一个类中的所有的构造器,通常分为两个步骤:
    ①明确操作的是哪一份字节码对象
    ②获取构造器

    Class类获取构造器方法:
    Constructor类:表示类中构造器的类型,Constructor的实例就是某一个类中的某一个构造器
    public Constructor<?>[] getConstructors():该方法只能获取当前Class所表示类的public修饰的构造器
    public Constructor<?>[] getDeclaredConstructors():获取当前Class所表示类的所有的构造器,和访问权限无关
    public Constructor<T> getConstructor(Class<?>... parameterTypes):获取当前Class所表示类中指定的一个public的构造器
    参数:parameterTypes表示:构造器参数的Class类型
    如:
    public User(String name) Constructor c = clz.getCOnstructor(String.class);

    public Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes):获取当前Class所表示类中指定的一个的构造器,和访问权限无关
    <pre><code>
    class User {

    public User() {}
    public User(String name) {}
    private User(String name, int age) {}
    

    }

    public class ConstructorDemo {

    public static void main(String[] args) throws Exception {
        //1、先找到被调用构造器所在类的字节码
        Class<User> clz = User.class;
        //2、获取所有构造器
        Constructor<?>[] cs = clz.getConstructors();
        for (Constructor<?> constructor : cs) {
            System.out.println(constructor);
        }
        System.out.println("---------------------------");
        //2、获取指定公有带参数构造器(获取指定公有构造器)
        Constructor<?> c = clz.getConstructor(String.class);
        System.out.println(c);
        System.out.println("---------------------------");
        //获取指定公有无参数构造器(获取指定公有构造器)
        c = clz.getConstructor();
        System.out.println(c);
        System.out.println("---------------------------");
        //2、获取指定私有构造器
        c = clz.getDeclaredConstructor(String.class,int.class);
        System.out.println(c);
    }
    

    }
    </pre></code>当我们在代码中添加如下代码:
    <pre><code>
    c = clz.getDeclaredConstructor(int.class);

    System.out.println(c);

    </pre></code> 表示:在User中没有找到带有int类型的构造器

    2、创建对象
    调用构造器,创建对象:
    Constructor<T>类:表示类中构造器的类型,Constructor的实例就是某一个类中的某一个构造器
    常用方法:
    public T newInstance(Object...initargs):如调用带参数的构造器,只能使用该方式.
    参数:initargs:表示调用构造器的可变实际参数
    返回:返回创建的实例,T表示Class所表示类的类型

    如果:一个类中的构造器可以直接访问,同时没有参数.,那么可以直接使用Class类中的newInstance方法创建对象.
    public Object newInstance():相当于new 类名();<pre><code>
    class User {

    public User() {
        System.out.println("User()");
    }
    public User(String name) {
        System.out.println("User(String name)   " + "name = "+name);
    }
    private User(String name, int age) {
        System.out.println("User(String name, int age)   " + "name = "+name+"  age = "+age);
    }
    

    }

    public class ConstructorDemo {

    public static void main(String[] args) throws Exception {
        //1、先找到被调用构造器所在类的字节码
        Class<User> clz = User.class;
        //2、获取指定公有带参数构造器(获取指定公有构造器)
        Constructor<?> c = clz.getConstructor(String.class); //
        //3、实例化对象
        c.newInstance("huangweiyong");
        System.out.println("---------------------------");
        //获取指定公有无参数构造器(获取指定公有构造器)
        c = clz.getConstructor();
        //3、实例化对象
        c.newInstance();
        System.out.println("---------------------------");
        //直接调用Class类的newInstance方法构造对象
        //3、实例化对象
        clz.newInstance();
        System.out.println("---------------------------");
        //、获取指定私有构造器
        c = clz.getDeclaredConstructor(String.class,int.class);
        //设置私用方法的可访问(切记,这里必须设置,否则会抛出下图的异常)
        c.setAccessible(true);
        //3、实例化对象
        c.newInstance("huangweiyong",18);
    }
    

    }</pre></code>c.setAccessible(true);如果上述代码在调用私有构造函数时没有设置成true或者不写,会抛出下图异常:

    上述异常的原因是:不能够访问User类中一个修饰符为private的成员.
    为了安全性考虑,private成员外界不准访问.
    但是问题是,我偏要访问:此时就要告诉成员在运行期间忽略掉该安全检查.
    解决方案:调用AccessibleObject类中的
    publicvoid setAccessible(boolean flag)方法:设置是否可访问
    setAccessible(true):可访问的
    又因为ConstructorAccessibleObject子类,所以Constructor中具有该方法.
    (这一点千万不要忘记,切记切记!!!!!!)

    相关文章

      网友评论

        本文标题:通过反射获取类的构造方法并且创建对象

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