Java注解--annotation
2015-02-11 08:54
309 查看
注解称为元数据,为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后摸个时刻非常方便的使用这些数据。——Java编程思想第四版.
注解是众多引入到Java SE5中得语言变化之一。他们可以提供完整的用来描述程序所需的信息,而这些信息是无法使用Java来表达的,注解使得我们可以由编译器来完成测试和验证的格式,存储有关程序的额外信息,属于编译期的类型检查。
定义注解:其中@Target用来定义你的注解将用在山么地方(例如是一个方法还是一个域)。@Retention用来定义该注解在哪一个级别可以使用(源代码中SOURCE,类文件中CLASS或者运行时RUNTIME)。
使用注解:
元注解:
@Target(ElementType.[type])
[type]={METHOD, FIELD, TYPE(类、接口、枚举声明), CONSTRUCTOR, LOCAL_VARIABLE, PARAMETER}
@Retention(RetentionPolicy.[policy])
[policy]={SOURCE, CLASS, RUNTIME(反射机制可读取)}
@Documented 表示将此注解包含到Javadoc中
@Inherited 表示允许子类继承父类的注解
标准注解:
注解@Override的代码非常简单,可用于注解类的方法,并在Source级别可用。 并且在Java当中,@Override是可选的
@Desprecated如果程序员使用了注解为他的元素,那么编译器发出警告信息。
@SuppressWarnings 关闭不当的编译器警告信息
[b]注解处理器:有了注解是不够的,还需要注解处理器进行注解的处理,否则注解还没有注释好用
[/b]
这个程序只用了两个反射的接口:getDeclaredMethods()和getAnnotation(),它们都属于AnnotationElement接口(Class、Method和Field
等类都实现了该接口)getAnnotation()返回指定类型注解对象,然后通过调用id()来返回UseCase对象中提取元素的值。
生成外部文件:
注解是众多引入到Java SE5中得语言变化之一。他们可以提供完整的用来描述程序所需的信息,而这些信息是无法使用Java来表达的,注解使得我们可以由编译器来完成测试和验证的格式,存储有关程序的额外信息,属于编译期的类型检查。
定义注解:其中@Target用来定义你的注解将用在山么地方(例如是一个方法还是一个域)。@Retention用来定义该注解在哪一个级别可以使用(源代码中SOURCE,类文件中CLASS或者运行时RUNTIME)。
import java.lang.annitation.*; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface UseCase{ public int id(); public String description() default "no description"; }
使用注解:
import java.util.*; public class PasswordUtils{ @UseCase(id = 47, description = "") public boolean validatePassword(String password){ return password.matches("\w\w"); } @UseCase(id = 48) public String encryptPassword(String password){ return new StringBuilder(password.reverse().toString()); } }
元注解:
@Target(ElementType.[type])
[type]={METHOD, FIELD, TYPE(类、接口、枚举声明), CONSTRUCTOR, LOCAL_VARIABLE, PARAMETER}
@Retention(RetentionPolicy.[policy])
[policy]={SOURCE, CLASS, RUNTIME(反射机制可读取)}
@Documented 表示将此注解包含到Javadoc中
@Inherited 表示允许子类继承父类的注解
标准注解:
注解@Override的代码非常简单,可用于注解类的方法,并在Source级别可用。 并且在Java当中,@Override是可选的
@Desprecated如果程序员使用了注解为他的元素,那么编译器发出警告信息。
@SuppressWarnings 关闭不当的编译器警告信息
[b]注解处理器:有了注解是不够的,还需要注解处理器进行注解的处理,否则注解还没有注释好用
[/b]
import java.lang.reflect.*; import java.util.*; public class UseCaseTracker { public static void trackUseCases(List<Integer> useCases, Class<?> cl) { for(Method m : cl.getDeclaredMethods()) { UseCase uc = m.getAnnotation(UseCase.class); if(uc != null) { System.out.println("Found Use Case:" + uc.id() +" " + uc.description()); useCases.remove(new Integer(uc.id())); } } for(int i : useCases) { System.out.println("Warning: Missing use case-" + i); } } public static void main(String[] args) { List<Integer> useCases = new ArrayList<Integer>(); Collections.addAll(useCases, 47, 48, 49, 50); trackUseCases(useCases, PasswordUtils.class); } } /* Output: Found Use Case:47 Passwords must contain at least one numeric Found Use Case:48 no description Found Use Case:49 New passwords can't equal previously used ones Warning: Missing use case-50 */
这个程序只用了两个反射的接口:getDeclaredMethods()和getAnnotation(),它们都属于AnnotationElement接口(Class、Method和Field
等类都实现了该接口)getAnnotation()返回指定类型注解对象,然后通过调用id()来返回UseCase对象中提取元素的值。
生成外部文件:
import java.lang.annotation.*; @Target(ElementType.TYPE) // Applies to classes only @Retention(RetentionPolicy.RUNTIME) public @interface DBTable { public String name() default ""; }
@DBTable(name = "MEMBER") public class Member { @SQLString(30) String firstName; @SQLString(50) String lastName; @SQLInteger Integer age; @SQLString(value = 30, constraints = @Constraints(primaryKey = true)) String handle; static int memberCount; public String getHandle() { return handle; } public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public String toString() { return handle; } public Integer getAge() { return age; } }
import java.lang.annotation.*; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Constraints { boolean primaryKey() default false; boolean allowNull() default true; boolean unique() default false; }
import java.lang.annotation.*; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface SQLInteger { String name() default ""; Constraints constraints() default @Constraints; }
import java.lang.annotation.*; @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface SQLString { int value() default 0; String name() default ""; Constraints constraints() default @Constraints; }
public @interface Uniqueness { Constraints constraints() default @Constraints(unique=true); }
import java.lang.annotation.*; import java.lang.reflect.*; import java.util.*; public class TableCreator { public static void main(String[] args) throws Exception { if(args.length < 1) { System.out.println("arguments: annotated classes"); System.exit(0); } for(String className : args) { Class<?> cl = Class.forName(className); DBTable dbTable = cl.getAnnotation(DBTable.class); if(dbTable == null) { System.out.println( "No DBTable annotations in class " + className); continue; } String tableName = dbTable.name(); // If the name is empty, use the Class name: if(tableName.length() < 1) tableName = cl.getName().toUpperCase(); List<String> columnDefs = new ArrayList<String>(); for(Field field : cl.getDeclaredFields()) { String columnName = null; Annotation[] anns = field.getDeclaredAnnotations(); if(anns.length < 1) continue; // Not a db table column if(anns[0] instanceof SQLInteger) { SQLInteger sInt = (SQLInteger) anns[0]; // Use field name if name not specified if(sInt.name().length() < 1) columnName = field.getName().toUpperCase(); else columnName = sInt.name(); columnDefs.add(columnName + " INT" + getConstraints(sInt.constraints())); } if(anns[0] instanceof SQLString) { SQLString sString = (SQLString) anns[0]; // Use field name if name not specified. if(sString.name().length() < 1) columnName = field.getName().toUpperCase(); else columnName = sString.name(); columnDefs.add(columnName + " VARCHAR(" + sString.value() + ")" + getConstraints(sString.constraints())); } StringBuilder createCommand = new StringBuilder( "CREATE TABLE " + tableName + "("); for(String columnDef : columnDefs) createCommand.append("\n " + columnDef + ","); // Remove trailing comma String tableCreate = createCommand.substring( 0, createCommand.length() - 1) + ");"; System.out.println("Table Creation SQL for " + className + " is :\n" + tableCreate); } } } private static String getConstraints(Constraints con) { String constraints = ""; if(!con.allowNull()) constraints += " NOT NULL"; if(con.primaryKey()) constraints += " PRIMARY KEY"; if(con.unique()) constraints += " UNIQUE"; return constraints; } } /* Output: Table Creation SQL for annotations.database.Member is : CREATE TABLE MEMBER( FIRSTNAME VARCHAR(30)); Table Creation SQL for annotations.database.Member is : CREATE TABLE MEMBER( FIRSTNAME VARCHAR(30), LASTNAME VARCHAR(50)); Table Creation SQL for annotations.database.Member is : CREATE TABLE MEMBER( FIRSTNAME VARCHAR(30), LASTNAME VARCHAR(50), AGE INT); Table Creation SQL for annotations.database.Member is : CREATE TABLE MEMBER( FIRSTNAME VARCHAR(30), LASTNAME VARCHAR(50), AGE INT, HANDLE VARCHAR(30) PRIMARY KEY); */
相关文章推荐
- Java基础-学习使用Annotation注解对象
- Java基础-学习使用Annotation注解对象
- 对Java注解(Annotation)初步的认识
- Java高新技术之Annotation(注解)
- Java自定义注解Annotation的使用
- JAVA Annotation 注解
- java 注解(Annotation)
- 理解Java基础之注解Annotation
- java学习笔记(annotation 注解_1)
- Java注解应用实例 - Annotation, 自定义注解, 注解类规则
- 自己写的基于java Annotation(注解)的数据校验框架
- Java 5.0 新特性总结 二 annotation 注解
- Java Annotation(注解)
- 对Java注解(Annotation)初步的认识
- java1.5新特性-----》注解----Annotation
- Java基础-学习使用Annotation注解对象
- java annotation(注解)--入门
- java Annotation注解的运用
- JAVA1.5新特性----注解Annotation
- java 之 注解Annotation学习示例