Java反射机制是在运行状态中(和编译无关),对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
获取反射的三种方法
- 使用.class 方法,根据类名获得
- 使用对象.getClass() 方法,根据对象获得
- 使用Class.forName() 静态方法,根据类的全路径名获得
public class Test_01 {
public static void main(String[] args) throws ClassNotFoundException {
// 使用对象.getClass() 方法,根据对象获得
Bean bean = new Bean();
bean.getClass();
// 使用.class方法,根据类名获得
Class<Bean> beanClass = Bean.class;
// 使用CLass.forName() 静态方法,根据类的全路径名获得
Class<?> aClass = Class.forName("com/Bean.java");
}
}
使用反射创建对象
通过反射创建对象的方法有两种
- 通过class对象的newInstance()方法创建
- 通过Constructor对象的newInstance()方法创建,使用Constructor对象创建类对象可以选择特定的构造方法,而使用class对象创建只能使用默认的无参构造方法
public class Test_02 {
public static void main(String[] args) throws Exception {
Class<?> aClass = Class.forName("com.Bean");
// 通过class对象的newInstance()方法创建
Object o = aClass.newInstance();
// 通过constructor的newInstance() 方法创建
Constructor<?> constructor = aClass.getConstructor();
constructor.newInstance();
// 创建有参对象
Constructor<?> constructor1 = aClass.getConstructor(String.class);
Object o1 = constructor1.newInstance("小明");
}
}
私有构造(暴力反射)
可是使用setAccessible()
方法将私有构造、属性、方法等设为可见的
public class Bean {
// 私有的构造方法
private Bean(){}
}
public class Test_02 {
public static void main(String[] args) throws Exception{
Class<?> aClass = Class.forName("com.Bean");
Constructor<?> declaredConstructor = aClass.getDeclaredConstructor();
declaredConstructor.setAccessible(true);// 设置可见
Object o = declaredConstructor.newInstance();
}
}
使用反射执行方法
Method getMethod(String name, Class<?>... parameterTypes)
使用getMethod().invoke()
执行方法,和上面的构造方法同理,可是使用setAccessible()使私有方法可见
public class Bean {
public Bean(){}
public void aa(){System.out.println("这是Bean的aa方法");}
public void bb(String string){System.out.println("这是Bean的bb方法,参数是:"+string);}
private void cc(){System.out.println("Bean的私有的方法");}
}
public class Test_03 {
public static void main(String[] args) throws Exception{
Class<?> aClass = Class.forName("com.反射.Bean");
Object o = aClass.newInstance();
// 无参的方法
Method aa = aClass.getMethod("aa");
aa.invoke(o);
// 有参的方法
Method bb = aClass.getMethod("bb", String.class);
bb.invoke(o,"haha");
//私有的方法
Method cc = aClass.getDeclaredMethod("cc");
cc.setAccessible(true);
cc.invoke(o);
}
}
/*
输出结果:
这是Bean的aa方法
这是Bean的bb方法,参数是:haha
*/