zoukankan      html  css  js  c++  java
  • 注解

    从高层次来讲,注解是与代码紧耦合的元数据;从底层来看,注解就是一组键值对;从语法上来看,注解就是一种特殊的接口。

    注解的生存期与注解的处理

    注解的两个元注解@Target@Retention定义了注解的使用目标和生存期。注解的生存期在java.lang.annotation.RetentionPolicy中进行了枚举,包括:

    • SOURCE 存在源码中,编译阶段被丢弃
    • CLASS 默认级别,存在类文件中,VM加载时将丢弃
    • RUNTIME 运行时,存在于运行时,可以通过反射API获取

    而处理注解的方式通常为以下几种情况:

    • 使用javax.annotation.processing处理器API,在编译前对注解进行处理,所有生存期的注解都能被处理;
    • 使用字节码处理框架如bcel对class文件进行读取并处理其中的注解,此时SOURCE级注解已经不存在;
    • 使用java.lang.instrument设备API,获得class文件并处理其中的注解,此时SOURCE级注解已经不存在;
    • 使用java.lang.annotationAPI,获取反射对象的注解并处理,此时SOURCE&CLASS级注解已经不存在。这是最常用的方式。

    《Java核心技术 卷2》(第9版)第10章节对上面方式都进行了介绍和基本实现,但是存在文字晦涩,第三种方式的示例代码错误等问题。在调试示例代码时需注意:

    1.由于bcel项目已经基本停滞,官网也推荐用户转向ASM框架。导致bcel存在版本兼容问题,其修改字节码后并未修改其StackMapTable,只适合JAVA 1.6及其以下的字节码文件。在调试时JDK需采用1.7及其以下版本。JDK1.7运行修改后的类文件,需要添加VM参数-XX:-UseSplitVerifier

    2.在示例类EntryLoggingAgent中存在BUG,需要做以下修改:

    instr.addTransformer(new ClassFileTransformer() {
        public byte[] transform(ClassLoader loader, String className, Class<?> cl,
                                ProtectionDomain pd, byte[] data) {
            className = className.replace('/', '.');//添加这一句
            ...

    元注解@Inherited

    如果注解类型使用了@Inherited,声明该注解的父类会将其注解继承给子类,这种继承关系只有用在类时才有效。

    下面用例子说明:
    首先是注解类型Country用来声明人所属国家。

    @Inherited
    @Retention(RetentionPolicy.RUNTIME)//因为是运行时测试,所以需要让注解在运行时保留
    public @interface Country {
        String name();
    }

    然后是Chinese表示中国人,其所属国家为China

    /**
     * 中国人
     */
    @Country(name = "China")
    public class Chinese {
    }

    子类SiChuanese表示四川人。

    /**
     * 四川人
     */
    public class SiChuanese extends Chinese {
    }

    测试SiChuanese是否从其父类Chinese继承了注解Country

    public class CountryTest {
        @Test
        public void testCountry(){
            Assert.assertEquals("China",SiChuanese.class.getAnnotation(Country.class).name());//测试通过
        }
    }

    单值注解

    可能好奇使用Spring框架时为什么当只需要一个元素时,可以省略元素名。如在Spring中:

    @RequestMapping("/index")

    这其实是注解的语法部分,叫做单值注解,特殊的value元素,当只指定该元素值时,可以省略元素名和等号。

    参考《Java核心技术 卷2》 744页

    其实质等于:

    @RequestMapping(value="/index")

    又因为Spring使用自定义注解@AliasFor声明了注解别名。因此等价于下面的注解:

    @RequestMapping(name="/index")



    https://www.cnblogs.com/redreampt/p/7906973.html
  • 相关阅读:
    iOS -一些常用的方法
    handoff了解
    UIlabel
    扩展运行机制
    github -- fork提交项目
    iOS
    AppDelegate解析
    KVC
    KVO
    xcode升级后, 插件失效修复
  • 原文地址:https://www.cnblogs.com/whymoney1000/p/10747179.html
Copyright © 2011-2022 走看看