在在我们上面自定义的ReflectTarget类中创建被各种不同访问修饰符修饰的方法,用于测试 package demo.reflect; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * 获取成员方法并调用: * 1)批量的 * public Method[] getMethods() 获取所有的”公有方法”(包含了父类的方法,也包含了Object类中的公有方法) * public Method[] getDeclaredMethods() 获取所有成员方法(包括私有的、受保护的、默认和公有的) * 2)获取单个的 * public Method getMethod(String name,Class<?>...parameterTypes) 获取单个的”公有的“字段 * 参数: * name: 方法名 * Class...: 形参的Class类型对象 * public Method getDeclaredMethod(String name,Class<?>...parameterTypes) 获取某个字段(可以是私有的、受保护的、默认和公有的) * * 调用方法: * Method --> public Object invoke(Object obj,Object...args); * 参数说明: * obj: 待调用方法方法的对象 * args: 调用方法时所传递的实参 */ public class MethodCollector { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //获取class对象 Class reflectTargetClass = Class.forName("demo.reflect.ReflectTarget"); // 获取所有的公有方法 System.out.println("*******************获取所有的public方法,包括父类和Object*******************"); Method[] methodArray = reflectTargetClass.getMethods(); for (Method method : methodArray) { System.out.println(method); } // 获取该类所有的方法 System.out.println("*******************获取该类所有的方法,包括私有的*******************"); methodArray = reflectTargetClass.getDeclaredMethods(); for (Method method : methodArray) { System.out.println(method); } // 获取单个公有方法 System.out.println("*******************获取公有的show1()*******************"); Method method = reflectTargetClass.getMethod("show1", String.class); System.out.println(method); // 通过反射调用无参构造方法,并使用无参构造创建对象 ReflectTarget reflectTarget = (ReflectTarget)reflectTargetClass.getConstructor().newInstance(); method.invoke(reflectTarget,"待反射方法一号"); System.out.println("*******************获取私有的show4()*******************"); method = reflectTargetClass.getDeclaredMethod("show4", int.class); System.out.println(method); method.setAccessible(true); // 接受show4()的返回值 String result = String.valueOf(method.invoke(reflectTarget, 100)) ; System.out.println(result); } } /** * 运行结果如下:我们从运行结果可以看到通过getMethods(),获取到Object类中的公有方法 * *******************获取所有的public方法,包括父类和Object******************* * public static void demo.reflect.ReflectTarget.main(java.lang.String[]) throws java.lang.ClassNotFoundException * public java.lang.String demo.reflect.ReflectTarget.toString() * public void demo.reflect.ReflectTarget.show1(java.lang.String) * public final void java.lang.Object.wait() throws java.lang.InterruptedException * public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException * public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException * public boolean java.lang.Object.equals(java.lang.Object) * public native int java.lang.Object.hashCode() * public final native java.lang.Class java.lang.Object.getClass() * public final native void java.lang.Object.notify() * public final native void java.lang.Object.notifyAll() * *******************获取该类所有的方法,包括私有的******************* * public static void demo.reflect.ReflectTarget.main(java.lang.String[]) throws java.lang.ClassNotFoundException * public java.lang.String demo.reflect.ReflectTarget.toString() * public void demo.reflect.ReflectTarget.show1(java.lang.String) * private java.lang.String demo.reflect.ReflectTarget.show4(int) * protected void demo.reflect.ReflectTarget.show2() * void demo.reflect.ReflectTarget.show3() * *******************获取公有的show1()******************* * public void demo.reflect.ReflectTarget.show1(java.lang.String) * 调用了公有的无参构造函数。。。 * 调用了公有的,String参数的show1(): str = 待反射方法一号 * *******************获取私有的show4()******************* * private java.lang.String demo.reflect.ReflectTarget.show4(int) * 调用了私有的,并且有返回值的,int参数的show4(): index = 100 * show4Result */
注解 注解介绍及作用 由于反射需要获取到相关的类全名(类名+包名),因此我们还需要记录哪些类是通过反射来获取的。我们可以通过XML来保存类相关的信息已供反射用,此外,我们还可以通过注解来保存类相关信息以供反射调用。
注解:提供一种为程序元素设置元数据的方法
元数据是添加到程序元素如方法、字段、类和包上的额外信息
注解是一种分散式的元数据设置方式,XML是集中式的设置方式
注解不能直接干扰程序运行
反编译字节码文件的指令:javap -verbose com.reminis.demo.annotation.TestAnnotation,通过反编译可以看到我们的自定义注解自动继承了Annotation
注解的功能
作为特定得标记,用于告诉编译器一些信息
编译时动态处理,如动态生成代码
运行时动态处理,作为额外信息的载体,如获取注解信息
注解的分类
标准注解:Override、Deprecated、SuppressWarnings
元注解:@Retention、@Target、@Inherited、@Documented,用于修饰注解的注解,通常用在注解的定义上
@Target:注解的作用目标,描述所修饰注解的使用范围
packages、types(类、接口、枚举、Annotation类型)
类型成员(方法、构造方法、成员变量、枚举值)
方法参数和本地变量(如循环变量、catch参数)
@Retention:注解的生命周期(标注注解保留时间的长短)
@Documented:注解是否应当被包含在JavaDoc文档中
@Inherited:是否允许子类继承该注解
自定义注解的实现自定义注解自动实现了 java.lang.annotation.Annotation
public @interface 注解名{ 修饰符 返回值 属性名() 默认值; 修饰符 返回值 属性名() 默认值; ... }