Java注解

187 阅读8分钟

Java 注解

1、@Target

@Target表示我们的注解可以用在哪些地方

ElementType.TYPE:能修饰类、接口或枚举类型
ElementType.FIELD:能修饰成员变量
ElementType.METHOD:能修饰方法
ElementType.PARAMETER:能修饰参数
ElementType.CONSTRUCTOR:能修饰构造器
ElementType.LOCAL_VARIABLE:能修饰局部变量
ElementType.ANNOTATION_TYPE:能修饰注解
ElementType.PACKAGE:能修饰包

2、@Retention

@Retention表示我们的注解在什么地方还有效

  1. RetentionPolicy.SOURCE —— 这种类型的Annotations只在源代码级别保留,编译时就会被忽略。
  2. RetentionPolicy.CLASS —— 这种类型的Annotations编译时被保留,在class文件中存在,但JVM将会忽略
  3. RetentionPolicy.RUNTIME —— 这种类型的Annotations将被JVM保留,所以他们能在运行时被JVM或其他使用

3、@Documented

@Documented注解表明这个注释是由 javadoc记录的,在默认情况下也有类似的记录工具。 如果一个类型声明被注释了文档化,它的注释成为公共API的一部分。

4、@Inherited

  1. 类继承关系中@Inherited的作用: 类继承关系中,子类会继承父类使用的注解中被@Inherited修饰的注解。
  2. 接口继承关系中@Inherited的作用: 接口继承关系中,子接口不会继承父接口中的任何注解,不管父接口中使用的注解有没有被@Inherited修饰。
  3. 类实现接口关系中@Inherited的作用: 类实现接口时不会继承任何接口中定义的注解。

当以后我们在定义一个作用于类的注解时候,如果希望该注解也作用于其子类,那么可以用@Inherited 来进行修饰。

详细可以看此处 @Inherited

5、@PostConstruct

简介

javaEE5引入了@PostConstruct和@PreDestroy两个作用于Servlet生命周期的注解,实现Bean初始化之前和销毁之前的自定义操作

使用场景

在项目中主要是在Servlet初始化之前加载一些缓存数据等

API使用说明

PostConstruct 注释用于在依赖关系注入完成之后需要执行的方法上,以执行任何初始化。此方法必须在将类放入服务之前调用。支持依赖关系注入的所有类都必须支持此注释。即使类没有请求注入任何资源,用 PostConstruct 注释的方法也必须被调用。只有一个方法可以用此注释进行注释。应用 PostConstruct 注释的方法必须遵守以下所有标准:该方法不得有任何参数,除非是在 EJB 拦截器 (interceptor) 的情况下,根据 EJB 规范的定义,在这种情况下它将带有一个 InvocationContext 对象 ;该方法的返回类型必须为 void;该方法不得抛出已检查异常;应用 PostConstruct 的方法可以是 public、protected、package private 或 private;除了应用程序客户端之外,该方法不能是 static;该方法可以是 final;如果该方法抛出未检查异常,那么不得将类放入服务中,除非是能够处理异常并可从中恢复的 EJB。

特点:

1、只有一个非静态方法能使用此注解

2、被注解的方法不得有任何参数

3、被注解的方法返回值必须为void

4、被注解方法不得抛出已检查异常

5、此方法只会被执行一次

servlet执行流程

服务器加载Servlet -> servlet 构造函数的加载 -> postConstruct ->init(init是在service 中的初始化方法. 创建service 时发生的事件.) ->Service->destory->predestory->服务器卸载serlvet 那么问题:spring中Constructor、@Autowired、@PostConstruct的顺序 Constructor >> @Autowired >> @PostConstruct

6、@SuppressWarnings

简介: java.lang.SuppressWarnings是J2SE5.0中标准的Annotation之一。可以标注在类、字段、方法、参数、构造方法,以及局部变量上。

作用: 告诉编译器忽略指定的警告,不用在编译完成后出现警告信息。

使用: @SuppressWarnings(“”) @SuppressWarnings({}) @SuppressWarnings(value={})

抑制警告的关键字

