程序中两个概念:
注释:让人们为了看懂某段程序写的什么
注解:让编译器了解这段程序是干什么的,该怎样使用这段程序
我们在编写自己的类时,经常会重写父类方法,这是在重写的方法上面会有注解@Override
,这是Java自带的重写方法的注解,我们以这个注解为例来分析Java中的注解是怎么回事,我们点击去这个注解,得到这样一段代码
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
我们发现这段代码中除了一个定义的类或接口之外好像又有两个注解,先来看第一个注解@Target
,这个注解使用了指定注解作用范围,点击得到这样一段代码
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
/**
* Returns an array of the kinds of elements an annotation type
* can be applied to.
* @return an array of the kinds of elements an annotation type
* can be applied to
*/
ElementType[] value();
}
这里好像又出现了这几个注解,先抛开注解不看,我们来看一看注解下面的这段代码,发现这里有个@interface
,定义一个注解都需要加上这个代码,接着往下看ElementType[] value()
,这个可不是定义注解的方法,而是一个注解的属性值,我们可以看出这个字段是ElementType
类型的,我们点进去看一看,
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
}
发现这是一个枚举类型,枚举中 TYPE 、FIELD、METHOD等字段就指定了注解作用范围,我们看到@Target(ElementType.ANNOTATION_TYPE)
中使用了ElementType中的ANNOTATION_TYPE字段。
再继续分析@Retention
注解,
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
发现这里有一个RetentionPolicy
类型的字段,而RetentionPolicy
也是一个枚举类型,有SOURCE、CLASS、RUNTIME三个字段,这个注解是用来定义注解生命周期。
根据Java自带的注解自己创建一个注解,可以看到每个注解都有一个@interface
,得出每个注解都是一个接口。当我们编译程序时,的确生成了一个class文件,在注解源文件中也可以看到import java.lang.annotation.*
语句,表明注解继承了annotation接口。
接下来写上我们的元注解:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface holy {
}
@Target(ElementType.METHOD)
:自定义注解只能作用在 方法上
@Retention(RetentionPolicy.RUNTIME)
:自定义注解作用周期为整个程序运行周期
注解还需要参数
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface holy {
String name() ;
}
我们在注解中定义了一个String类型的变量name,与在普通类中的变量不同,注解中定义的变量需要在后面加上括号。
自定义注解使用:
public class Test{
@holy(name="Herry"))
public void annotationTest(){
System.out.println("this is tset");
}
public static void main(String[] args) {
Test test =new Test();
test.annotationTest();
}
}
在注解中设置参数默认值,在使用该注解时就无需填写该参数,设置默认值在变量后面加上default 变量名
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface holy {
String name() default "Herry";
}
在使用只有一个参数的注解时,可以直接写参数值,不必写参数名,即:
public class Test{
@holy("Herry"))
public void annotationTest(){
System.out.println("this is tset");
}
public static void main(String[] args) {
Test test =new Test();
test.annotationTest();
}
}