Java中的反射与注解

        //Java中的反射
        //Java反射机制是指在运行状态中
        //
        //对于任意一个类,都能知道这个类的所有属性和方法;
        //对于任何一个对象,都能够调用它的任何一个方法和属性;

        //这样动态获取新的以及动态调用对象方法的功能就叫做反射。
        //反射机制的相关类
        //
        //Class         代表类实类
        //Field         代表类的成员变量
        //Method        代表类方法
        //Constructor   代表类的构造函数

        Class clz = ContentBean.class;
        try {//获得公有属性
            Field field = clz.getField("content");
            System.out.println("field = " + field.getName());
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        //获得所有公有属性
        Field[] fields = clz.getFields();
        for (Field f :
                fields) {
            System.out.println("field = " + f.getName());
        }
        System.out.println("_____________________________________________________________");
        try {//获得某个类的属性
            Field declaredField = clz.getDeclaredField("author");
            System.out.println("修饰符:" + Modifier.toString(declaredField.getModifiers())
                    + "  declaredField = " + declaredField.getName());
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        //获得所有属性
        Field[] declaredFields = clz.getDeclaredFields();
        for (Field df :
                declaredFields) {
            System.out.println("修饰符:" + Modifier.toString(df.getModifiers())
                    + "  declaredField = " + df.getName());
        }
        System.out.println("_____________________________________________________________");
        //获得与参数匹配的公有注解对象
        Annotation annotation = clz.getAnnotation(Deprecated.class);
        if (annotation != null)
        System.out.println("annotation:" + annotation.annotationType().getName());
        //获得所有公有注解对象
        Annotation[] annotations = clz.getAnnotations();
        for (Annotation a :
                annotations) {
            System.out.println("修饰符:" + Modifier.toString(a.annotationType().getModifiers()) + "  a = " + annotation.annotationType().getName());
        }
        System.out.println("_____________________________________________________________");
        //获得某个匹配的注解对象
        Annotation declaredAnnotation = clz.getDeclaredAnnotation(Deprecated.class);
        if (declaredAnnotation != null)
        System.out.println("declaredAnnotation:" + declaredAnnotation.annotationType().getName());
        //获得所有注解对象
        Annotation[] declaredAnnotations = clz.getDeclaredAnnotations();
        for (Annotation da:
             declaredAnnotations) {
            System.out.println("修饰符:" + Modifier.toString(da.annotationType().getModifiers()) + "  da:" + da.annotationType().getName());
        }
        System.out.println("_____________________________________________________________");
        //获得某个参数类型匹配的公有构造函数
        try {
            Constructor constructor = ContentBean.class.getConstructor();
            System.out.println("constructor = " + constructor.getName());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        //获得所有公有构造函数
        Constructor[] constructors = ContentBean.class.getConstructors();
        for (Constructor c :
                constructors) {
            System.out.println("修饰符:" + Modifier.toString(c.getModifiers()) + "  c:" + c.getName());
        }
        System.out.println("_____________________________________________________________");
        //获得某个参数类型匹配的构造函数
        try {
            Constructor dc = ContentBean.class.getDeclaredConstructor();
            System.out.println("dc = " + dc.getName());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        //获得所有构造函数
        Constructor[] dcs = ContentBean.class.getDeclaredConstructors();
        for (Constructor dc: dcs) {
            System.out.println("修饰符:" + Modifier.toString(dc.getModifiers()));
            System.out.println("所有参数:");
            Parameter[] parameters = dc.getParameters();
            for (Parameter p :
                    parameters) {
                System.out.println("修饰符 = " + p.getType().getSimpleName() + " p = " + p.getName());
            }
         }
        System.out.println("_____________________________________________________________");
        //获得某个参数类型与函数名称匹配的函数
        try {
            Method method = ContentBean.class.getMethod("getName");
            System.out.println("method = " + method.getName() + "    " + method.getReturnType().getSimpleName());
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        //...........省略getMethods()、getDeclaredMethod(...)、getDeclaredMethods()...........
        System.out.println(clz.isAnnotation());//是否是注解类型
        System.out.println(clz.isAnnotationPresent(Deprecated.class));//是否被指定注解类型修饰
        System.out.println(clz.isAnonymousClass());//是否是匿名类
        System.out.println(clz.isArray());//是否是数组
        System.out.println(clz.isEnum());//是否是枚举类
        System.out.println(clz.isInterface());//是否是接口类
        System.out.println(clz.isLocalClass());//是否是局部类
        System.out.println(clz.isMemberClass());//是否是内部类

        //Field类
        //equals(object):属性与obj相等则返回true
        //get(object):获得obj中对应的属性值
        //set(object, value);设置obj中对应属性值
        ContentBean c = new ContentBean();
        c.setAuthor("测试");
        try {
            Field field = clz.getDeclaredField("author");
            field.setAccessible(true);
            System.out.println("author = " + field.get(c));
            field.set(c, "内容变了");
            System.out.println("author = " + field.get(c));
        }  catch (IllegalAccessException | NoSuchFieldException e) {
            e.printStackTrace();
        }

        //Method类
        //invoke(obj, args...)
        try {
            Method method = clz.getDeclaredMethod("setAuthor", String.class);
            method.invoke(c, "内容又变了");
            Method method2 = clz.getDeclaredMethod("getAuthor");
            System.out.println(method2.invoke(c));
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }

        //Constructor类
        //newInstance方法
        try {
            Constructor constructor = clz.getDeclaredConstructor(String.class, String.class);
            constructor.setAccessible(true);
            ContentBean cb = (ContentBean)constructor.newInstance("dragon", "龙博");
            System.out.println(cb.getName());
            System.out.println(cb.getAuthor());
        } catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }

        //正确构造反射的步骤
        try {
            Class className = Class.forName("com.dragon.devl.test.ContentBean");
            //获取到类对象后,自行决定反射其内部哪些方法,比如反射setName方法
            Method method = className.getDeclaredMethod("setName", String.class);
            //获取到方法对象后,需要构建对应的类实例,才可以反射该方法
            Constructor constructor = className.getDeclaredConstructor();
            //constructor.setAccessible(true);无参构造函数是public类型,所以不需要设置权限
            Object obj = constructor.newInstance();//调用该构造方法获取对象
            method.invoke(obj, "测试");//调用setName方法。

            //最后我们输出数据
            Method getMethod = className.getDeclaredMethod("getName");
            System.out.println(getMethod.invoke(obj));

            //如果只是调用静态方法,则不需要构造实例,直接使用method.invoke(null, args)调用
            Method staticMethod = className.getDeclaredMethod("setDesc", String.class);
            staticMethod.invoke(null, "设置静态属性值");
            Method getStaticMethod = className.getDeclaredMethod("getDesc");
            System.out.println(getStaticMethod.invoke(null));
            System.out.println(ContentBean.getDesc());
        } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {///由于可能会出现找不到类的情况,所以需要捕获异常
            e.printStackTrace();
        }

Java注解

Annotation(注解)就是Java提供了一种源程序中的元素关联任何信息或者任何元数据(metadata)的途径和方法。

Annotation是被动的元数据,永远不会有主动行为

//自定义注解,使用@interface表示这是一个注解,Annotation只有成员变量,没有方法
//Annotation的成员变量在Annotation中以无形参的方法形式来声明,其方法名定义了该成员变量的名字,其返回值定义了该成员变量的类型
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
@Documented
@Inherited
public @interface BindContent {
    String content() default "nothing";
    boolean canBeNull() default false;
}
//在自定义注解内部使用的注解称之为元注解
//@Retention 用来标记自定义注解的有效范围
//1、RetentionPolicy.SOURCE:只在源代码中保留,一般是用来增加代码的理解性或者帮助代码检查之类的,例如override
//2、RetentionPolicy.CLASS:默认值,把注解保留到编译后的字节码文件中,但运行时无法得到
//3、RetentionPolicy.RUNTIME:保留到编译后的字节码文件中,同时也能在运行时获取。

//@Target:指定Annotation用于修饰哪些程序元素
//内部包含一个value[]成员变量
//允许传入以下值
//ElementType.TYPE:能修饰类、接口或枚举类
//ElementType.FIELD:修饰成员变量
//ElementType.METHOD:修饰方法
//ElementType.PARAMETER:修饰参数
//ElementType.CONSTRUCTOR:修饰构造器
//ElementType.LOCAL_VARIABLE:修饰局部变量
//ElementType.ANNOTATION_TYPE:修饰注解
//ElementType.PACKAGE:修饰包

//@Documented表示可以在javadoc中被找到
//@Interited:表示注解里的内容可以被子类继承,只针对class类

//类继承关系中,子类会继承父类使用的注解中被@Inherited修饰的注解
//
//接口继承关系中@Inherited的作用
//
//接口继承关系中,子接口不会继承父接口中的任何注解,不管父接口中使用的注解有没有被@Inherited修饰
//
//类实现接口关系中@Inherited的作用
//
//类实现接口时不会继承任何接口中定义的注解

然后通过反射来获取对应的注解内容

@BindContent(content = "Class desc")
public class AnnotationTesting {

    @BindContent()
    public String content;

    public void printInfo() {
        System.out.println(content);
    }

    public static void main(String[] args) {
        try {
            Class c = Class.forName("com.dragon.devl.test.AnnotationTesting");
            AnnotationTesting annotationTesting = (AnnotationTesting)c.newInstance();
            Field[] fields = c.getDeclaredFields();
            for (Field f :
                    fields) {
                if (f.isAnnotationPresent(BindContent.class)) {
                    BindContent bc = f.getAnnotation(BindContent.class);
                    f.set(annotationTesting, bc.content());
                }
            }
            annotationTesting.printInfo();
        } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

}

 

你可能感兴趣的:(Java,反射,java)