关键字用途
all取消显示所有警告。
boxing抑制与装箱/取消装箱操作相关的警告。
cast抑制与强制转换操作相关的警告。
dep-ann禁止显示与不推荐使用的批注相关的警告。
deprecation抑制相对于弃用的警告。
fallthrough抑制与switch语句中缺少中断有关的警告。
finally抑制不返回的与finally块相关的警告。
hiding抑制与隐藏变量的局部变量相关的警告。
incomplete-switch抑制与switch语句中缺少的条目相关的警告(枚举大小写)。
nls抑制相对于非nls字符串文字的警告。
null抑制与null分析相关的警告。
rawtypes在类参数上使用泛型时,禁止显示与非特定类型相关的警告。
restriction抑制与使用不鼓励或禁止的引用相关的警告。
serial禁止显示与可序列化类的缺少serialVersionUID字段相关的警告。
static-access抑制与不正确的静态访问相关的警告。
synthetic-access抑制与来自内部类的未优化访问相关的警告。
unchecked抑制与未检查操作相关的警告。
unqualified-field-access抑制与未限定字段访问相关的警告。
unused抑制与未使用的代码相关的警告。

7、@Override

@Override注解,只能用于标记方法,并且它只在编译期生效,不会保留在class文件中。

@Override注解标记的方法声明,如果没有覆写或者实现超类的方法声明,或者不是覆写Object的public方法,那么编译就会报错。使用@Override注解,有助于我们尽早发现这样的错误:本来想声明一个“覆写”方法,却偶然声明成“重载”方法。

注意:只能覆写Object示例中的三个方法,对于protected finalize()方法或者final修饰的方法是不能覆写的。

8、@Repeatable

@Repeatable注解表明标记的注解可以多次应用于相同的声明或类型,此注解由Java SE 8版本引入。

9、@SafeVarargs

在声明具有模糊类型(比如:泛型)的可变参数的构造函数或方法时,Java编译器会报unchecked警告。鉴于这些情况,如果程序员断定声明的构造函数和方法的主体不会对其varargs参数执行潜在的不安全的操作,可使用@SafeVarargs进行标记,这样的话,Java编译器就不会报unchecked警告。

package java.lang;

import java.lang.annotation.*;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
public @interface SafeVarargs {}

@SafeVarargs注解,只能用于标记构造函数和方法,由于保留策略声明为RUNTIME,所以此注解可以在运行时生效。

使用的时候要注意:@SafeVarargs注解,对于非static或非final声明的方法,不适用,会编译不通过。

10、@FunctionalInterface

被@FunctionalInterface注解标记的类型表明这是一个函数接口。从概念上讲,函数接口只有一个抽象方法。如果接口声明的抽象方法覆写Object类的公共方法,那这方法不算作接口的抽象方法,因为接口具有Object方法的默认实现。

package java.lang;

import java.lang.annotation.*;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface FunctionalInterface {}

由Java源代码声明我们了解到:@FunctionalInterface注解,只能用于类。其实,它的应用范围更小,只能应用于接口类型。

我们可以使用lambda表达式,方法引用或构造函数引用创建功能接口的实例。

如果一个类型被此标记的话,如果不是以下情况,编译器会报错:

  1. 此类型是接口类型并且不是注解类型、枚举或类
  2. 标记的类型满足函数接口的要求

但是,无论接口声明中是否标记了@FunctionalInterface注解,编译器都会将满足函数接口定义的任何接口视为函数接口。

像我的“函数接口(Functional Interfaces)”这篇博文中声明的函数接口,都可以使用此注解进行显式标记,告诉用户此接口是函数接口。

11、@Deprecated

被注解@Deprecated标记的程序元素是不鼓励使用的程序元素,通常是因为它很危险,或者是因为存在更好的替代方案。

除了对象自身引用自己用@Deprecated标记的方法外,其他情况使用@Deprecated注解标记的类型,方法,字段或构造函数时,Java编译器都会生成deprecation警告。

package java.lang;

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}

由Java源代码声明我们了解到:@Deprecated注解,可以应用在很多地方,包括构造函数、字段、本地变量、方法、包、参数和类。

在一个元素被弃用时,也应使用Javadoc @deprecated标记对其进行记录,如以下示例所示。 在Javadoc注释和注解中使用@符并非巧合:它们在概念上是相关的。 另请注意,Javadoc标记以小写d开头,注解以大写D开头。

Java API中有很多地方都使用了@Deprecated注解,例如像上例中使用的java.util.Date类中的方法:

public Date(String s)

大家可以轻易在Java API中找到示例,我这里就不赘述。