注解(元数据)在我们代码中提供形式化的方法,注解是跟你的源代码结合在一起使用的.注解之所以产生,是为了减少样板试代码的开发,提供开发效率.
注解相对比较简单的,除了使用@符号,基本与java固有的的语法是一致的。
java.lang.的有三种标准的注解:
@Override:
@Deprecated:
@SuppressWarnings:
四种元注解:负责创建其他注解
@Target
@Retention
@Document
@Inherited
定义注解
package com.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
public abstract int id() default 0;
public abstract String value() default "";
}
@Target(ElementType.METHOD): 你的注解应用于什么地方,ElementType提供了8中方式
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,/** Method declaration */
METHOD,/** Parameter declaration */
PARAMETER,/** Constructor declaration */
CONSTRUCTOR,/** Local variable declaration */
LOCAL_VARIABLE,/** Annotation type declaration */
ANNOTATION_TYPE,/** Package declaration */
PACKAGE
@Retention(RetentionPolicy.RUNTIME):你的注解在哪个级别二用,在源码(Source),类文件中(Class)或者是在运行时(RUNTIME)
应用注解
package com.anno;
public class Utils {
@UseCase(id = 0, value = "1")
public boolean validate() {
return false;
}
@UseCase(id = 1, value = "2")
public boolean validate1() {
return false;
}
@UseCase(id = 2, value = "3")
public boolean validate2() {
return false;
}
}
如果没有注解读取工具,那注解也不会比注释更有用.使用注解过程中,最重要的编写注解处理器,Java API 反射机制扩展了注解,同时提供了外部工具apt解析带有注解的源码.
下面是非常简单的注解解析器帮助我们解析Utils
package com.anno;
import java.lang.reflect.Method;
public class AnnoUtils {
public static void parse(Class<?> cls) {
Method[] methods = cls.getDeclaredMethods();
for (Method e : methods) {
UseCase useCase = e.getAnnotation(UseCase.class);
System.out.println("Method Name:" + e.getName() + " Annocation Id:" + useCase.id() + " Anocation value" + useCase.value());
}
}
public static void main(String[] args) {
AnnoUtils.parse(Utils.class);
}
}
Method Name:validate Annocation Id:0 Anocation value1
Method Name:validate1 Annocation Id:1 Anocation value2
Method Name:validate2 Annocation Id:2 Anocation value3
-
所有的基础数据类型(int\float\double\boolean\char\long\short\byte)
-
String
-
Class
-
Annocation
-
enum
-
以上类型的数组
编译器对元素的过分的限制,首先元素不能有不确定的值,也就是说元素不然又默认值,不然使用注解的时候必须指定.并且非基本数据类型不能为NULL,为了绕开这个约束,我们定义一些特殊的值,比如负数或者空字符串,此意表示元素不存在
public @interface UseCase {
public abstract int id() default -1;
public abstract String value() default "";
}
高级应用
假如你希望提供一些基础的对象/关系数据库映射,
- 定义映射表的注解
package com.anno;
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 Table {
public abstract String value();
}
- 定义公共属性
package com.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Constraines {
public abstract boolean primarkKey() default false;
public abstract boolean allowNull() default true;
public abstract boolean unique() default false;
}
package com.anno;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public interface R {
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface SQLString {
public abstract String column() default "";
public abstract String value() default "";
public abstract Constraines constraines() default @Constraines;
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface SQLInteger {
public abstract String column() default "";
public abstract int value() default -1;
public abstract Constraines constraines() default @Constraines;
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface SQLDate {
public abstract String column() default "";
public abstract long value() default -1;
public abstract Constraines constraines() default @Constraines;
}
}
下面定义个简单的JavaBean:
package com.anno;
import com.anno.R.SQLInteger;
import com.anno.R.SQLString;
@Table(value = "TBL_CIF")
public class Memery {
@SQLInteger(constraines = @Constraines(allowNull = false, primarkKey = true, unique = true))
private int id;
@SQLString(constraines = @Constraines(allowNull = false, primarkKey = true, unique = true))
private String fristName;
@SQLString(constraines = @Constraines(allowNull = false, primarkKey = true, unique = true))
private String lastName;
}
接口R中我对注解统一管理,在对不同类型实施注解时,出现了重复的代码,Constraines constraines() default @Constraines;是不是可以通过集成@interface呢?这样可以减少大量的代码,很遗憾注解不支持Extend.以上代码也是最优的了