做亚马逊学英语有什么网站吗,qq浏览网页版进入,开一个公司需要多少钱,wordpress数据库替换页面【1】注解介绍
1#xff09;注解是什么#xff1f;
注解#xff08;元数据#xff09;是 java提供的一种对程序元素#xff08;如类#xff0c;方法#xff0c;变量#xff09;打标记的方法#xff1b;以便运行程序或编译器可以识别这些元素进行特殊处理#xff1b…【1】注解介绍
1注解是什么
注解元数据是 java提供的一种对程序元素如类方法变量打标记的方法以便运行程序或编译器可以识别这些元素进行特殊处理最典型的用法是框架代码启动时扫描某注解修饰的所有类并将其加载到内存以构建系统底层框架更直白点类方法变量被注解修饰后更容易被识别以便加载
补充 显然开发或学习底层框架的同学肯定必不可少要学习注解所以注解是相当重要的 【2】java内置的三种注解
1Override 表示被标记的方法将覆盖超类中的方法
2Deprecated表示被标记的元素类或方法被废弃了 如果代码使用该元素则编译器会发出警告
3SuppressWarnings关闭不当的编译器警告信息 【3】4种标准元注解
1元注解元注解的作用是负责修饰其他注解参与其他注解的定义或声明。 java5.0 定义了4个标准的元注解类型 干货——你也可以认为被注解修饰就是被注解打标记
1.1Target元注解用于指定被修饰注解可以应用到哪些元素上
如 注解可以被应用到 packagestype类接口枚举Annotation类类型成员方法构造方法成员变量枚举值方法参数和本地变量等
注解定义例子1
Target(ElementType.METHOD) // 表示用于修饰标记方法
Retention(RetentionPolicy.RUNTIME) // 表示运行时可用
public interface Test {} ///:~
注解应用例子1
public class Testable {public void execute() {System.out.println(Executing..);}Test // Test 注解用于修饰方法void testExecute() {execute();}
} 1.2Retention元注解用于指定被修饰注解的生命周期
SOURCE源文件有效被编译器丢弃CLASSclass文件有效被JVM丢弃RUNTIME 运行时有效常用VM将在运行期也保留注解通过反射机制读取注解
1.3Document 用于指定被修饰的注解可以被 javadoc 工具文档化
1.4Inherited 用于指定被修饰的注解是可以被继承的 2上面例子中修饰的注解 Test是没有任何成员方法的。下面我们来看有成员方法的注解UseCase·
// 下面定义了一个注解UseCase该注解作用于方法该注解在运行时发挥作用
// 该注解UseCase应用于什么地方
Target(ElementType.METHOD)
// 该注解UseCase的应用级别源代码-SOURCE, 类文件中-CLASS 运行时-RUNTIME
Retention(RetentionPolicy.RUNTIME)
public interface UseCase {public int id();public String description() default no description; // no description 是默认值
}
/*
D:\workbench_idea\study4vw\thinkinjava\srcjavap chapter20.UseCase
Compiled from UseCase.java
public interface chapter20.UseCase extends java.lang.annotation.Annotation {public abstract int id();public abstract java.lang.String description();
}
*/
反编译javap后的源码可以看到注解就是一个接口该接口的父类是 Annotation 注解接口类型当然了接口中的方法都是抽象方法。
2.1使用 UseCase注解
// 荔枝-有3个方法被注解UseCase修饰为用例
public class PasswordUtils {// 将 UseCase 注解作用于方法UseCase(id 47, description validatePassword method)public boolean validatePassword(String password) {return (password.matches(\\w*\\d\\w*));}UseCase(id 48) // description 默认为 no descriptionpublic String encryptPassword(String password) {return new StringBuilder(password).reverse().toString();}UseCase(id 49, description checkForNewPassword method)public boolean checkForNewPassword(ListString prevPasswords, String password) {return !prevPasswords.contains(password);}
}
/* 反编译简要结果如下
D:\workbench_idea\study4vw\thinkinjava\srcjavap chapter20.PasswordUtils
Compiled from PasswordUtils.java
public class chapter20.PasswordUtils {public chapter20.PasswordUtils();public boolean validatePassword(java.lang.String);public java.lang.String encryptPassword(java.lang.String);public boolean checkForNewPassword(java.util.Listjava.lang.String, java.lang.String);
}
*/
解析注解
/*** 注解解析测试用例*/
public class AnnotationDiyTest {public final static T void f1(ClassT c1) {for (Method method : c1.getMethods()) { // 获取类定义方法UseCase useCase method.getAnnotation(UseCase.class); // 获取方法上某个注解if (useCase ! null) {System.out.println(useCase.id() - useCase.description()); // 解析注解}}}public static void main(String[] args) {f1(PasswordUtils.class);}
}
/*
47-validatePassword method
48-no description
49-checkForNewPassword method
*/ 【4】自定义注解
UseCase注解有两个方法方法返回类型有 intString此外还有其他返回类型包括
所有基本类型
String
Class
enum
Annotation// 注解的成员方法的返回值类型还可以是注解类型
以及以上类型的数组
下面定义一个嵌套注解即注解的方法返回类型是注解类型
Target(ElementType.FIELD)
Retention(RetentionPolicy.RUNTIME)
public interface SQLString {int value() default 0;String name() default ;Constraints constraints() default Constraints();// 嵌套注解
} // /:~
// 定义注解并定义嵌套注解
Target(ElementType.FIELD)
Retention(RetentionPolicy.RUNTIME)
public interface SQLInteger {int value() default 0;String name() default ;// 嵌套注解因为 Constraints 也是注解类型Constraints constraints() default Constraints;
} // /:~
// 荔枝-定义注解并定义嵌套注解
Target(ElementType.FIELD)
Retention(RetentionPolicy.RUNTIME)
public interface SQLDouble {double value() default 0f;// 嵌套注解因为 Constraints 也是注解类型Constraints constraints() default Constraints;
}
// 荔枝-定义注解用于生成一个数据库表
Target(ElementType.TYPE) // 注解作用于哪里注解的作用对象
// Applies to classes only
Retention(RetentionPolicy.RUNTIME) // 注解的作用时间这里是运行时
public interface DBTable {// DBTable 有一个name元素// 这个注解通过使用 value元素 为处理器创建数据库表提供的表名public String value() default ;
} // /:~
// 荔枝-为修饰 javabean域 准备的注解
Target(ElementType.FIELD)
Retention(RetentionPolicy.RUNTIME)
public interface Constraints {boolean primaryKey() default false; // 主键boolean allowNull() default true; // 允许为空boolean unique() default false; // 唯一键
} // /:~
使用注解创建数据库表对应的javabean
// DBTable 注解作用于类
DBTable(MEMBER)
public class Member {SQLString(30) String firstName;SQLString(value50, name lastName) String lastName;SQLInteger(name age, constraints Constraints(primaryKeytrue, allowNullfalse, uniquetrue)) Integer age;SQLString(value 30 , name handle, 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;}
} // /:~
使用注解的快捷方式如果注解中定义了名为value元素value方法且在使用注解时该元素是唯一一个需要复制的元素那么只需要给出value元素的值即可无需写键值对形式 DBTable(MEMBER)-快捷方式 DBTable(valueMEMBER)-普通方式 【5】使用apt处理注解
1问题 上述代码中都需要为注解编写处理器以解析注解 很麻烦
使用 apt类库方法可以生成注解处理器apt 是使用源代码生成注解的无法通过class文件获取类的属性但 mirror api 可以允许程序员在源代码中查看类属性如方法属性
2注解
// 抽取注解
Target(ElementType.TYPE) //
Retention(RetentionPolicy.SOURCE) // 在源文件起作用
public interface ExtractInterface {public String value();
} // /:~ 【6】小结
java se5仅提供了很少的注解大多数情况下需要自定义注解及注解处理器特别是开发底层框架的时候需要自定义注解
javassist 能够用来操作字节码mirror api 能够用来找出java源代码中的元素 apt-mirror-api maven repo