反射基础
构造器
铺垫动态代理
阅读此文章需要先了解[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)