java注解
java注解何为注解内置注解注解的定义及使用注解处理器注解元素何为注解也称为元数据,为在代码中添加信息提供一种形式化的方法,使我们可以在稍后某个时刻非常方便地使用这些数据。将元数据和源代码二建结合起来,而不是保存在外部文档中。能够提供更加干净易读的代码以及编译期类型检查。内置注解@Override:表示当前方法定义将覆盖超类中的方法@Deprecated:使用此注解,编译器会发出警告信...
何为注解
也称为元数据,为在代码中添加信息提供一种形式化的方法,使我们可以在稍后某个时刻非常方便地使用这些数据。将元数据和源代码二建结合起来,而不是保存在外部文档中。能够提供更加干净易读的代码以及编译期类型检查。
内置注解
- @Override:表示当前方法定义将覆盖超类中的方法
- @Deprecated:使用此注解,编译器会发出警告信息
- @SuppressWarnings:关闭不当的编译器警告信息
- @Target:定义注解应用在什么地方,一个方法或者一个域。下面列出可能的ElementType参数:
- CONSTRUCTOR: 构造器声明
- FIELD: 域声明
- LOCAL_VARIABLE: 局部变量声明
- METHOD: 方法声明
- PACKAGE :包声明
- PARAMETER: 参数声明
- TYPE: 类、接口或enum声明
- @Retention:定义注解在哪个级别可用,源码还是类文件还是运行时。可选RetentionPolicy参数为:
- SOURCE: 注释被编译器丢弃
- CLASS: 注释在class中可用,会被VM丢弃
- RUNTIME:VM在运行期也保留注解,可以通过反射机制读取注解的信息。
- Documented:将此注解包含在javadoc中
- Inherited:允许子类继承父类中的注解
注解的定义及使用
注解的定义如下图所示,看起来像接口的方法,唯一的区别是可以指定默认值。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface useCase {
public int id();
public String description() default "no description";
}
注解使用时为名-值对的形式,例如下图中调用useCase的注解,我们可以很方便地看出下面每一个方法对应的功能描述,从而避免了另外书写代码文档。
public class PasswordUtils {
@useCase(id=47,description = "password must contain at least one 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 passwords can't equal previously used ones")
public boolean checkForNewPassword(List<String> prevPasswords, String password){
return !prevPasswords.contains(password);
}
}
注解处理器
如果单单是上文中展示的注解的话,我们通过普通的注释就可以实现这种解释代码的功能。所以关键的优点就在于,可以结合反射机制使用注解处理器帮助程序员解析带有注解的java源代码。
什么意思呢,通俗一点讲就是。如果一个项目有1,2,3,4,5共五个功能点,而程序员实现了1,2,3共3个功能点,并在其上面添加注解。如果使用普通注释的话,主管在检查代码时,需要查阅源代码,一个一个看功能点是否实现,非常费时。那如果我们使用注解,我们可以结合反射机制,通过代码直接快速检查功能点是否存在。
如下面的代码所示,假设我们在最初的设计文档中设计了47,48,49,50一共5个函数功能点,那么通过获取所有的annotation列表,直接排查就可以得到我们还有哪个功能点暂未实现。
代码中,第3-9行将找到的useCase从列表中依次去除,最后10-12行将列表中还存在的useCase输出,表明是没有找到的case。
cl.getDeclaredMethods()获得类中声明的所有方法,m.getAnnotation获取方法中对应的注解。
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("Waning: 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);
}
}
注解元素
注解内的元素包括:
- 所有基本类型:int,float,boolean等等
- String
- Class
- enum
- Annotation
- 以上类型的数组
不存在于上述类型中的类型出现时,编译就会报错。注解也可以嵌套。
默认值
注解的默认值不能有不确定的值,要么是默认值要么是注解时提供的值。不能以null作为其值,如果想要表示某个元素不存在,可以自定义一些特殊的值。
基于注解的单元测试
单元测试是注解的一个重要功能,最常用的为@Test注解。@Test标记测试方法,不带参数,返回值为boolean类型来表示测试成功与否。
优点
- 无需创建单独的类来保存单元测试,可以直接在需要验证的类中编写测试
- 不仅能测试public方法,还能测试private方法
一个简单的单元测试如下:
import net.mindview.atunit.Test;
public int methodOne(){
return 1;
}
@Test
boolean testOne(){
return methodOne()==1;
}
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)