什么是反射?
反射(Reflection) 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说“自审”,动态获取类的信息以及动态调用对象方法。
• 运行时,对于任意一个类,能够获取该类的所有属性、方法、构造器。 • 运行时,对于任意一个对象,能够调用该对象的任意一个方法和属性。
• 如何反射获取 Class 对象 • 如何反射获取类中的所有字段 • 如何反射获取类中的所有构造方法 • 如何反射获取类中的所有非构造方法。
类的加载
类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆内存中创建一个java.lang.Class对象,用来封装类在方法区内的数据结构。
实现反射有三种基本形式:(Class类:代表类的实体,在运行Java应用程序中表示类和接口。)
1.使用Class.forName静态方法
Class clz = Class.forName("java.lang.String");
2.使用类型的class()方法
Class clz = String.class;
3.使用对象的getClass()方法
String str = new String("Hello"); Class clz = str.getClass();
对于反射来说,在了解反射的同时要明白反射中最重要的4个类,将其解释拆解为Class类、Field类、Constructor类、Method类。
反射可以将Java类中的各个组成部分,映射成一个个的不同类型的Java对象。
Class类:代表类的定义。
Method类:代表类的方法。
Field类:代表类的成员变量。
Constructor类:代表类的构造方法。
其中各个部件的功能及其部分方法如下:
Class类中的方法
获取类相关的方法
方法:forName(String className) 用途:根据类名返回类的对象
方法:newInstance() 用途:创建类的实例
方法:getName() 用途:获得类的完整路径名字
方法:getSimpleName() 用途:获得类的名字
方法:getPackage() 用途:获得类的包
方法:getSuperclass() 用途:获得当前类继承的父类的名字
方法:getInterfaces() 用途:获得当前类实现的类或是接口
获得类中属性相关的方法(Field类型对象)
方法:getField(String name) 用途:获得某个公有的属性对象
方法:getFields() 用途:获得所有公有的属性对象
方法:getDeclaredField(String name) 用途:获得某个属性对象
方法:getDeclaredFields() 用途:获得所有属性对象
获得类中构造器相关的方法(Constructor类型对象)
方法:getConstructor(Class... parameterTypes) 用途:获得该类中与参数类型匹配的公有构造方
方法:getConstructors() 用途:获得该类的所有公有构造方法
方法:getDeclaredConstructor(Class... parameterTypes) 用途:获得该类中与参数类型匹配的构造方法
方法:getDeclaredConstructors( ) 用途:获得该类所有构造方法
获得类中方法相关的方法(Method类型对象)
方法:getMethod(String name, Class... parameterTypes) 用途:获得该类某个公有的方法
方法:getMethods( ) 用途:获得该类所有公有的方法
方法:getDeclaredMethod(String name, Class... parameterTypes) 用途:获得该类某个方法
方法:getDeclaredMethods( ) 用途:获得该类所有方法
Field类中的方法
方法:equals(Object obj) 用途:属性与obj相等则返回true
方法:get(Object obj) 用途:获得obj中对应的属性值
方法:set(Object obj, Object value) 用途:设置obj中对应属性值
方法:setAccessible(boolean flag) 用途:设置私有属性是否可访问
Method类中的方法
方法:invoke(Object obj, Object... args) 用途:传递object对象及参数调用该对象的方法
方法:getModifiers( ) 用途:返回方法访问修饰符
方法:getParameters( ) 用途:返回方法参数
方法:getReturnType( ) 用途:返回返回值类型Class
方法:setAccessible(boolean flag) 用途:设置私有方法是否可访问
Constructor类中的方法
方法:newInstance(Object... initargs) 用途:根据传递的参数创建类的对象
方法:setAccessible(boolean flag) 用途:设置私有构造方法是否可访问
举一个简单了例子:
//以正常方法调用类里面的方法
Book book = new Book();
book.dosth(101, 3.14, "小鸡炖蘑菇");
//以反射的方法进行调用类里面的方法
try {
//1.首先先获取class对象
Class bookClass = Class.forName("com.apesource.entity.Book");
Object obj = bookClass.newInstance();
//2.获取其中book类中的方法method,若是私有的同样要进行设置访问性
Method methodx = bookClass.getDeclaredMethod("dosth", int.class,double.class,String.class);
//3.获取到方法之后进行执行
methodx.invoke(obj, 1024,3.14,"天王盖地虎");
System.out.println("============================");
//4.获取方法的修饰符名称等
System.out.println("方法的名称:"+ methodx.getName());
System.out.println("方法的访问修饰符:"+ methodx.getModifiers());
System.out.println("方法的访问修饰符是否为public:" + (methodx.getModifiers() == Modifier.PUBLIC));
//获取方法的参数列表
Parameter[] parameter = methodx.getParameters();
System.out.println("方法的参数列表:"+Arrays.toString(parameter));
System.out.println("方法的参数个数:"+methodx.getParameterCount());
//获取返回值类型
Class RetrunType = methodx.getReturnType();
System.out.println("方法的返回值类型:"+RetrunType);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}