zoukankan      html  css  js  c++  java
  • java注解

    Java注解

    • 注解概述
    • 内置的基本注解类型
    • 自定义注解类型
    • 对注解进行注解
    • 使用反射获取注解信息

    注解概述

    annotation。可以添加到程序的任何元素上,用来设置一些说明和解释,java开发和部署工具可以读取这些注释,并以某种形式处理这些注释,可生成其他java源文件、XML文档或要与包含注释的程序一起使用的其他构件。

    元数据:描述数据的一种数据。

    注解是代码中的特殊标记,可以再编译、类加载、运行时被读取,并执行响应的处理。

    注解被用来为程序元素(类、方法、成员变量等)设置元数据,它不影响程序代码的执行,无论增加、删除注解程序的执行都不受任何的影响。

    访问和处理注解的工具统称为:APT(Annotation Processing Tool)。

    JDK内置的基本注解类型

    采用@标记,后面根生注解类型名称,name = value的形式。

    @SuppressWarnings(value={"unchecked"});

    注解类型和注解的区别:注解类型是某一类型注解的定义,注解是某注解类型的具体实例。

    重写Override

    限定重写的方法,指明被注解的方法必须是重写超类中的方法,这个注解只能用于方法上。编译器在编译源代码时会检查用@Override标注的方法是否有重写父类的方法。

    被Override注解的方法必须在父类中存在同样的方法,编译才能通过。

    警告Deprecated

    用来标记已过时的成员的注解类型,用来指明被注解的方法是一个过时的方法,不建议使用了。编译到Deprecated的方法的类,编译器会产生警告。

    抑制警告SuppressWarnings

    抑制编译器警告的注解类型,用来指明被注解的方法、边或类在编译时如果有警告信息,就阻止警告。

    public class SuppressWarningsTest {
        public static void main() {
        	List list = new ArrayList();
            list.add("xx");
        }
    }
    

    编译这段代码会得到警告

    注意:SuppressWarningsTest使用了未经检查或不安全的操作。
    注意:要了解详细新,请使用-Xlint:unchecked重新编译
    

    List类必须使用泛型才是安全的,才能进行类型检查。

    两种方法不显示警告:

    public class SuppressWarningsTest {
        public static void main() {
        	List<String> list = new ArrayList<String>();
            list.add("xx");
        }
    }
    
    public class SuppressWarningsTest {
        @SupressWarnings("unchecked")
        public static void main() {
        	List list = new ArrayList();
            list.add("xx");
        }
    }
    

    @SupressWarnings(value ={"unchecked", "deprecation"})表示要抑制未检查和已过时警告。

    自定义注解类型

    注解类型的定义和接口类型的定义差不多,知识在interface前面多加了一个"@"

    public @interface MyAnnotation {
        String value(); //定义一个属性 也可以不定义
    }
    
    class User{
        @MyAnnotation("abc") //此处的abc若没有显示指定属性名,却指定了属性值,而恰好有名为value的属性名,则隐式将值赋给value属性,若果没有value属性,就会出现编译错误。
        public void method(){
            
        }
    }
    

    也可以给属性赋默认值。

    enum Status {ACTIVE, INACTIVE};
    public @interface MyAnnotation {
        String value(); //定义一个属性 也可以不定义
        Status status() default Status.ACTIVE;
    }
    

    也可以显示指定值。

    对注解进行注解

    对注解类型的注解。

    目标Target

    ElementType枚举类型。

    public enum ElementType {
        Type,				//适用于类、接口、枚举
        FILED,				//适用于成员字段
        METHOD,				//适用于方法
        PARAMETER,			//适用于方法的参数
        CONSTRUCTOR,		//适用于构造方法
        LOCAL_VARIABLE,		//适用越局部变量
        ANNOTATION_TYPE,	//适用于注解类型
        PACAGE				//适用于包
    }
    

    使用Target时至少要提供这些枚举值中的一个,以指定该被注解的注解类型可以应用于程序上的哪些元素。

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Target;
    //表示自定义这个注解类型只能作用在构造方法和成员方法上
    @Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
    @interface MethodAnnotation {
        
    }
    @MethodAnnotation //作用在类上 -->编译出错
    public class TargetTest {
        @MethodAnnotaion //作用在方法上 -->正确
        public void myMthod(){}
    }
    
    

    类型Retention

    要读取程序中的注解信息,首先要把注解信息留在程序中,即保存在class文件中才能被读出来。

    三种方式:

    • 编译器处理完,不保留注解到编译后的类文件中
    • 将注解保存在编译后的类文件中,但是在运行时忽略它
    • 将注解保存在编译后的类文件中,并再第一次加载类时读取它。

    三种方式对应java.lang.annotation.RetentionPolicy枚举的3个值

    public enum RetentionPolicy {
        SOURCE, //编译器处理完,不保留注解到编译后的类文件中
        CLASS, //将注解保存在编译后的类文件中,但是在运行时忽略它
        RUNTIME //将注解保存在编译后的类文件中,并再第一次加载类时读取它
    }
    
    
    @Retention(RetentionPolicy.SOURCE)
    @interface My1{}
    @interface My2{}
    @Retention(RetentionPolicy.RUNTIME)
    @interface My3{}
    
    
    

    My1不爆粗你在class文件中,类似java代码中的//注释,在编译成字节码时会被过滤掉。

    My2使用默认值CLASS将被保存在class文件中,但在运行时会被忽略,不能被反射读取。

    My3可以再运行时通过反射来读取它的信息。

    Override、SupressWarnings为SOURCE,Deprecated为RUNTIME。

    文档Document

    注解和文档有关。

    定义为Document的注解必须设置为Retention的值为RUNTIME

    @Document
    @Retention(RetentionPolicy.RUNTIME)
    @interface DocAnnotation {
        
    }
    
    

    继承Inherited

    继承注解。

    父类的注解默认不能被子类继承。

    要想继承需要添加Inherited注解

    利用反射获取注解信息

    注解必须是RUNTIME的。

    java.lang.relect.AnnotatedElement接口定义了四种反射读取注解信息。

    • public Annotation getAnnotation(Class annotationType):如果存在该元素的指定类型的注解,则返回这些注解,否则返回null
    • public Annotation[] getAnnotations():返回此元素上存在的所有注解
    • public Annotation[] getDeclaredAnnotations():返回存在于此元素上的所有注解
    • public boolean isAnnotationPresent(Class annotationType):如果指定类型的直接存在于此元素上则返回true否则返回false

    java.lang.Class类和java.lang.reflect包中的Constructor、Filed、Method、Package类都实现了AnnotatonElement接口。

    package Annotation;
    import java.lang.annotation.*;
    import java.lang.reflect.Method;
    
    @Target({ElementType.TYPE, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @interface MyAnno {
        String value() default "无值";// 默认值
    
    }
    
    @MyAnno
    class UserMyanno{
        @MyAnno("method")
        @Deprecated
        public void test() {
    
        }
    }
    
    public class MyAnnotation {
        public static void main(String[] args) throws SecurityException, NoSuchMethodException {
            //获取指定类注释类的Annotation实例
            Annotation anno1 = UserMyanno.class.getAnnotation(MyAnno.class);
            if (anno1 != null) {
                MyAnno myAnno = (MyAnno)anno1;
                System.out.println("类上的MyAnno注解:value="+myAnno.value());
            }
            //取的test()方法的对应Method实例
            Method method = UserMyanno.class.getMethod("test");
            Annotation[] annotations = method.getAnnotations();
            for (Annotation anno : annotations) {
                System.out.println("注解类型名为:"+anno.annotationType().getName());
            }
        }
    }
    
    
    
  • 相关阅读:
    Qt快速入门学习笔记(基础篇)
    IDEA 创建文件夹总默认根节点问题解决
    SpringBoot 集成MyBatis 中的@MapperScan注解
    Springboot项目下mybatis报错:Invalid bound statement (not found)
    IDEA maven项目查自动查看依赖关系,解决包冲突问题
    Mybatis-generator/通用Mapper/Mybatis-Plus对比
    Mybatis
    在一个已经使用mybatis的项目里引入mybatis-plus,结果不能共存
    springboot整合图像数据库Neo4j
    Spring Boot:Boot2.0版本整合Neo4j
  • 原文地址:https://www.cnblogs.com/DengSchoo/p/12853291.html
Copyright © 2011-2022 走看看