第9章-第4节-再谈Java中的反射
在运行期探究和使用编译期的内容(编译期配置的注解),要用到Java中的灵魂技术——反射!
1、首先我们需要回顾一下我们之前讲的反射的知识
反射机制:是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意属性和方法;这种动态获取信 息以及动态调用对象方法的功能称为 java 语言的反射机制;
2、反射知识补充:
1)、Method对象,获取method对象:
| 方法 | 备注 |
|---|---|
| Method[] getMethods() | 返回所有[公共]成员方法对象的数组,包括继承的 |
| Method[] getDeclaredMethods() | 返回所有成员方法对象的数组,不包括继承的Method |
| getMethod(String name, Class<?>... parameterTypes) | 返回单个公共成员方法对象Method |
| getDeclaredMethod(String name, Class<?>... parameterTypes) | 返回单个成员方法对象 |
public class Student {//私有的,无参无返回值private void show() {System.out.println("私有的show方法,无参无返回值");}//公共的,无参无返回值public void function1() {System.out.println("function1方法,无参无返回值");}//公共的,有参无返回值public void function2(String name) {System.out.println("function2方法,有参无返回值,参数为" + name);}//公共的,无参有返回值public String function3() {System.out.println("function3方法,无参有返回值");return "aaa";}//公共的,有参有返回值public String function4(String name) {System.out.println("function4方法,有参有返回值,参数为" + name);return "aaa";}
}
public class Demo5 {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {//method1();//method2();//method3();//method4();//method5();}private static void method5() throws ClassNotFoundException, NoSuchMethodException {
// Method getDeclaredMethod(String name, Class<?>... parameterTypes):返回单个成员方法对象Class clazz = Class.forName("com.aaa.Student");//获取一个成员方法showMethod method = clazz.getDeclaredMethod("show");System.out.println(method);} private static void method4() throws ClassNotFoundException, NoSuchMethodException {Class clazz = Class.forName("com.aaa.Student");//获取一个有形参的方法function2Method method = clazz.getMethod("function2", String.class);System.out.println(method);}private static void method3() throws ClassNotFoundException, NoSuchMethodException {//Method getMethod(String name, Class<?>... parameterTypes) :返回单个公共成员方法对象Class clazz = Class.forName("com.aaa.Student");//获取成员方法function1Method method1 = clazz.getMethod("function1");System.out.println(method1);} private static void method2() throws ClassNotFoundException {
//Method[] getDeclaredMethods():返回所有成员方法对象的数组,不包括继承的Class clazz = Class.forName("com.aaa.Student");Method[] methods = clazz.getDeclaredMethods();for (Method method : methods) {System.out.println(method);}} private static void method1() throws ClassNotFoundException {// Method[] getMethods():返回所有公共成员方法对象的数组,包括继承的//1.获取class对象Class clazz = Class.forName("com.aaa.Student");//2.获取成员方法对象Method[] methods = clazz.getMethods();//3.遍历for (Method method : methods) {System.out.println(method);}}
}
2)、使用Method对象运行方法—Object invoke(Object obj, Object... args)运行方法
public class tDemo6 {public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
// Object invoke(Object obj, Object... args):运行方法
// 参数一:用obj对象调用该方法
// 参数二:调用方法的传递的参数(如果没有就不写)
// 返回值:方法的返回值(如果没有就不写)//1.获取class对象Class clazz = Class.forName("com.aaa.Student");//2.获取里面的Method对象 function4Method method = clazz.getMethod("function4", String.class);//3.运行function4方法就可以了//3.1创建一个Student对象,当做方法的调用者Constructor con = clazz.getConstructor();Student student = (Student)con.newInstance();//3.2运行方法Object result = method.invoke(student, "zhangsan");//4.打印一下返回值System.out.println(result);}
}
3、反射操作获取注解:
public class TestAnnotation {public static void main(String[] args){try {//获取Student的Class对象Class stuClass = Class.forName("pojos.Student");//说明一下,这里形参不能写成Integer.class,应写为int.classMethod stuMethod = stuClass.getMethod("study",int.class);if(stuMethod.isAnnotationPresent(CherryAnnotation.class)){System.out.println("Student类上配置了CherryAnnotation注解!");//获取该元素上指定类型的注解CherryAnnotation cherryAnnotation = stuMethod.getAnnotation(CherryAnnotation.class);System.out.println("name: " + cherryAnnotation.name() + ", age: " + cherryAnnotation.age()+ ", score: " + cherryAnnotation.score()[0]);}else{System.out.println("Student类上没有配置CherryAnnotation注解!");}} catch (ClassNotFoundException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();}}
}
注意:
-
如果我们要获得的注解是配置在方法上的,那么我们要从Method对象上获取;如果是配置在属性上,就需要从该属性对应的Field对象上去获取,如果是配置在类型上,需要从Class对象上去获取。总之在谁身上,就从谁身上去获取!
-
isAnnotationPresent(Class<? extends Annotation> annotationClass)方法是专门判断该元素上是否配置有某个指定的注解;
-
getAnnotation(Class<A> annotationClass)方法是获取该元素上指定的注解。之后再调用该注解的注解类型元素方法就可以获得配置时的值数据;
-
反射对象上还有一个方法getAnnotations(),该方法可以获得该对象身上配置的所有的注解。它会返回给我们一个注解数组,需要注意的是该数组的类型是Annotation类型,这个Annotation是一个来自于java.lang.annotation包的接口。