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);
    }
}
原文地址:https://www.cnblogs.com/vshen999/p/8809708.html