java注解相关
1. 怎么创建一个注解?
注释是一种接口形式,其中关键字接口以 @开头,其主体包含与方法非常相似的注释类型元素声明,如下所示:
a、创建注解
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Cks {
String value() default "This is an element";
int[] type();
}
b、使用注解
import com.ck.admin_fiction.demo.Cks;
@Cks(value = "hjh",type = {1,2,3})
public class Test {
}
注意:为数组元素提供多个值时,必须将它们括在括号中。并且其可选地,只要它们是编译器的常量表达式,就可以提供默认值。
2. 可以从注解方法声明返回哪些对象类型?
返回类型必须是基本类型,String,Class,Enum 或以前类型之一的数组。否则,编译器将抛出错误。
eg: 成功的栗子
enum Complexity {
LOW, HIGH
}
public @interface ComplexAnnotation {
Class<? extends Object> value();
int[] types();
Complexity complexity();
}
由于 _Object_ 不是有效的返回类型,下一个示例将无法编译:
public @interface FailingAnnotation {
Object complexity();
3. 哪些程序元素可以注解?
注释可以应用于整个源代码的多个位置。它们可以应用于类,构造函数和字段的声明。
eg: 举个栗子
@SimpleAnnotation // 类
public class Apply {
<span class="hljs-meta">@SimpleAnnotation</span> <span class="hljs-comment">//属性</span>
<span class="hljs-keyword">private</span> String aField;
<span class="hljs-meta">@SimpleAnnotation</span> <span class="hljs-comment">//方法</span>
<span class="hljs-keyword">public</span> <span class="hljs-title function_">Apply</span><span class="hljs-params">()</span> {
<span class="hljs-comment">// ...可以用在局部变量,包,其他注释类型</span>
}
4. java 元注解有哪些?
java 中有四个元注解,@Target,@Retention,@Documented,@Inherited
元注解 | 描述 |
---|---|
@Target | 表示该注解可以用于什么地方。可能的 ElementType 参数包括: CONSTRUCTOR:构造器的生命 FIELD:域声明(包括 enum 实例) LOCAL_VARIABLE:局部变量声明 METHOD:方法声明 PACKAGE:包声明 PARAMETER:参数声明 TYPE:类、接口(包括注解类型)和 enum 声明 ANNOTATION_TYPE:注解声明(与 TYPE 的区别?,专门用在注解上的 TYPE) TYPE_PARAMETER:Java8 TYPE_USE:Java8 |
@Retention | 表示需要在什么级别保存该注解信息。可选的 RetentionPolicy 参数包括: SOURCE:注解将在编译器丢弃 CLASS:注解在 class 文件中可用,但会被 VM 丢弃 RUNTIME:VM 将在运行期也保留注解,因此可以通过反射机制读取注解的信息 |
@Documented | 将此注解包含在 Javadoc 中 |
@Inherited | 允许子类继承父类中的注解 |
详细介绍如下:
a.@Target 注解
ElementType 这个枚举类型的常量提供了一个简单的分类:注释可能出现在 Java 程序中的语法位置(这些常量与元注释类型 (@Target) 一起指定在何处写入注释的合法位置)
- ElementType 的类型如下
类型 | 小写 | 描述 |
---|---|---|
TYPE | type | 类, 接口 (包括注释类型), 或 枚举 声明 |
FIELD | field | 字段声明(包含枚举常量) |
METHOD | method | 方法声明 |
PARAMETER | parameter | 正式的参数声明 |
CONSTRUCTOR | constructor | 构造函数声明 |
LOCAL_VARIABLE | local_variable | 局部变量声明 |
ANNOTATION_TYPE | annotation_type | 注释类型声明 |
PACKAGE | package | 包声明 |
TYPE_PARAMETER | type_papameter | 类型参数声明 |
TYPE_USE | type_use | 使用类型声明 |
- ElementType 具体源码如下
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
<span class="hljs-comment">/** Field declaration (includes enum constants) */</span>
FIELD,
<span class="hljs-comment">/** Method declaration */</span>
METHOD,
<span class="hljs-comment">/** Formal parameter declaration */</span>
PARAMETER,
<span class="hljs-comment">/** Constructor declaration */</span>
CONSTRUCTOR,
<span class="hljs-comment">/** Local variable declaration */</span>
LOCAL_VARIABLE,
<span class="hljs-comment">/** Annotation type declaration */</span>
ANNOTATION_TYPE,
<span class="hljs-comment">/** Package declaration */</span>
PACKAGE,
<span class="hljs-comment">/**
* Type parameter declaration
*
* <span class="hljs-doctag">@since</span> 1.8
*/</span>
TYPE_PARAMETER,
<span class="hljs-comment">/**
* Use of a type
*
* <span class="hljs-doctag">@since</span> 1.8
*/</span>
TYPE_USE
}
b. @Retention 注解
RetentionPolicy 这个枚举类型的常量描述保留注释的各种策略,它们与元注释 (@Retention) 一起指定注释要保留多长时间
- RetentionPolicy 的类型如下:
类型 | 小写 | 描述 |
---|---|---|
SOURCE | source | 注释只在源码级别保留,编译时被忽略 |
CLASS | class | 注释将被编译器在类文件中记录,但在运行时不需要 JVM 保留,这是默认行为 |
RUNTIME | runtime | 注释将类编辑器记录到类文件中,在运行是保留 JVM,因此可以反读 |
- RetentionPolicy 的源码如下:
package java.lang.annotation;
/**
-
Annotation retention policy. The constants of this enumerated type
-
describe the various policies for retaining annotations. They are used
-
in conjunction with the {@link Retention} meta-annotation type to specify
-
how long annotations are to be retained.
-
@author Joshua Bloch
-
@since 1.5
/
public enum RetentionPolicy {
/*
- Annotations are to be discarded by the compiler.
*/
SOURCE,
/**
- Annotations are to be recorded in the class file by the compiler
- but need not be retained by the VM at run time. This is the default
- behavior.
*/
CLASS,
/**
- Annotations are to be recorded in the class file by the compiler and
- retained by the VM at run time, so they may be read reflectively.
- @see java.lang.reflect.AnnotatedElement
*/
RUNTIME
}
c.@Documented 注解
Documented 注解表明这个注释是由 javadoc 记录的,在默认情况下也有类似的记录工具。 如果一个类型声明被注释了文档化,它的注释成为公共 API 的一部分。
package java.lang.annotation;
/**
- Indicates that annotations with a type are to be documented by javadoc
- and similar tools by default. This type should be used to annotate the
- declarations of types whose annotations affect the use of annotated
- elements by their clients. If a type declaration is annotated with
- Documented, its annotations become part of the public API
- of the annotated elements.
- @author Joshua Bloch
- @since 1.5
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
d.@Inherited 注解
允许子类继承父类中的注解
5. 什么是重复注解?
a. 重复注解
即允许在同一申明类型(类,属性,或方法)前多次使用同一个类型注解
在 java8 以前,同一个程序元素前最多只能有一个相同类型的注解;如果需要在同一个元素前使用多个相同类型的注解,则必须使用注解“容器”
java8 之前使用方式:
public @interface Authority {
String role();
}
//@Authorities 注解作为可以存储多个 @Authority 注解的容器
public @interface Authorities {
Authority[] value();
}
public class RepeatAnnotationUseOldVersion {
@Authorities({@Authority(role="admin"),@Authority(role="manager")})
public void doSomeThing(){
}
}
java8 新增了重复注解,其使用方式为:
@Repeatable(Authorities.class)
public @interface Authority {
String role();
}
public @interface Authorities {
Authority[] value();
}
public class RepeatAnnotationUseNewVersion {
@Authority(role="admin")
@Authority(role="manager")
public void doSomeThing(){ }
}
6. 描述 5 个有用的注解。
类型 | 描述 |
---|---|
@Controller | 该注释声明 Controller 层,一般在 spring 里面使用 |
@RequestMapping | 该注释在方法前或者类前,表示请求的路径 |
@Autowired | 该注释表示自动装配,默认按照类型装配 |
@Service | 用在 Service 层的代码 |
@Repository | 该注解对应数据访问层的 Bean |
@Component | 该注解不确定是哪一层的时候使用该注解 |
7. 是否可以扩展注释?
注释。注释总是扩展 _java.lang.annotation.Annotation,_ 如Java 语言规范中所述。
如果我们尝试在注释声明中使用 _extends_ 子句,我们将得到一个编译错误:
public @interface AnAnnotation extends OtherAnnotation {
// Compilation error}
reference:https://blog.csdn.net/qq_37939251/article/details/83215703