廖雪峰Java4反射与泛型-1反射-4调用构造方法

1.Class.newInstance()只能调用public的无参数构造方法

public class Main {
    public static void main(String[] args) throws InstantiationException,IllegalAccessException{
        String s = (String) String.class.newInstance();
        Integer n = (Integer) Integer.class.newInstance();//Interger没有无参数的public构造方法会提示实例化失败
    }
}

2.调用带参数的Constructor

Constructor对象包含一个构造方法的所有信息,可以用它来创建一个实例。
如Integer有2个构造方法,1个传入数字,1个传入字符串

Main.java

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

public class Main {
    public static void main(String[] args) throws InvocationTargetException,InstantiationException, IllegalAccessException, NoSuchMethodException {
        Integer n1 = new Integer(123);
        Integer n2 = new Integer("123");
        System.out.println("n1:"+n1+"\t"+"n2:"+n2);

        Class cls = Integer.class;
        Constructor cons1 = cls.getConstructor(int.class);
        Integer n3 = (Integer) cons1.newInstance(123);
        Constructor cons2 = cls.getConstructor(String.class);
        Integer n4 = (Integer) cons2.newInstance("123");
        System.out.println("n3:"+n3+"\t"+"n4:"+n4);
    }
}

3.通过Class实例获取Constructor信息

  • getConstructor(Class...):获取某个public的Constructor
  • getDeclaredConstructor(Class...):获取某个Constructor,包括非public的
  • getConstuctors():获取所有public的Constructor
  • getDeclaredConstructors():获取所有的Constructor,包括非public的。

Constructor总是当前类的构造方法,和继承没有关系,因此也不可能获得父类的Constructor

通过Constructor实例可以创建一个实例对象

  • newInstance(Object...parameters)

Hello.java

public interface Hello {
    public void hello();
}

Student.java

public class Student implements Hello{
    public static int number = 0;
    public String name ;
    private int age;
    public Student(){
        this("unNamed");
    }
    public Student(String name){
        this(name,20);
    }
    private Student(String name,int age){
        this.name=name;
        this.age = age;
        number++;
    }
    public void hello(){
        System.out.println(name+" is Student");
    }
}

Main.java

import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;

public class Main {
    public static void main(String[] args) throws InvocationTargetException,InstantiationException, IllegalAccessException, NoSuchMethodException {
        Class cls = Student.class;
        Constructor con1 = cls.getDeclaredConstructor(String.class,int.class);//传入参数类型
        printConstructor(con1);
        con1.setAccessible(true);//允许访问这个构造方法
        Student s = (Student) con1.newInstance("小明",12);
        s.hello();
    }
    static void printConstructor(Constructor c){
        System.out.println(c);//打印构造方法
        System.out.println("parameters: "+Arrays.toString(c.getParameterTypes()));//打印参数类型
        System.out.println("modifier:"+c.getModifiers());//打印传入参数个数
    }
}

4.SecurityManager

通过设置setAccessible(true)来访问非public构造方法
serAccessible(true)可能会失败:

  • 定义了SecurityManager
  • SecurityManager的规则阻止对该Constructor设置accessible:例如,规则应用与所有Java和Javax开头的package的类

5.总结

  • Constructor对象封装了构造方法的所有信息
  • 通过Class实例的方法可以获取Constructor实例:getConstructor()/getDeclaredConstructor()/getConstuctors()/getDeclaredConstructors()
  • 通过Constructor实例可以创建一个实例对象:newInstance(Object...parameters)
  • 通过设置setAccessible(true)来访问非public构造方法
posted on 2019-02-01 15:02  singleSpace  阅读(522)  评论(0编辑  收藏  举报