开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的10天,点击查看活动详情
五.通过反射创建对象
1.方式一:调用类中的oublic修饰的无参构造器 2.方式二:调用类中的指定构造器
3.Class类相关方法
- newInstance:调用类中的无参构造器,获取对应类的对象
- getConstructor(Class...clazz):根据参数列表,获取对应的public构造器对象
- getDecalaredConstructor((Class...clazz):根据参数列表,获取对应的所有构造器对象
4.Constructor类相关方法
- setAccessible:暴破
- newlnstance(Object...obj):调用构造器
5.1通过反射访问类中的成员
- 访问属性
1.根据属性名获取Field对象
Field f=clazz对象.getDeclaredField(属性名):
2.暴破:f.setAccessible(true);//f是Field
3.访问
f.set(o,值); syso(f.get(o));
4.如果是静态属性,则set和get中的参数o,可以写成null
/**
* @author LeeZhi
* @version 1.0
*/
public class ReflectAccessProperty {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchFieldException {
//1.得到Student类对应的Class对象
Class<?> stuClass = Class.forName("com.gbx.reflection.Student");
//2.创建对象
Object o = stuClass.newInstance();//o 得运行类型就是Student
//3.使用反射得到 age属性对象
Field age = stuClass.getField("age");
age.set(o,18);//通过反射设置属性
System.out.println(o);
//4.使用反射操作name属性
Field name = stuClass.getDeclaredField("name");
//对name进行暴破
name.setAccessible(true);
name.set(o,"小黄");//
name.set(null,"子");//因为name是static属性,因此o也可以写出nulL
System.out.println(o);
}
}
class Student{
public int age;
private static String name;
public Student() {
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
'}';
}
- 访问方法
1.根据方法名和参数列表获取Method方法对象:Method m= clazz.getMethod(方法名,XX.class);
2.获取对象:Object o=clazz.newInstance();
3.暴破:m.setAccessible(true):
4.访问:Object returnValue=m.invoke(o,实参列表)://o就是对象
5.注意:如果是静态方法,则invoke的参数o,可以写成null!
public class ReflectAccessMethod {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
//1.得到Boss类对应的Class对象
Class<?> bossCls = Class.forName("com.gbx.reflection.Boss");
//2.创建对象
Object o = bossCls.newInstance();
//3.调用public的hi方法
//Method hi = bossCls.getMethod("hi");
//3.1得到hi方法对象
Method hi1 = bossCls.getDeclaredMethod("hi",String.class);
//3.2调用
hi1.invoke(o,"Lee");
//4.调用 private static 方法
//4.1得到 say 方法对象
Method say = bossCls.getDeclaredMethod("say", int.class, String.class, char.class);
say.setAccessible(true);
System.out.println(say.invoke(100, "小黄", "女"));
//4.3因为say方法是static的,还可以这样调用,可以传入null
System.out.println(say.invoke(null,200,"李四",'女'));
//5.在反射中,如果方法有返回值,统一返回0bjct,但是他运行类型和方法定义的返回类型一致
Object reVal=say.invoke(null,300,"王五",'男');
System.out.println("reVal的运行类型="+reVal.getClass());//String
}
}
class Boss{
public int age;
private static String name;
private static String say(int n,String s,char c){
return n +" "+s +" "+c;
}
public void hi(String s){
System.out.println("hi" + s);
}
}