java 类属性如何注释-html注释css字体属性
我们来看看之前的Test注解是怎么声明的:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {}
我们使用@interface声明Test注解,使用@Target注解传入ElementType.METHOD参数表示@Test只能用在方法上,@Retention(RetentionPolicy.RUNTIME)用于表示annotation lifetime is runtime ,从代码上看,annotation的定义和interface的定义很相似,确实如此,毕竟编译后会生成Test.class文件。对于@Target和@Retention是Java提供的meta-annotations,所谓meta-annotations就是标记其他注解的注解,下面介绍
注释元素及其数据类型
通过上面@Test注解的定义,我们了解了注解定义的过程。 由于@Test内部没有定义其他元素,所以@Test也被称为标记注解(marker annotation),但自定义注解一般会包含一些元素来表示某些值,以方便处理器使用,如下例所示:
/**
* Created by wuzejian on 2017/5/18.
* 对应数据表注解
*/@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface DBTable {
String name() default "";
}
上面定义了一个名为DBTable的注解,主要用于数据库表和Bean类的映射(后面会有完整的案例分析),和前面的Test注解不同的是我们声明了一个String类型的name元素,其默认值为空字符,但必须注意任何元素对应的声明都应采用method声明方式,可以选择使用default来提供默认值。 @DBTable 用法如下:
@DBTable(name = "MEMBER")
public class Member {
//
}
关于注解支持的元素数据类型,除了上面的String,还支持以下数据类型
如果使用其他数据类型,编译器将抛出编译错误。 请注意,在声明注释元素时可以使用基本类型,但不允许使用包装类型。 同时需要注意的是,注解也可以作为元素的类型,即Nested annotations,下面的代码演示了上述类型的使用:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Reference{
boolean next() default false;
}public @interface AnnotationElementDemo {
enum Status {FIXED,NORMAL};
Status status() default Status.FIXED;
boolean showSupport() default false;
String name()default "";
Class> testCase() default Void.class;
Reference reference() default @Reference(next=true);
long[] value();
}
编译器对默认值的限制
编译器对元素的默认值有点挑剔。 首先,元素不能有不确定的值。 也就是说,元素必须具有默认值,或者在使用注释时为元素提供值。 其次,对于非基本类型的元素java 类属性如何注释,无论是在源码中声明,还是在注解接口中定义默认值,都不能使用null作为取值。 缺少状态,因为在每个注解的声明中,所有的元素都存在并有相应的值。 为了规避这个限制,可以只定义一些特殊的值,比如空字符串或者负数,表示某个元素不存在。
注解不支持继承
注解不支持继承,所以不能使用extends关键字来继承某个@interface,但是注解编译后,编译器会自动继承java.lang.annotation.Annotation接口。 这里我们反编译之前定义的DBTable注解
package com.zejian.annotationdemo;
import java.lang.annotation.Annotation;
public interface DBTable extends Annotation{
public abstract String name();
}
虽然反编译后发现DBTable注解继承了Annotation接口,但是请记住,Java接口虽然可以实现多重继承,但是在定义注解时不能使用extends关键字来继承@interface。
一条捷径
所谓shortcut就是在注解中定义了一个名为value的元素,在使用这个注解的时候java 类属性如何注释,如果这个元素是唯一需要赋值的元素,那么就不需要使用key=的语法此时的value,只是在括号中给value元素想要的值即可。这可以应用于任何合法类型的元素,记住,这限制了元素名称为value,一个简单的案例如下
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)
@interface IntegerVaule{
int value() default 0;
String name() default "";
}public class QuicklyWay {
@IntegerVaule(20)
public int age;
@IntegerVaule(value = 10000,name = "MONEY")
public int money;
}
Java 内置注释和其他元注释
再看看Java自带的注解。 主要有以下三种:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {}
@Documented@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {}
这三个注解都比较简单,只看一个简单的案例:
@Deprecatedclass A{
public void A(){ }
@Deprecated()
public void B(){ }
}
class B extends A{
@Override
public void A() {
super.A();
}
@SuppressWarnings({"uncheck","deprecation"})
public void C(){ }
@SuppressWarnings("uncheck")
public void D(){ }
}
前面我们分析了两个元注解,@Target 和@Retention。 除了这两个元注解,Java还提供了另外两个元注解,@Documented和@Inherited,分别介绍如下:
注解和反射机制
经过前面的反编译,我们知道所有的Java注解都继承了Annotation接口,也就是说Java使用Annotation接口来表示注解元素,它是所有Annotation类型的父接口。 同时,为了在运行时准确获取注解的相关信息,Java在java.lang.reflect反射包下增加了一个AnnotatedElement接口。 接口提供的方法可以使用反射技术读取注解信息。 比如反射包的Constructor类、Field类、Method类、Package类、Class类都实现了AnnotatedElement接口。 其简要含义如下(详见深入理解Java类型信息(Class对象)与反射机制):
Class:类的Class对象定义
Constructor:表示类的构造函数定义
Field:表示类的成员变量定义
Method:表示类的方法定义
package:表示类的包定义
以下是AnnotatedElement中的相关API方法。 以上五个类都实现了以下方法
返回值方法名称说明
getAnnotation(类注解类)
如果该元素存在指定类型的注解,则返回这些注解,否则返回null。
注解[]
获取注解()
返回此元素上存在的所有注释,包括从父类继承的注释
布尔值
isAnnotationPresent(类