注解(annotation)
一、四大元注解
元注解是java api提供,专门用来注解自定义注解的注解
(1)@Target 注解该用于什么地方?
@Target 表示该注解用于什么地方,可能的值在枚举类 ElemenetType 中,
* @author Joshua Bloch
* @since 1.5
* @jls 9.6.4.1 @Target
* @jls 4.1 The Kinds of Types and Values
*/
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE
}
我大概测了一下,这个包声明,没找到使用它的位置,以后找到了再改,不知道是我使用方法弄错了还是什么的。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2018.12.3
终于找到了这个包声明是在何处使用的了,这里牵扯到一个package-info.java,而这个声明,就在那里用,详细的我马了一篇博客
https://blog.csdn.net/achuo/article/details/50610559
先马着,到时候再看
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
而Type_Use使用的地方就比较广泛了。大概的还是跟下面的差不多,感觉上是哪里都能用的样子。
枚举值 |
说明 |
ElemenetType.CONSTRUCTOR |
构造器前使用 |
ElemenetType.FIELD |
字段(属性)声明,包括枚举常量前使用 |
ElemenetType.LOCAL_VARIABLE |
局部变量前使用 |
ElemenetType.METHOD |
方法前使用 |
ElemenetType.PACKAGE |
包声明(package-info.java中使用) |
ElemenetType.PARAMETER |
形式参数前使用 |
ElemenetType.TYPE |
类、接口(包括注释类型)或枚举声明*/类型前使用 |
ElemenetType.TYPE_PARAMETER |
类泛型前使用 |
ElemenetType.TYPE_USE |
类、接口(包括注释类型)或枚举声明*/类型,属性前使用 |
ElemenetType.ANNOTATION_TYPE |
@interface 注解前使用。 |
这样定义似乎可以使自己的注解在更大的范围使用。
@Target(value={ElementType.TYPE,ElementType.FIELD,ElementType.METHOD})
(2)@Retention 什么时候使用该注解?
与Target类似,有三个可能的值在枚举RetentionPolicy中。
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
}
RetentionPolicy.SOURCE //注解仅存在于源码中,在class字节码文件中不包含
RetentionPolicy.CLASS // 默认的保留策略,注解会在class字节码文件中存在,VM不保存,运行时无法获得。
RetentionPolicy.RUNTIME // 注解会在class字节码文件中存在,VM保存,在运行时可以通过反射获取。
(3)@Documented 注解是否将包含在JavaDoc中?
加上就说明该注解将被包含在javaDoc文档中。
(4)@Inherited 是否允许子类继承该注解?
很简单,允许继承就加上。
二、自定义注解
(1)关键字 @interface
我们通过关键字@interfaceface就可以定义一个注解。如下,我们定义了一个type注解,可以在运行时通过方法获取。这些都是用元注解定义的。
package C;
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)
public @interface My_Type {
String name();
int id;
int[] ids;
}
ps:当注解中使用的属性名为value时,且只有value时,对其赋值时可以不指定属性的名称而直接写上属性值接口;除了value意外的变量名都需要使用name=value的方式赋值。
开始的时候,我也不清楚这个属性可以允许哪些类型定义,但是,我脑瓜子一开,定义了一个报错的属性,把它的错误提示信息翻译一下就是下面的话了,流弊,又学会了一招,不知道哪些是对的,那你就弄一个错的,它就会告诉你哪些是对的了。
only primitive type, String, Class, annotation, enumeration are permitted or 1-dimensional arrays thereof
只允许基本类型、字符串、类、注释、枚举或其一维数组
关于属性详细的,找到了一篇文章,其中有默认值 default 的讲解。其实也简单,就是String name default "你好" ;类似于这样,设定一个默认值。突然发现了一个重点,设定了默认值的属性,在使用该注解时可以不对该属性赋值
https://blog.csdn.net/qq_31408331/article/details/80100242
(2) 注解的使用
就单纯的来讲 注解直接 这样使用,属性配合值,在放在Target元注解约束的范围中,
package D;
import C.*;
import A.*;
@My_Type(value="",name="")
public class Test <T> {
}
当然实际中,都是配合反射用的。反射,我得研究一下。