Annotation注解-基础

来源:互联网 发布:托福听力评分标准知乎 编辑:程序博客网 时间:2024/06/05 05:45

一、Annotation简介

Java5.0版发布以来,5.0平台提供了一个正式的annotation功能:允许开发者定义、 用自己的annotation类型。此功能由一个定义annotation类型的语法和一个描述annotation声明的语法,读取annotationAPI,一个使用annotation修饰的class文件,一个annotation处理工具(apt)组成。

  annotation并不直接影响代码语义,但是它能够以工作的方式被看作类似程序的工具或者类库,它会反过来对正在运行的程序语义有所影响。annotation可以从源文件、class文件或者以在运行时反射的多种方式被读取。Annotation用到的地方非常普遍。

二、Annotation在应用中的小例子

每个系统都有自己的权限控制,自从Annotation出现以后,用Annotation配合拦截器来控制权限的系统越来越多,请看下面的小例子:

用户有不同的角色,不同角色有不同的权限,不同权限的用户登录进来能看到的数据也不同,能操作的功能不同。

请看代码示例

package com.cienet.authority;public class User {    private Integer userId;        private String name;        private RoleEnum role;        public User(Integer userId, String name, RoleEnum role) {        super();        this.userId = userId;        this.name = name;        this.role = role;    }        public Integer getUserId() {        return userId;    }        public void setUserId(Integer userId) {        this.userId = userId;    }        public String getName() {        return name;    }        public void setName(String name) {        this.name = name;    }        public RoleEnum getRole() {        return role;    }        public void setRole(RoleEnum role) {        this.role = role;    }    }
package com.cienet.authority;public enum RoleEnum {    ProjectManager, Developer;}
package com.cienet.authority;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;@Retention(RetentionPolicy.RUNTIME)public @interface AuthorityAnnotation {    RoleEnum[] value();}
package com.cienet.authority;import java.lang.reflect.Method;import java.util.HashMap;import java.util.Map;public class Action {    private Map<String, User> session = new HashMap<String, User>();        public String login() throws Exception {        System.out.println(session.get("user").getName() + " ---- 執行注册操作:");        String invoke = "login";        // 1. check privilage        checkUser(session.get("user"), invoke);        // 2. do business        System.out.println("恭喜您,注册成功!\n");        return "success";    }        @AuthorityAnnotation( {RoleEnum.ProjectManager, RoleEnum.Developer})    public String queryUser() throws Exception {        System.out.println(session.get("user").getName() + " ----- 執行查询操作:");        String invoke = "queryUser";        // 1. check privilage        checkUser(session.get("user"), invoke);        // 2. do business        System.out.println("查询操作成功!\n");        return "success";    }        @AuthorityAnnotation(RoleEnum.ProjectManager)    public String deleteUser() throws Exception {        System.out.println(session.get("user").getName() + " ----- 執行删除操作:");        String invoke = "deleteUser";        checkUser(session.get("user"), invoke);        System.out.println("删除操作成功!\n");        return "success";    }        /**     * this method replace interceptor of struts2     *      * @param loginUser     * @param invoke     * @return     * @throws Exception     */    private void checkUser(User loginUser, String invoke) throws Exception {        Class action = this.getClass();        Method method = action.getMethod(invoke, new Class[] {});        boolean authFlag = false;        if (method.isAnnotationPresent(AuthorityAnnotation.class)) {            AuthorityAnnotation annotation = method                .getAnnotation(AuthorityAnnotation.class);            RoleEnum[] role = annotation.value();            for (int i = 0; i < role.length; i++) {                if (loginUser.getRole() == role[i]) {                    authFlag = true;                    break;                }            }        } else {            authFlag = true;        }        if (!authFlag) {            throw new RuntimeException("哥们,你权限不足,走人!\n");        }    }        public Map<String, User> getSession() {        return session;    }    }
package com.cienet.authority;import java.util.HashMap;import java.util.Map;public class Client {        public static void main(String[] args) throws Exception {                Action action = new Action();        User projectManager = new User(1, "孙悟空", RoleEnum.ProjectManager);        action.getSession().put("user", projectManager);        User developer = new User(2, "牛魔王", RoleEnum.Developer);        action.getSession().put("user", developer);        User other = new User(3, "西门催雪", null);        action.getSession().put("user", other);                action.login();        action.queryUser();        action.deleteUser();    }}
三、使用JDK5内建Annotation

@Override

  该注解只能用在方法上,表示被注解的方法重写了父类的方法。

@Deprecated

  被注解的元素不建议被使用。

@SuppressWarnings

  该注解告诉编译器压制指定的警告信息。

参见程序实例

package com.cienet.internal;class Person {public String getInfo() {return "this is person";}}public class OverrideTest extends Person {@Overridepublic String getInfo() {return "this is student";}public static void main(String[] args) {Person person = new OverrideTest();System.out.println(person.getInfo());}}
package com.cienet.internal;import java.util.Date;public class DeprecatedTest {@Deprecatedpublic String doSomething() {return "doSomething";}public static void main(String[] args) {DeprecatedTest deprecatedTest = new DeprecatedTest();System.out.println(deprecatedTest.doSomething());}}
package com.cienet.internal;import java.util.Date;import java.util.HashMap;import java.util.Map;public class SuppressWarningsTest {//@SuppressWarnings("unchecked")public static void main(String[] args) {Map map = new HashMap();//Map<String, Date> map = new HashMap<String,Date>();map.put("hello", new Date());System.out.println(map.get("hello"));DeprecatedTest test = new DeprecatedTest();test.doSomething();}}

   java.lang.Override是个Marker annotation

   java.lang.Deprecated也是個Marker annotation

  • ldeprecation 使用了过时的类或方法时的警告
  • lunchecked 执行了未检查的转换时的警告,例如当使用集合时没有用泛型(Generics)来指定集合保存的类型  
  • lfallthroughSwitch程序块直接通往下一种情况而没有Break 时的警告  
  • lpath 在类路径、源文件路径等中有不存在的路径时的警告
  • lserial 当在可序列化的类上缺少serialVersionUID定义时的警告
  • lfinally 任何finally子句不能正常完成时的警告
  • lall 关于以上所有情况的警告

四、自定义Annotation类型

定义Marker Annotation,也就是Annotation名称本身即提供信息

对于程序分析工具来说,主要是检查是否MarkerAnnotation的出现,并作出对应的动作

使用@interface自行定义Annotation型态时,实际上是自动继承了java.lang.annotation.Annotation接口

由编译程序自动为您完成其它产生的细节

在定义Annotation型态时,不能继承其它的Annotation型态或是接口

参见程序实例

package com.cienet.define;public enum EnumTest {Hello,World,Welcome;}
package com.cienet.define;public interface MyAnnotation {    }
package com.cienet.define;//@MyAnnotationpublic class AnnotationUsage {public void method() {System.out.println("usage of annotation");}public static void main(String[] args) {AnnotationUsage annotationUsage = new AnnotationUsage();annotationUsage.method();}}

  Annotation里定义的类型必须为以下的类型及其数组:

    1. 八种原始数据类型

    2. String

    3. Class

    4. Enum

    5.Annotation