Java反射
Contents
反射(Reflection) 允许运行中的Java 程序获取自身的信息,并且可以操作类或对象的内部属性。
反射的核心是 JVM 在运行时才动态加载类或调用方法/访问属性,它不需要事先(写代码的时候或编译期)知道运行对象是谁。
Java 反射主要提供以下功能
- 在运行时,判断任意一个对象所属的类;
- 在运行时,构造任意一个类的对象;
- 在运行时,判断任意一个类所具有的成员变量和方法(甚至可以调用private方法);
- 在运行时,调用任意一个对象的方法
获取类的Class对象的方式
| 获取class对象方式 | 作用 | 应用场景 |
|---|---|---|
| 对象.getClass() | 通过对象的getClass()方法获取 | 多用于对象的获取字节码的方式 |
| 类名.class | 通过类名的属性class获取 | 多用于参数的传递 |
| Class.forName(“全类名”) | 通过指定的字符串路径获取 | 多用于配置文件,将类名定义在配置文件中。读取文件,加载类 |
toString()方法
toString()- return (isInterface() ? “interface " : (isPrimitive() ? "” : “class “))+ getName();
toGenericString()- return a string describing this Class, including information about modifiers and type parameters
- 返回描述此类的字符串,包括有关修饰符和类型参数的信息。
获取类的Class对象的
Class<?> forName(String className)- 返回与给定字符串名称的类或接口相关联的类对象
-
public static void main(String[] args) throws Exception { //反射获取目标类的字节码对象,并执行其成员方法 Class<?> c1 = Class.forName("com.abc.clazz.Student"); Object obj = c1.newInstance(); //反射获取有参数方法:Student的eat方法 Method eatMethod = c1.getMethod("eat", String.class, double.class); //调用eat方法,传递实际参数 eatMethod.invoke(obj, "西红柿炒鸡蛋", 9.9); }
Class<?> forName(String name, boolean initialize, ClassLoader loader)- 使用给定的类加载器返回与给定字符串名称的类或接口相关联的类对象。如果参数loader为空,则通过引导类加载器加载该类。只有当initialize参数为true并且尚未被初始化时,该类才被初始化。
Class类中与Constructor相关方法
Constructor[] getConstructors()- 获取Class对象所表示的类的所有公共构造函数
Constructor<T> getConstructor(Class<?>... parameterTypes)- 返回一个Constructor对象,该对象反映此Class对象所表示的类的指定公共构造函数.parameterTypes参数是一个Class对象的数组,用于按声明的顺序标识构造函数的形式参数类型
Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)- Class类的getDeclaredConstructor()方法,可获取到类的私有构造器( 包括带有其他修饰符的构造器),但在使用private的构造器时,必须设置setAccessible()为true,才可以获取并操作该Constructor对象。
-
@Test void testName() throws Exception { HelloWorld world=null; String className="hello.HelloWorld"; Constructor con=Class.forName(className).getDeclaredConstructor(); con.setAccessible(true); Object obj=con.newInstance(); world=(HelloWorld) obj; world.sayHello(); }
Constructor类中常用方法
T newInstance(Object ... initargs)根据指定参数创建对象。T newInstance()空参构造方法创建对象。void setAccessible(boolean flag)设置是否允许访问私有构造方法Class<?>[] getParameterTypes()获取构造方法的所有参数类型
Class类中与Method相关方法
Method[] getMethods()获取所有的public修饰的成员方法,包括父类中。Method getMethod(String name, Class<?>... parameterTypes)根据方法名和参数类型获得一个方法对象,只能是获取public修饰的Method[] getDeclaredMethods()获取所有的成员方法,包括私有的,但是不包括父类中的方法Method getDeclaredMethod(String name, Class<?>... parameterTypes)-
public class ClassDemo { public static void main(String[] args) { ClassDemo cls = new ClassDemo(); Class c = cls.getClass(); try { // parameter type is null Method m = c.getDeclaredMethod("show", null); System.out.println("method = " + m.toString()); // method Integer Class[] cArg = new Class[1]; cArg[0] = Integer.class; Method lMethod = c.getDeclaredMethod("showInteger", cArg); System.out.println("method = " + lMethod.toString()); } catch (NoSuchMethodException e) { System.out.println(e.toString()); } } private Integer show() { return 1; } public void showInteger(Integer i) { this.i = i; } public int i = 78655; } } // return: //method = private java.lang.Integer reflection.ClassDemo.show() //method = public void reflection.ClassDemo.showInteger(java.lang.Integer)
-
Method类中关键方法
Object invoke(Object obj, Object... args)- 返回值Object,表示调用方法后,该方法的返回值
- 根据参数args调用对象obj的该成员方法
- 如果obj=null,则表示该方法是静态方法
void setAccessible(boolean flag)Class<?>[] getParameterTypes()- 获取方法的所有参数类型
Class<?> getReturnType()- 获取方法的返回值类型
String getName()- 获取方法的名称
Annotation[][] getParameterAnnotations()- 获取方法的参数注解
代码位置
- java.lang.Object
- java.lang.Class
- java.lang.reflect.Constructor
- java.lang.reflect.Method
- java.lang.annotation.Annotation