zoukankan      html  css  js  c++  java
  • Java学习笔记 -注解

    概述

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

    • 2.自定义注解:
      [修饰符列表] @interface 注解类型名{}

    • 3.注解怎么使用,用在什么地方:
      第一:注解使用的语法格式:@注解类型名
      第二:注解可以出现在类上、属性上、方法上、变量上等,注解还可以出现在注解上

    示例程序:

    //MyAnnotation 注解类型
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MyAnnotation {
    
        /**
         * 在注解中可以定义属性,以下是MyAnnotation的name属性
         * 看着像一个方法,实际上是属性
         *
         * 属性的类型可以是:
         * 八种基本数据类型、String、class,它们的数组类型也可以
         */
        String name();
    
        int age() default 22;  //给属性指定默认值
    
        //如果属性名是value,且只有一个属性的话,则该属性名可以省略
        String value();
    }
    
    public enum Season {
        SPRING,SUMMER,AUTUNDO,WINTER
    
    }
    
    @MyAnnotation(name = "lisi", age = 12, value = "ee",season = {Season.SPRING,Season.SUMMER})
    public class AnnotationTest01{
    
        //如果数组中只有一个元素,则大括号可以省略
        @MyAnnotation(name = "zhangsan",value = "ee",season = Season.SPRING)
        public void doSome(){
    
        }
    }
    

    元注解

    • Target:
      用来标注”被标注的注解“可以出现在那些位置上
      @Target(ElementType.METHOD) : 表示”被标注的注解“只能出现在方法上

    • Retention:
      用来”被标注的注解“最终保存在哪里
      @Retention(RetentionPolicy.SOURCE) :表示该注解被保存在java源文件中
      @Retention(RetentionPolicy.CLASS):表示该注解被保存在class文件中
      @Retention(RetentionPolicy.RUNTIME):表示该注解被保存在class文件中,并且可以被反射机制读取

    在此基础上看看 @Override 的源码

    @Target(ElementType.METHOD)    //只能出现在方法上
    @Retention(RetentionPolicy.SOURCE)  //表示该注解被保存在源文件中
    public @interface Override {}
    
    • 是给编译器参考的,和运行阶段没有关系
    • 如果给方法加上了它,编译器会自动检测是否正确的重写了父类的方法

    @Deprecated

    @Retention(RetentionPolicy.RUNTIME)
    @Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
    public @interface Deprecated {}
    
    • 表示被标注的已过时,不推荐使用
    public class AnnotationTest03 {
        public static void main(String[] args) {
            T.doSome(); //doSome有横线
        }
    }
    
    class T{
        @Deprecated
        public static void doSome(){
    
        }
    }
    

    通过反射机制获取注解

    • 该注解必须被保存在class文件中,并且可以被反射机制读取

    示例程序:

    public class RefledtAnnotationTest {
        public static void main(String[] args) throws Exception {
            Class c = Class.forName("T");
    
            //如果c类有MyAnnotation这个注解,则返回true
            if(c.isAnnotationPresent(MyAnnotation.class)){
                MyAnnotation myAnnotation = (MyAnnotation)c.getAnnotation(MyAnnotation.class);
    
                //专门用来获取属性名为"value"的值
                String value = myAnnotation.value();
                System.out.println(value);
            } else {
                System.out.println(false);
            }
    
            //获取方法上完整属性
            Method doSomeMethod = c.getDeclaredMethod("doSome");
    
            if(doSomeMethod.isAnnotationPresent(MyAnnotation.class)){
                MyAnnotation myAnnotation = doSomeMethod.getAnnotation(MyAnnotation.class);
                System.out.println(myAnnotation.name());
                System.out.println(myAnnotation.age());
                System.out.println(myAnnotation.value());
            }
        }
    }
    

    注解的使用实例

    编写一个注解Id,用来修饰类,如果该类没有定义int id属性,就抛出异常

    代码:

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface Id {
    }
    
    public class HasNotIdPropertyException extends RuntimeException{
        public HasNotIdPropertyException(){
    
        }
    
        public HasNotIdPropertyException(String s){
            super(s);
        }
    
    }
    
    @Id
    public class User {
        int id;
        String name;
        int age;
    }
    
    public class Test {
        public static void main(String[] args) throws Exception {
            Class userClass = Class.forName("example.User");
    
            if(userClass.isAnnotationPresent(Id.class)){
    
                //获取类的属性
                Field[] fields = userClass.getDeclaredFields();
                boolean flag = false;
                for(Field f : fields){
                    if("id".equals(f.getName()) && "int".equals(f.getType().getSimpleName())){
                        flag = true;
                        break;
                    }
                }
    
                if(!flag){
                    throw new HasNotIdPropertyException("没有定义int id属性");
                }
            }
        }
    }
    
  • 相关阅读:
    浅拷贝在项目中的应用
    MVC3中使用AuthorizeAttribute特性来完成登陆权限的验证
    一个面向对象的JS例子,很好的支持了开闭原则(不要重复你昨天的代码)
    c++学习笔记5
    JS跨域访问操作iframe
    Select函数
    MacOS10.8.3+Xcode4.6+IOS6.1 编译FFmpeg,简单使用
    eclipse部署,在tomcat中找不到eclipse发布的项目。eclipse更改项目发布路径
    初识Volley(二)
    MySQL 5.0 迁移到 MariaDB 10.0.2 存储过程无法迁移
  • 原文地址:https://www.cnblogs.com/zy200128/p/13051073.html
Copyright © 2011-2022 走看看