• JAVA中的注解小结


    以下内容参考java编程思想-4,jdk版本为jdk5.0,有点老-_-|||

    什么是注解

    JAVA SE5引入,也称元数据,可以直接添加到代码中,用来完整描述程序所需的信息,而这些信息是无法用Java来表达的;

    内置注解

    jdk5.0中内置了三种标准注解和四种元注解;

    三种标准注解,定义在java.lang中:

    @Override  //表示子类方法覆盖父类方法

    @Deprecated //已过时,不建议使用的API

    @SuppressWarnings //取消编译器警告

    四种元注解:

    @Target  //指定该注解可以用在什么地方

    可选参数:

    CONSTRUCTOR:构造器声明

    FIELD:域声明

    LOCAL_VARIABLE:局部变量声明

    METHOD:方法声明

    PACKAGE:包声明

    PARAMETER:参数声明

    TYPE:类、接口声明

    @Retention //表明该注解在哪一级别可用

    可选参数:

    SOURCE:注解将被编译器丢弃;

    CLASS:注解在class文件中可用,但会被VM丢弃;

    RUNTIME:VM在运行期间也保留注解,可以通过反射机制读取注解信息;

    @Documented//表明将此注解包含在Javadoc中

    @Inherited //允许子类继承父类的注解

    基本语法

    自定义注解

    标记注解

    定义一个@Test注解,如下代码所示,可以看到,注解的定义与接口类似,事实上注解与接口一样,也会被编译成class文件;

    package annotations;
    
    import java.lang.annotation.*;
    
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Test {
        
    }

    在注解中,一般都会包含一些元素以表示某些值,当分析处理注解时,程序可以读取这些值;

    上面的@Test注解不包含元素,被称为标记注解;

    包含元素的注解

    下面代码定义了一个包含元素的注解,元素的定义类似于方法,定义中包含了元素的数据类型,如下,id为int类型,description为String类型,且包含一个默认值;

    package annotations;
    
    import java.lang.annotation.*;
    
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface UseCase {
        public int id();
    
        public String description() default "no description";
    }

    注意,注解元素可用的类型如下:

    所有的基本数据类型(int,double...)

    String

    Class

    enum

    Annotation

    数组(以上类型为元素)

    如果使用其它类型编译器会报错,特别提醒,Integer,Double等基本数据类型的包装类型也是不允许的;

    另外,元素是不能有不确定的值,要么有默认值,要么提供元素的值,且不能为null;

    注解使用

    上面定义的@UseCase注解的使用如下所示,很简单,在方法前面写上注解,并指定元素的值,如果未指定的话将使用默认值;

    package annotations;
    
    import java.util.*;
    
    public class PasswordUtils {
        @UseCase(id = 47, description = "Passwords 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的反射机制,可以查找注解标记,下面是一个简单的注解处理器,用于解析上面提到的@UserCase注解,主要使用到了Class类的getDeclaredMethods()方法和Method类的getAnnotation(Class<T> annotationClass)方法;getDeclaredMethods返回类中声明的所有方法,getAnnotation返回指定的注解;

    package annotations;
    
    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);
        }
    }

    注解常见使用场景

    描述数据库表结构与类关系映射(hibernate...)

    单元测试(junit...)

    一些配置等(spring...)

    ...

  • 相关阅读:
    C# NameValueCollection
    visual studio使用技巧创建自己代码片段
    C#在DataTable中使用LINQ
    [转]C# 中的.pdb/ .vshost.exe/ .vshost.exe.manifest文件讨论
    C#自定义控件在添加引用后不显示在工具箱的解决方法
    Java 工程师
    redis-CRC16
    sql server-当天日期减去一天 应该如何写
    清除访问Windows共享时缓存的凭据
    cmd下查看当前登陆用户
  • 原文地址:https://www.cnblogs.com/chenpi/p/5327151.html
Copyright © 2020-2023  润新知