Idea提示我newInstance();被弃用了,
我查了下,使用getDeclaredConstructor().newInstance(); 代替
1)通过反射创建实例:
newInstance(); 会在创建实例对象时调用无参数构造器,
(所以想要使用反射机制,要求类必须有无参数构造器,并且必须是public修饰的):
证明newInstance(); 调用了无参数构造器,比如Student类的构造器这么写:
程序里这么写:
Class clazz = Student.class;
Object obj = clazz.getDeclaredConstructor().newInstance();
printf(obj);
输出实例:
2)通过反射获取类完整的结构(父类、注解、实现的接口、方法、异常、内部类、属性等等):
这里为了测试的进行:
Student继承 Per类(只有一个public long id属性),实现了MyInterface1, MyInterface2这两个接口(都是空接口),还贴了一个注解@Data
//1)getFields(); 获取当前类及其父类声明为public的属性
Class clazz = Student.class;
Field[] fields = clazz.getFields();
for(Field filed : fields){
printf(filed);
}
结果:
//2)getDeclaredFields(); 获得当前类的所有属性
Field[] fields1 = clazz.getDeclaredFields();
for(Field filed : fields1){
printf(filed);
}
结果:
//3)//权限修饰符 变量类型 变量名
//获取属性各个部分的内容(getDeclaredFields ()只能获取这个类本身声明的属性)
Class clazz = Student.class;
Field[] fields = clazz.getDeclaredFields();
for(Field filed : fields) { //1 获取每个属性的成员修权限饰符号
int i =filed.getModifiers();//1 public 2 private 4 protected 8 static .........
printf(i);
//修饰符 //获取数据类型 //输出变量名
printf(Modifier.toString(i)+" "+filed.getType()+" "+filed.getName());//转换为对应的名称
}
//2 获取每个属性的变量类型 //3 获取属性名}
结果如下:(public 对应1 ,private对应2,其他的修饰符对应的号码可以查看源代码)
//4) 获取所有方法使用lazz.getDeclaredMethods();和clazz.getMethods(); 两者的区别于属性的相同
一个获取运行时类和父类的所有public属性,一个获取运行时类自身声明的任何属性:
//5)获得所有构造器
Class clazz = Student.class;
Constructor[] constructors = clazz.getDeclaredConstructors();
for(Constructor constructor : constructors){
printf(constructor);
}
//6)其他:
获取父类:
//获取父类
Class clazz = Student.class;
Class supperClass = clazz.getSuperclass();
printf(supperClass);
//获取带泛型的父类
Class clazz = Student.class;
Type supperType = clazz.getGenericSuperclass();
printf(supperType);
获取实现的接口:
Class clazz = Student.class;
Class[] inter = clazz.getInterfaces();
for(Class i : inter){
printf(i);
}
获取类的注解:(如果注解的生命周期太短会在运行前就被丢掉了,就得不到)
Class clazz = Student.class;
Annotation[] annotations = clazz.getAnnotations();
for( Annotation annotation : annotations){
printf(annotation);
}
3:通过反射运行指定的方法,得到指定的属性:
public 属性:
Class clazz = Student.class;
//1)获取指定属性
Field name = clazz.getField("name");
Student student = (Student)clazz.getDeclaredConstructor().newInstance();
name.set(student, "王麻子");
printf(student);
private属性:
Class clazz = Student.class;
//1)获取指定属性
Field age = clazz.getDeclaredField("age");
age.setAccessible(true); //设置为可访问的
//3)赋值运行时类指定属性 (name属性)
age.set(student, 1000);
printf(student);
public方法: clazz.getMethod("toString",Class.......);如果方法带有参数,需要加上
Class clazz = Student.class;
Method toString = clazz.getMethod("toString"); //得到方法
Student student =(Student) clazz.getDeclaredConstructor().newInstance();//创建实例
String str = (String)toString.invoke(student); //方法调用
printf(str);
private方法:这里就带了参数 getDeclaredMethod()
Method display = clazz.getDeclaredMethod("display", String.class, String.class, String.class);
display.setAccessible(true); //设置可访问权限
display.invoke(student, "1","2","3");
static方法:(static一般不会设置 private 权限吧?所以一般使用 getMethod("sut"); )
//静态方法
Method sut = clazz.getMethod("sut");
sut.invoke(Student.class); //这里传入的是Class 而不是实例
调用指定构造器:
Class clazz = Student.class;
Constructor constructor = clazz.getDeclaredConstructor(String.class);
Student student = (Student) constructor.newInstance("张三");
//等价于 Student student = clazz.getDeclaredConstructor(String.class).newInstance("张三");
printf(student);