New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

学习Java注解 #15

Open
thinkerou opened this Issue May 21, 2018 · 0 comments

Comments

Projects
None yet
1 participant
@thinkerou
Copy link
Owner

thinkerou commented May 21, 2018

参考:Java Annotations

注解可以做什么?

  • 编译时指令
  • 构建时指令
  • 运行时指令

使用注解来修饰什么?

  • 接口
  • 方法
  • 方法参数
  • 属性
  • 局部变量

一个完整的使用注解的示例如下:

@Entity
public class Vehicle {
    @Persistent
    protected String vehicleName = null;

    @Getter
    public String getVehicleName() {
        return this.vehicleName;
    }

    public void setVehicleName(@Optional vehicleName) {
        this.vehicleName = vehicleName;
    }

    public List addVehicleNameToList(List names) {
        @Optional
        List localNames = names;

        if(localNames == null) {
            localNames = new ArrayList();
        }
        localNames.add(getVehicleName());

        return localNames;
    }
}

内置注解有哪些?

@deprecated

  • 可以用来标记方法、类、属性
  • 如果上述三种元素不再使用,请使用 @deprecated 注解
  • 如果代码中使用了已经 @deprecated 注解的类、方法、属性,则编译器会给出警告
  • 使用方式,如注解一个类:
    @Deprecated
    public class MyComponent {
    }
  • 使用 @deprecated 注解后,建议同时使用对应的@deprecated JavaDoc符号,并解释为什么被弃用及替用方案,如:
    @Deprecated
    /**
     * @deprecated This class is full of bugs. Use MyNewComponent instead.
     */
    public class MyComponent {
    }

@override

  • 修饰对父类进行重写的方法
  • 如果修饰的方法并非父类的方法,则编译器会提示错误
  • 在子类中重写父类或接口的方法,@override 注解并非必须,但建议使用
  • 使用 Override 注解的示例:
    public class MySuperClass {
      public void doTheThing() {
        System.out.println("Do the thing");
      }
    }
    
    public class MySubClass extends MySuperClass{
      @Override
      public void doTheThing() {
        System.out.println("Do it differently");
      }
    }

@SuppressWarnings

  • 用来抑制编译器生成警告信息
  • 可以修饰类、方法、方法参数、属性、局部变量
  • 当一个方法调用一个弃用的方法或进行不安全的类型转换时,编译器会生成警告,此时就可以使用 @SuppressWarnings 注解来抑制编译器生成警告
  • 说明:使用 @SuppressWarnings 注解应该采取就近原则,如一个方法出现警告,应该尽量使用 @SuppressWanings 注解这个方法,而不是注解方法所在的这个类
  • 一个使用示例:
    @SuppressWarnings
    public void methodWithWarning() {
    }

怎样创建自己的注解?

  • 注解和类、接口一样,定义在自己的文件里
    @interface MyAnnotation {
      String value();
      String name();
      int age();
      String[] newNames();
    }
  • @interface 关键字告诉编译器这时一个注解
  • 注解元素的定义类似于接口的方法,这些元素有类型和名称,这些类型可以是:
    • 原始类型
    • String
    • Class
    • annotation
    • 枚举
    • 一维数组
  • 使用上面注解的示例:
    @MyAnnotation(
      value="123",
      name="Jakob",
      age=37,
      newNames={"Jenkov", "Peterson"}
    )
    public class MyClass {
    }
  • 需要为所有注解元素设置值,一个都不能少
  • 注解元素可以设置默认值,如:
    @interface MyAnnotation {
      String value() default "";
      String name();
      int age();
      String[] newNames();
    }
  • 这里设置了value元素的默认值为空串,在使用时就可以不为value设置值,如:
    @MyAnnotation(
      name="Jakob",
      age=37,
      newNames={"Jenkov", "Peterson"}
    )
    public class MyClass {
    }

@retention

  • @retention 是用来修饰注解的注解
  • 可以控制注解是否写入class文件
  • 可以控制class文件中的注解是否在运行时可见
  • 控制很简单,示例如:
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    
    @Retention(RetentionPolicy.RUNTIME)
    @interface MyAnnotation {
      String   value() default "";
    }
  • 注解 @retention 的取值有:
    • RetentionPolicy.SOURCE 表明注解仅在源码中,不在对应的class文件中,更不能运行时可见,常见的注解为:@override@SuppressWarnings
    • RetentionPolicy.CLASS 默认的注解保留策略,注解存在于对应的class文件中,但不能运行时可见
    • RetentionPolicy.RUNTIME 可以在运行时被访问到,通常与反射结合使用

@target

  • 使用**@target**注解可以设定自定义注解可以修饰哪些Java元素,如:
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Target;
    @Target({ElementType.METHOD})
    public @interface MyAnnotation {
      String   value();
    }
  • 该示例说明MyAnnotation注解只能修饰方法
  • 注解 @target 的取值有:
    • ElementType.ANNOTATION_TYPE(修饰注解)
    • ElementType.CONSTRUCTOR
    • ElementType.FIELD
    • ElementType.LOCAL_VARIABLE
    • ElementType.METHOD
    • ElementType.PACKAGE
    • ElementType.PARAMETER
    • ElementType.TYPE(修饰任何类型)

@inherited

  • 如果需要让一个类和其子类都包含某个注解,就可以使用**@inherited**注解进行修饰,如:
    @Inherited
    public @interface MyAnnotation {
    }
    
    @MyAnnotation
    public class MySuperClass {
    }
    
    public class MySubClass extends MySuperClass {
    }
  • 使用**@inherited**注解修饰注解MyAnnotation
  • 使用MyAnnotation注解MySuperClass
  • 实现一个类MySubclass继承自MySuperClass,则MySubClass也拥有MyAnnotation注解。

@thinkerou thinkerou added the Java label May 21, 2018

@thinkerou thinkerou self-assigned this May 21, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment