Thinking in java - 注解(1)

来源:互联网 发布:手机淘宝修改发货地址 编辑:程序博客网 时间:2024/05/17 02:47
第20章:注解(java.lang.annotation 为Java 编程语言注释设施提供库支持)

综述:
1.注解(也称之为元数据DAD,元数据:描述数据的数据,如定义数据库表的表头数据)
注解为我们在代码中国添加信息提供了一种形式化的方法,使我们在稍后某个时刻非常方便的使用这些数据。

2.注解的产生来源于C#等其他语言给Java造成的语言特性压力而做出的一种回应。

3.注解是JavaSE5的重要语言变化之一。用来完整的描述程序所需要的信息,而这些信息是无法用Java来表达的。因此,注解使得
我们能够有编译器来测试和验证的格式,存储有关程序的额外信息。注解可以用来生成描述符文件,甚至或是新的类定义,并且
有助于减轻编写“样板”代码的负担。注解使得Java代码更加干净易读,编译器类型检查。

4.JavaSE5内置了3中,定义在java.lang中的注解:
4.1 @Override,表示当前中的方法定义将覆盖超类中的方法。
4.2 @Deprecated,如果程序员使用了此注解,那么编译器会发出警告类信息,通常用来标注不建议使用的类,方法等。
4.3 @SuppressWarnings,关闭不当的编译器警告信息。

5.描述符:描述符的英文是descriptor,意思就是描述某个东西的物体。所以套接字描述符,文件描述符,或者中断寄存器描述符
都是一个类似作用的东西,用来描述所引用的对象和对象的一些特性。)

6.每当你创建描述符性质的类或者接口时,一旦其中包含了重复性的工作,那就可以使用注解来简化与自动化该过程。

7.注解的出现,可以替代某些现有的系统。例如:XDolect,它是一个独立的文档化工具,专门用来生成类似注解一样的文件。

package Unit20注解.annotation;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;/** *  *@Test的定义就像一个接口,@interface注解其实就是一个特殊的接口,在编译成class后也会生成class文件。 *定义接口时,需要一些元注解(meta-annotation),如@Target和@Retention * *@Target:用来定义注解用于什么地方,(例如用于一个类,还是一个方法,一个域) *ElementType包括以下几种: *1.CONSTRUCTOR : 构造器的声明。 *2.FIELD:域声明(包括enum实例) *3.LOCAL_VARIABLE:局部变量声明。 *4.METHOD:方法声明 *5.PACKAGE:包声明 *6.PARANETER:参数声明 *7.TYPE:类,接口(包括注解类型)或enum声明 * *@Retention:用来定义注解在哪一个级别可以用(在源代码中(SOURCE),类文件中(CLASS),或者运行时(RUNTIME)) * *@Documented 将此注解包含在Javadoc中。 * *@Inherited 允许类继承父类中的注解。 * *注解的元素就像接口中的方法,唯一的区别就是你可以为其指定默认值。 * *没有元素的注解称为标记注解(Marker annotation) */@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface Test{}
package Unit20注解.annotation;/** 一下的代码,使用@Test对TestExecute()方法进行注解。该注解本 身不做任何事情,但是该注解确保在其构建路径上必须有@Test的注解的定义  */public class Testable {public void execute(){System.out.println("Executing ...");}@Test void testExecute(){execute();};}

package Unit20注解.annotation;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 {//使用:@UseCase(id = 10,description = "这是一个例子")//以下是参数定义/* * 注解的元素只可以使用以下几种类型: * 1.所有基本类型 * 2.String * 3.Class * 4.enum * 5.Annotation * 6.以上类型的数组 *  * 如果你使用过了其他类型,那编译器就会报错。注意,也不允许使用任何其他包装类型,注解作为元素的类型,也就是说 * 注解可以嵌套。 * * */public int id();public String description() default "no description";//和接口唯一的区别,可以有默认值}
package Unit20注解.annotation;import java.util.List;public class PasswordUtils {@UseCase(id = 47 ,description = "Password  must contain at least ine numeric")public boolean validatePassword(String password){//验证密码是否合法return (password.matches("\\w*\\d\\w*"));}@UseCase(id = 48)public String encryptPassword(String password){//密码加密return new StringBuilder(password).reverse().toString();}@UseCase(id = 49 , description = "New password can't equal previously used ones")public boolean checkForNewPassword(//List<String> prevPassword , String password){return !prevPassword.contains(password);}}
package Unit20注解.annotation;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.Collections;import java.util.List;public class UseCaseTracker {//注解处理器public static void trackUserCases(List<Integer> useCases , Class<?> cl){for(Method m : cl.getDeclaredMethods()){//getDeclaredMethods可以反射所有方法,包括私有UseCase uc = m.getAnnotation(UseCase.class);//获取该方法上的UseCase注解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);trackUserCases(useCases, PasswordUtils.class);}}
以下是通过注解,来创建数据库表。

package Unit20注解.annotation.DB;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 DBtable {public String name() default  "";}
package Unit20注解.annotation.DB;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 SQLInteger {//String name() default "";Constraints constraints() default @Constraints;}
package Unit20注解.annotation.DB;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 SQLString {int value() default 0;String name() default "";Constraints constraints() default @Constraints;//注解嵌套}
package Unit20注解.annotation.DB;public @interface Uniqueness {Constraints constraints()default @Constraints(unique = true);}
package Unit20注解.annotation.DB;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 Constraints {//主键的注解boolean primaryKey() default false;boolean allowNull() default true;boolean unique() default false;}
package Unit20注解.annotation.DB;@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 Integer getAge(){return age;}public String toString(){return handle;}}
package Unit20注解.annotation.DB;import java.lang.annotation.Annotation;import java.lang.reflect.Field;import java.util.ArrayList;import java.util.List;public class TableCreator {public static void main(String[] args) throws Exception{//System.out.println(System);args= new String[]{"Unit20注解.annotation.DB.Member"}; //Class.forName(args[0]);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 nameif(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;}if(anns[0] instanceof SQLInteger){SQLInteger sInt = (SQLInteger) anns[0];//Use field name , if naem not specifiedif(sInt.name().length() < 1)columnName = field.getName().toUpperCase();elsecolumnName = 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 specifiedif(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 commaString 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;}}







0 1
原创粉丝点击