zoukankan      html  css  js  c++  java
  • JavaSE笔记-注释

    Annotation

    Annotation是一个接口,可以把Annotation当成一个修饰符

    Annotation的定义

    注解通过@interface定义

    public @interface TestAnnotation {
      //Annotation的成员变量通过无形参的方法形式声明,方法名和返回值表示成员变量的名字和类型
      String name();
      //默认值通过default指定
      int age() default 32;
    }

    提取Annotation的信息

    提取Annotation的信息需要用到java.lang.reflect的反射API,并且在定义Annotation的@Retention要指定为RetentionPolicy.RUNTIME

    5个基本的Annotation

    @Override->强制重写父类的方法,避免出现父类方法名和子类方法名不一致的错误

    @Deprecated->标记方法已过时

    @Suppress Warnings->取消编译器的警告

    @Safe Varages->解决“堆污染”

     public static void main(String[] args) {
            List list = new ArrayList();
            list.add(20);
            //当把一个不带泛型的对象赋值给一个带泛型的变量,引发的错误叫“堆污染”,发生ClassCastException
            List<String> ls = list;
            System.out.println(ls.get(0));
    }

    @FunctionalInterface->标记接口是一个函数式接口

    @FunctionalInterface
    //函数式接口中有一个抽象方法,多个静态方法和默认方法,如果试图声明第二个抽象方法,会报错
    public interface Test {
        void a();
        default void b(){
            System.out.println("b");
        }
        static void c() {
            System.out.println("c");
        }
    }

    6个Meta Annotation

    @Retention

    Retention用于修饰Annotation,作用是指定修饰的Annotation可以保留多长时间

    //Retention有一个RetentionPolicy的成员变量value
    // value的取值:RetentionPolicy.RUNTIME,RetentionPolicy.CLASS,RetentionPolicy.SOURCE
    //RUNTIME、CLASS会将Annotation记录在class文件中,SOURCE会直接丢弃Annotation
    //RUNTIME可以通过反射获取Annotation的信息,class不可以
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Test {
    }

    @Target

    Target用于修饰Annotation,作用是指定Annotation可以修饰那些程序单元

    • ElementType.ANNOTATION_TYPE 可以给一个注解进行注解
    • ElementType.CONSTRUCTOR 可以给构造方法进行注解
    • ElementType.FIELD 可以给属性进行注解
    • ElementType.LOCAL_VARIABLE 可以给局部变量进行注解
    • ElementType.METHOD 可以给方法进行注解
    • ElementType.PACKAGE 可以给一个包进行注解
    • ElementType.PARAMETER 可以给一个方法内的参数进行注解
    • ElementType.TYPE 可以给一个类型进行注解,比如类、接口、枚举
    //Retention有一个ElementType的成员变量value
    @Target(ElementType.FIELD)
    public @interface Test {
    }
    class A{
    @Test
    private int a;
    }

    @Documented

    Documented用于修饰Annotation,作用是指定被Documented修饰的Annotation类会被javadoc提取成文档

    @Inherited

    Inherited用于修饰Annotation,作用是指定被修饰的Annotation具有继承性

    @Inherited
    //注意这要写上RUNTIME,不然下边的isAnnotationPresent()不能通过反射拿到Annotation信息
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Test {
    }
    
    @Test
    class A{
    }
    //B类并未使用@Test注解,但是B类也被@Test修饰了
    class B extends A{
        public static void main(String[] args){
            System.out.println(B.class.isAnnotationPresent(Test.class));
        }
    }

    @Repeatable

    Repeatable用于修饰Annotation,可以使用多个相同名字的注解

    //在没有使用Repeatable前,我们要给某个程序元素注解多个相同名字的注解时,必须要有一个容器注解
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Result{
        String name();
        int age();
    }
    @Retention(RetentionPolicy.RUNTIME)
    @interface Results{
        Result[] value();
    }
    @Results({@Result(name="张三",age=16),
            @Result(name="李四",age=20)}
    )
    class Person{
        public static void main(String[] args){
            Class<Person> pClass = Person.class;
            Results results = pClass.getDeclaredAnnotation(Results.class);
            System.out.println(results);
        }
    }
    //使用Repeatable注解修改
    @Retention(RetentionPolicy.RUNTIME)
    @Repeatable(Results.class)
    public @interface Result{
        String name();
        int age();
    }
    @Retention(RetentionPolicy.RUNTIME)
    @interface Results{
        Result[] value();
    }
    @Result(name="张三",age=16)
    @Result(name="李四",age=20)
    class Person{
        public static void main(String[] args){
            Class<Person> pClass = Person.class;
            Results results = pClass.getDeclaredAnnotation(Results.class);
            System.out.println(results);
        }
    }

    实际上任然需要容器注解,只是红色的部分写法发生了变化

    ElemType

    Java 8 中 ElementType 增加了 ElementType.TYPE_USE 和 ElementType.TYPE_PARAMETER。它们都可以限制哪个类型可以进行注解。能在局部变量、泛型类、父类和接口的实现处使用,甚至能在方法上声明异常的地方使用。

    ElementType.TYPE_PARAMETER(Type parameter declaration) 用来标注类型参数。

    @Target(ElementType.TYPE_PARAMETER)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface TypeParameterAnnotation {
        
    }
    
    // 如下是该注解的使用例子
    public class TypeParameterClass<@TypeParameterAnnotation T> {
        public <@TypeParameterAnnotation U> T foo(T t) {
            return null;
        }    
    }

    ElementType.TYPE_USE(Use of a type) 能标注任何类型名称,包括上面这个(ElementType.TYPE_PARAMETER的)

    ublic class TestTypeUse {
    
        @Target(ElementType.TYPE_USE)
        @Retention(RetentionPolicy.RUNTIME)
        public @interface TypeUseAnnotation {
            
        }
        
        public static @TypeUseAnnotation class TypeUseClass<@TypeUseAnnotation T> extends @TypeUseAnnotation Object {
            public void foo(@TypeUseAnnotation T t) throws @TypeUseAnnotation Exception {
                
            }
        }
        
        // 如下注解的使用都是合法的
        @SuppressWarnings({ "rawtypes", "unused", "resource" })
        public static void main(String[] args) throws Exception {
            TypeUseClass<@TypeUseAnnotation String> typeUseClass = new @TypeUseAnnotation TypeUseClass<>();
            typeUseClass.foo("");
            List<@TypeUseAnnotation Comparable> list1 = new ArrayList<>();
            List<? extends Comparable> list2 = new ArrayList<@TypeUseAnnotation Comparable>();
            @TypeUseAnnotation String text = (@TypeUseAnnotation String)new Object();
            java.util. @TypeUseAnnotation Scanner console = new java.util.@TypeUseAnnotation Scanner(System.in);
        }
    }
  • 相关阅读:
    jquery使用ajax
    Docker下使用centos无法使用systemctl怎么办
    memcache安装及解决无法远程连接的问题
    NetCore控制台程序-使用HostService和HttpClient实现简单的定时爬虫
    PHP代码审计01
    路由和交换-
    路由和交换-VLAN
    路由和交换-FTP配置
    51job招聘信息爬虫
    豆瓣电影排行250爬虫
  • 原文地址:https://www.cnblogs.com/vshen999/p/8809708.html
Copyright © 2011-2022 走看看