zoukankan      html  css  js  c++  java
  • 注解

    3 注解
    3.1 注解,或者叫做注释类型,英文单词是:Annotation
    疑问:注解是干什么的?


    3.2 注解Annotation是一种引用数据类型。编译之后也是生成xxx.class文件。

    3.3 怎么自定义注解呢?语法格式?
    [修饰符列表]@interface 注解类型名{

    }

    3.4 注解怎么使用,用在什么地方?
    第一:注解使用时的语法格式是:
    @注解类型名

    第二:注解可以出现在类上、属性上、方法上、变量上等。。。
    注解还可以出现在注解类型上。

    3.5 JDK内置了哪些注解?

    掌握:
    Deprecated 用 @Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。

    掌握:
    Override 表示一个方法声明打算重写超类中的另一个方法声明。

    了解:
    SuppressWarnings 指示应该在注释元素(以及包含在该注释元素中的所有程序元素)中取消显示指定的编译器警告。

    3.6 元注解
    什么是元注解?
    用来标注“注解类型”的“注解”,称为元注解。

    常见的元注解有哪些呢?
    Target
    Retention

    关于Target注解:
    这是一个元注解,用来标注“注解类型”的“注解”
    这个Target注解用来标注“被标注的注解”可以出现在哪些位置上。

    @Target(ElementType.METHOD):表示“被标注的注解”只能出现在方法上。
    @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})
    表示该注解可以出现在:
    构造方法上
    字段上
    局部变量上
    方法上
    ...
    类上...

    3.7 Retention的源代码:

    // 元注解
    public @interface Retention {
    // 属性
    RetentionPolicy value();
    }

    RetentionPolicy的源代码:
    public enum RetentionPolicy {
    SOURCE,
    CLASS,
    RUNTIME
    }


    3.8 Target的源代码


    关于Retention注解:
    这是一个元注解,用来标注“注解类型”的“注解”
    这个Retention注解用来标注“被标注的注解”最终保存在哪里。

    @Retention(RetentionPolicy.SOURCE):表示该注解纸杯保留在java源文件中。
    @Retention(RetentionPolicy.Class):表示该注解被保存在class文件中。
    @Retention(RetentionPolicy.RUNTIME):表示该注解被保存在class文件中,并且可以被反射机制所读取。


    3.9 注解在开发中有什么用呢?
    需求:
    假设有这样一个注解,叫做:@Id
    这个注解只能出现在类上面,当这个类上有这个注解的时候,要求这个类中必须有一个int类型的id属性。
    如果没有这个属性就报异常。如果有这个属性则正常执行!

    案例1:

    package com.javaSe.annotation;
    /*
    1 注解,或者叫做注释,英文单词是:Annotation
    2 注解Annotation是一种引用数据类型。编译之后也是生成xxx.class文件。
    3 怎么自定义注解呢?语法格式?
        [修饰符列表]@interface 注解类型名{
        
        }
        
    4 默认情况下,注解可以出现在任意位置。
    */
    @MyAnnotation
    public class AnnotationTest01 {
        
        @MyAnnotation
        private int no;
        
        @MyAnnotation
        public static void m1(){
            @MyAnnotation
            int i = 100;
        }
        
        @MyAnnotation
        public static void m2(@MyAnnotation String name,
                              @MyAnnotation int k){
        
        }
        
        @MyAnnotation
        public AnnotationTest01() {
        }
        
        @MyAnnotation
        public AnnotationTest01(int no) {
            this.no = no;
        }
    }
    
    
    @MyAnnotation
    interface MyInterface{
    
    
    }
    
    
    @MyAnnotation
    enum Season{
        SPRING,SUMMER,AUTUMN,WINTER
    }
     
    关于JDK当中的override(编译)注解:
    package com.javaSe.annotation;
    /*
    关于JDK lang包下的override注解
    
    
    源代码:
    public @interface Override {}
    
    
    @Override这个注解只能注解方法。
    @Override这个注解是给编译器参考的,和运行阶段没有关系。
    @Override凡是java中的方法带有这个注解的,编译器都会进行编译检查,如果这个方法不是重写父类的方法,编译器报错。
    
    
    标识性注解,给编译器作参考的。
    编译器看到方法上有这个注解的时候,编译器会自动检查该方法是否重写了父类的方法。
    如果没有重写,报错。
    
    
    这个只是在编译阶段起作用,和运行期无关。
    */
    public class AnnotationTest02 {
        
        @Override
        public String toString() {
            return "toString()";
        }
        
        public static void main(String[] args) {
        
        }
    }

    关于JDK当中的Deprecated(已过时)注解:

    package com.javaSe.annotation;
    
    
    // 表示这个类已过时。
    // @Deprecated
    public class AnnotationTest03 {
        public static void main(String[] args) {
            AnnotationTest03 at = new AnnotationTest03();
            at.doSome();
        }
        
        
        @Deprecated
        public void doSome(){
            System.out.println("do something!");
        }
        
        // Deprecated这个注解标注的元素已过时。
        // 这个注解主要是向其他程序员传达一个信息,告知已过时,有更好的解决方案存在。
        @Deprecated
        public static void doOther(){
            System.out.println("do other...");
        }
    }
    
    
    class T{
        public static void main(String[] args) {
            AnnotationTest03 at = new AnnotationTest03();
            at.doSome();
        
            AnnotationTest03.doOther();
        }
    }

    自定义注解:

    package com.javaSe.annotation;
    /*
    自定义注解:MyAnnotation
    */
    public @interface MyAnnotation {
    }

    注解修饰注解:

    package com.javaSe.annotation;
    
    
    // 注解修饰注解
    @MyAnnotation
    public @interface OtherAnnotation {
    
    
    }

    自定义注解:

    package com.javaSe.annotation2;
    
    
    public @interface MyAnnotation {
        
        /**
         * 我们通常在注解当中可以定义属性,以下是MyAnnotation的name属性。
         * 看着像一个方法,但实际上我们称之为属性name。
         * @return
         */
        String name();
        
        /**
         * 颜色属性
         * @return
         */
        String color();
        
        /**
         * 年龄属性
         * @return
         */
        int age() default 25; // 属性指定默认值
    }

    注解中的属性用法:

    package com.javaSe.annotation2;
    
    
    public class MyAnnotationTest {
        
        // 报错的原因:如果一个注解当中有属性,那么必须给属性赋值。(除非该属性使用了default指定了默认值)
        /*@MyAnnotation()
        public void doSome(){
        
        }*/
        
        // @MyAnnotation(属性名=属性值)
        // 指定name的属性值就好了
        @MyAnnotation(name="zhangsan",color = "红色")
        public void doSome(){
        
        }
    }

    自定义注解:

    package com.javaSe.annotation3;
    
    
    public @interface MyAnnotation {
        
        /**
         * 指定一个value属性
         * @return
         */
        String value();
        
        // String email();
    }

    如果注解中的属性是value,而且只有一个属性的时候,value可以省略:

    package com.javaSe.annotation3;
    /*
    如果一个注解的属性的名字是value的话,并且只有一个属性的话,在使用的时候,该属性名可以省略。
    */
    public class MyAnnotationTest {
        
        // 报错原因:没有指定属性的值。
        /*@MyAnnotation()
        public void doSome(){
        
        }*/
        
        @MyAnnotation(value = "hehe")
        public void doSome(){
        
        }
        
        @MyAnnotation("haha")
        public void doOther(){
        
        }
    }

    自定义注解:

    package com.javaSe.annotation3;
    
    
    public @interface OtherAnnotation {
        String name();
    }

    如果注解中的属性不是value,那么会报错

    package com.javaSe.annotation3;
    
    
    public class OtherAnnotationTest {
        
        // 报错了,因为属性名是name,不能省略。
        // @OtherAnnotation("test")
        
        // 正确的
        @OtherAnnotation(name = "test")
        public void doSome(){
        
        }
    }
     
    自定义注解(注解当中的属性可以是哪一种类型?):
    package com.javaSe.annotation4;
    
    
    public @interface MyAnnotation {
        /*
        注解当中的属性可以是哪一种类型?
            byte short int long float double double char String Class 枚举类型 以及以上每一种数组形式
         */
        
        int value1();
        
        String value2();
        
        int[] value3();
        
        String[] value4();
        
        Season value5();
        
        Season[] vakye6();
        
        Class parameterType();
        
        Class[] parameterTypes();
        
    }

    自定义枚举:

    package com.javaSe.annotation4;
    
    
    public enum Season {
        SPRING,SUMMER,ANTUMN,WINTER
    }

    自定义注解:

    package com.javaSe.annotation4;
    
    
    public @interface OtherAnnotation {
        
        /**
         * 年龄属性
         * @return
         */
        int age();
        
        /**
         * 邮箱数组,支持多个
         * @return
         */
        String[] email();
        
        /**
         * 季节数组,Season是枚举类型
         * @return
         */
        Season[] seasonArray();
    }

    如果注解是数组的话,该如何使用:

    package com.javaSe.annotation4;
    
    
    import java.lang.annotation.Retention;
    
    
    public class OtherAnnotationTest {
        
        // 数组是大括号
        @OtherAnnotation(age = 25, email = {"123","234","345","456"},seasonArray = Season.WINTER)
        public void doSome(){
        
        }
        
        @Deprecated
        // 如果数组中只有一个元素:大括号可以省略
        @OtherAnnotation(age = 25, email = "789",seasonArray = {Season.SPRING,Season.SUMMER})
        public void doOther(){
        
        }
    }

    自定义注解:

    package com.javaSe.annotation5;
    
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    
    // 只允许注解可以标注类、方法
    @Target({ElementType.TYPE,ElementType.METHOD})
    // 希望这个注解可以被反射到
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation {
        String value() default "黑龙江";
    }

    使用注解:

    package com.javaSe.annotation5;
    
    
    /*
    为什么注解不能用在成员变量和局部变量中还有构造方法中,因为你没有在注解类中定义。
    */
    
    
    @MyAnnotation("四川雅安")
    public class MyAnnotationTest {
        
        // @MyAnnotation
        int i;
        
        @MyAnnotation
        public void doSome(){
            // @MyAnnotation
            int i;
        }
        
        // @MyAnnotation
        public MyAnnotationTest() {
        
        }
    }

    通过反射机制获取注解:

    package com.javaSe.annotation5;
    
    
    public class ReflectAnnotationTest {
        public static void main(String[] args) throws Exception{
            
            // 获取这个类
            Class c = Class.forName("com.javaSe.annotation5.MyAnnotationTest");
            
            // 判断类上面是否有这个注解
            boolean b = c.isAnnotationPresent(MyAnnotation.class);
            // System.out.println(b);// true
            if(b){
                // 获取该注解对象
                MyAnnotation mt = (MyAnnotation) c.getAnnotation(MyAnnotation.class);
                // System.out.println("类上面的注解对象" + mt); //类上面的注解对象@com.javaSe.annotation5.MyAnnotation()
                // 获取注解对象的属性怎么办?和调接口没区别。
                String value = mt.value();
                System.out.println(value);
            }
            
            // 判断String类上面是否存在这个注解
            Class stringClass = Class.forName("java.lang.String");
            boolean b1 = stringClass.isAnnotationPresent(String.class);
            System.out.println(b1);// false
        }
    }

    ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    注解在程序中的用处:代码如下:

    自定义@Id注解

    package com.javaSe.annotation7;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    // 表示这个注解只能出现在类上面
    @Target(ElementType.TYPE)
    // 表示该注解可以被反射机制读取到
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Id {
    
    }
    
    // 这个注解@Id用来标注类,被标注的类中必须有一个int类型的id属性,没有就报异常

    User用户业务类:

    package com.javaSe.annotation7;
    
    @Id
    public class User {
        int id;
        String name;
        String password;
    }

    测试程序:

    package com.javaSe.annotation7;
    
    import java.lang.reflect.Field;
    
    public class Test {
        public static void main(String[] args) throws Exception{
            // 获取类
            Class userClass = Class.forName("com.javaSe.annotation7.User");
            // 判断类上是否存在@Id注解
            if(userClass.isAnnotationPresent(Id.class)){
                // 当一个类上有@Id注解的时候,要求类中必须存在int类型的id属性
                // 如果没有int类型的id属性则报异常。
                // 获取类的属性
                Field[] fields = userClass.getDeclaredFields();
                boolean isOk = false;// 给一个默认的标记
                for (Field field : fields){
                    if("id".equals(field.getName()) && "int".equals(field.getType().getSimpleName())){
                        // 表示这个类是合法的类。有@Id注解,则这个类中必须有int类型的id
                        isOk = true; // 表示合法
                        break;
                    }
                }
                
                // 判断是否合法
                if(!isOk){
                    throw new HasNotIdPropertyException("被@Id注解标注的类中必须要有一个int类型的id属性!");
                }
            }
        }
    }

    自定义异常:

    package com.javaSe.annotation7;
    
    /*
    自定义异常
     */
    public class HasNotIdPropertyException extends RuntimeException{
        public HasNotIdPropertyException(){
        
        }
        
        public HasNotIdPropertyException(String s){
            super(s);
        }
    }
  • 相关阅读:
    加入创业公司有什么利弊
    Find Minimum in Rotated Sorted Array II
    Search in Rotated Sorted Array II
    Search in Rotated Sorted Array
    Find Minimum in Rotated Sorted Array
    Remove Duplicates from Sorted Array
    Spiral Matrix
    Spiral Matrix II
    Symmetric Tree
    Rotate Image
  • 原文地址:https://www.cnblogs.com/xlwu/p/13612841.html
Copyright © 2011-2022 走看看