zoukankan      html  css  js  c++  java
  • Java深入

    我们在使用Spring框架的时候,会常常使用类似:@Autowired 这种注解。

    我们也能够自定义一些注解。Java的注解主要在包:java.lang.annotation中实现。

    1. 元注解

    什么是元注解?你能够这样理解。元注解是自己定义注解的注解。

    元注解主要包括4个。

    他们主要在java.lang.annotation中能够找到。

    我们自己要创建注解的时候必需要用到这些元注解。

    所以必须彻底理解这四个元注解的含义。

    1. @Documented

    2. @Inherited

    3. @Retention

    4. @Target

    比如:

    package com.test.www;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    
    
    /**
     * 定义一个username的自己定义注解
     * @author zhuli
     * @date 2014-7-5
     */
    @Documented
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ ElementType.TYPE, ElementType.METHOD})
    @Inherited
    public @interface UserNameAnnotations {
    
        public String value() default "";
    
    }

    1. @Documented

    @Documented用于描写叙述其他类型的annotation应该被作为被标注的程序成员的公共API,因此能够被比如javadoc此类的工具文档化。

    Documented是一个标记注解,没有成员。

    2. @Inherited

    @Inherited 元注解是一个标记注解。@Inherited阐述了某个被标注的类型是被继承的。

    假设一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

    3. @Target

    @Target说明了Annotation所修饰的对象范围:Annotation可被用于 packages、types(类、接口、枚举、Annotation类型)、类型成员(方法、构造方法、成员变量、枚举值)、方法參数和本地变量(如循环变量、catch參数)。

    ElementType.CONSTRUCTOR  作用于构造器
    ElementType.FIELD  作用于域/属性
    ElementType.LOCAL_VARIABLE  用于描写叙述局部变量
    ElementType.METHOD  作用于方法
    ElementType.PACKAGE   用于描写叙述包
    ElementType.PARAMETER   用于描写叙述參数
    ElementType.TYPE   用于描写叙述类、接口(包含注解类型) 或enum声明,最经常使用

    单个修饰对象的范围:

    @Target(ElementType.TYPE)

    多个:

    @Target({ ElementType.TYPE, ElementType.METHOD})

    4. Retention

    定义了该Annotation被保留的时间长短:某些Annotation仅出如今源码中,而被编译器丢弃。而还有一些却被编译在class文件里;编译在class文件里的Annotation可能会被虚拟机忽略。而还有一些在class被装载时将被读取(请注意并不影响class的运行,由于Annotation与class在使用上是被分离的)。使用这个meta-Annotation能够对 Annotation的“生命周期”限制。

    RetentionPolicy.RUNTIME 注解会在class字节码文件里存在,在执行时能够通过反射获取到

    RetentionPolicy.CLASS 默认的保留策略。注解会在class字节码文件里存在,但执行时无法获得

    RetentionPolicy.SOURCE 注解仅存在于源代码中,在class字节码文件里不包括


    2. 创建一个自己定义注解 - 作用于类

    1. 创建一个注解类

    package com.test.www;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Inherited;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    
    
    /**
     * 定义一个username的自己定义注解
     * @author zhuli
     * @date 2014-7-5
     */
    @Documented //文档
    @Retention(RetentionPolicy.RUNTIME) //在执行时能够获取
    @Target({ ElementType.TYPE, ElementType.METHOD}) //作用到类,方法,接口上等
    @Inherited //子类会继承
    public @interface UserNameAnnotations {
        
        public String value() default ""; //使用的时候 @UserNameAnnotations(value="xxx")
    
    }

    2. 创建一个Test类

    package com.test.www;
    
    
    /**
     * 一个注解的測试类
     * @author zhuli
     * @date 2014-7-5
     */
    //注入注解作用于类上面
    //能够通过反射 获取类的信息之后 获取得到这个注解的值
    @UserNameAnnotations(value = "initphp") 
    public class Test {
    
        private String userName;
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
    }
    


    3. 測试类

    package com.test.www;
    
    
    public class mainTest {
    
        public static void main(String[] args) {
            Class<Test> testClass = Test.class;
            //由于注解是作用于类上面的,所以能够通过isAnnotationPresent来推断是否是一个
            //有UserNameAnnotations注解的类
            if (testClass.isAnnotationPresent(UserNameAnnotations.class)) {
                System.out.println("this is a Annotations class");
                //通过getAnnotation能够获取注解对象
                UserNameAnnotations userNameAnnotations = (UserNameAnnotations) testClass.
    getAnnotation(UserNameAnnotations.class);
                if (userNameAnnotations != null) {
                    System.out.println("value:" + userNameAnnotations.value());
                } else {
                    System.out.println("null");
                }
            } else {
                System.out.println("this is not Annotations class");
            }
    
        }
    }
    

    4. 输出:

    this is a Annotations class
    value:initphp


    3. 创建一个自己定义注解 - 作用于方法

    1. 自己定义注解类

    package com.test.www;
    
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * 定义一个作用到方法的注解
     * @author zhuli.zhul
     * @date 2014-7-5
     */
    @Documented//文档
    @Retention(RetentionPolicy.RUNTIME)//在执行时能够获取
    @Target({ ElementType.TYPE, ElementType.METHOD })//作用到类,方法,接口上等
    public @interface MethodType {
    
        //枚举类型
        public enum MethodTypeEnum {
            TYPE1, TYPE2
        }
    
        //实际的值
        public MethodTypeEnum methodType() default MethodTypeEnum.TYPE1;
    }
    

    2. 创建一个使用注解的类

    package com.test.www;
    
    import com.test.www.MethodType.MethodTypeEnum;
    
    
    /**
     * 一个注解的測试类
     * @author zhuli
     * @date 2014-7-5
     */
    //注入注解作用于类上面
    //能够通过反射 获取类的信息之后 获取得到这个注解的值
    @UserNameAnnotations(value = "initphp") 
    public class Test {
    
        private String userName;
    
        //注解到
        @MethodType(methodType=MethodTypeEnum.TYPE2)
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
    }
    

    3. 创建main入口

    package com.test.www;
    
    
    import java.lang.reflect.Method;
    
    import com.test.www.MethodType.MethodTypeEnum;
    
    public class mainTest {
    
        public static void main(String[] args) {
            Class<Test> testClass = Test.class;
            try {
                //由于是注解到method上的。所以首先要获取这种方法
                Method method = testClass.getDeclaredMethod("getUserName");
                
                //推断这种方法上是否有这个注解
                if (method.isAnnotationPresent(MethodType.class)) {
                    System.out.println("this is a method Annotation");
                    
                    //假设有这个注解,则获取注解类
                    MethodType methodType = (MethodType) method.getAnnotation(MethodType.class);
                    if (methodType != null) {
                        if (MethodTypeEnum.TYPE1.equals(methodType.methodType())) {
                            System.out.println("this is TYPE1");
                        } else {
                            System.out.println("this is TYPE2");
                        }
                    }
                } else {
                    System.out.println("this is not  a method Annotation");
                }
    
            } catch (Exception e) {
            }
    
        }
    }
    

    4. 输出:

    this is a method Annotation
    this is TYPE2


    4. 创建一个自己定义注解 - 作用于域

    1. 创建一个自己定义注解

    package com.test.www;
    
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    /**
     * 定义一个作用到域上的自己定义注解
     * @author zhuli
     * @date 2014-7-5
     */
    @Documented//文档
    @Retention(RetentionPolicy.RUNTIME)//在执行时能够获取
    @Target({ ElementType.FIELD })//作用到类的域上面
    public @interface FieldAnnotations {
    
        public String value() default ""; //使用的时候 @FieldAnnotations(value="xxx")
    
    }
    

    2. 创建一个使用注解的类

    package com.test.www;
    
    import com.test.www.MethodType.MethodTypeEnum;
    
    
    /**
     * 一个注解的測试类
     * @author zhuli
     * @date 2014-7-5
     */
    //注入注解作用于类上面
    //能够通过反射 获取类的信息之后 获取得到这个注解的值
    @UserNameAnnotations(value = "initphp") 
    public class Test {
    
        @FieldAnnotations(value="zhuli")
        private String userName;
    
        //注解到
        @MethodType(methodType=MethodTypeEnum.TYPE2)
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
    }
    

    3. 创建main入口类

    package com.test.www;
    
    
    import java.lang.reflect.Field;
    
    public class mainTest {
    
        public static void main(String[] args) {
            Test test = new Test();
            Class<Test> testClass = Test.class;
            try {
                //由于是注解到Field上的。所以首先要获取这个字段
                Field field = testClass.getDeclaredField("userName");
    
                //推断这个Field上是否有这个注解
                if (field.isAnnotationPresent(FieldAnnotations.class)) {
                    System.out.println("this is a field Annotation");
    
                    //假设有这个注解,则获取注解类
                    FieldAnnotations fieldAnnotations = (FieldAnnotations) field.getAnnotation(FieldAnnotations.class);
                    if (fieldAnnotations != null) {
                        //通过反射给私有变量赋值
                        field.setAccessible(true);
                        field.set(test, fieldAnnotations.value());
                        System.out.println("value:" + test.getUserName());
                    }
                } else {
                    System.out.println("this is not  a field Annotation");
                }
    
            } catch (Exception e) {
            }
    
        }
    }
    

    4. 输出:

    this is a field Annotation
    value:zhuli



  • 相关阅读:
    wget(转)
    852. Peak Index in a Mountain Array
    617. Merge Two Binary Trees
    814. Binary Tree Pruning
    657. Judge Route Circle
    861. Score After Flipping Matrix
    832. Flipping an Image
    461. Hamming Distance
    654. Maximum Binary Tree
    804. Unique Morse Code Words
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5395164.html
Copyright © 2011-2022 走看看