zoukankan      html  css  js  c++  java
  • Java注解

    Java注解

    • 概念:说明程序的,给计算机看的
    • 注释:用文字去描述程序,给程序员看。
    • 概念描述:注解JDK1.5之后的新特性,与类、接口、枚举是在同一个层次。
    • 作用分类:
    1. 编写文档:通过代码里的标识的注解生成的文档【生成doc文档】
    2. 代码分析:通过代码里的标识的注解对代码进行分析【使用反射】
    3. 编译检查:通过代码里的标识的注解让编译器能过实现基本的编译检查【Override】
    //1.编写文档 在类的前面注解,或者在方法前面注解,可以自动生成API
    /**
         *
         * @param a 整数
         * @param b 整数
         * @return 两数的和
         * 
         */
    public int add(int a,int b)
     {
         return a+b;
     }
    
    • JDK中预定义的一些注解
    1. @ Override:检测被该注解标注的方法是否是继承自父类(接口)
    2. @Deprecated:该注解标注的内容,表示已经过时
    3. @SuppressWarnings:压制警告
    @SuppressWarnings("all") //压制所有的警告
    public class AnnoDemo2 {
        @Override
        public  String toString() //检测是否继承自父类,如果没有注解@Override会报错。例如:toString()写成了toString1()
        {
            return super.toString();
        }
        @Deprecated //方法会被打上横杠表示废弃
        public  void show1()
        {
            //有缺陷
        }
    
        public void show2()
        {
            //新方法
        }
    }
    
    • 自定义注解

      Ⅰ格式:

      元注解

      public @interface 注解名称()

      Ⅱ本质:注解本质上就是一个接口,该接口默认继承Annotation接口

      public interface Anno extend java.lang.annotation.Annotation{}

    Ⅲ属性:接口中抽象方法

    1.属性的返回值类型

    • 基本数据类型
    • String
    • 枚举
    • 注解
    public @interface Anno {
       String show1(); //属性show1 字符串类型
       int show();
       Person per();
       Anno2 anno2(); //属性类型为Anno2注解
       String [] str();
    }
    

    2.需要给属性赋值

    • 如果定义属性时,使用default关键字给属性默认初始化值,使用注解时,自动使用默认值
    • 如果只有一个属性需要赋值,并且属性的名称是value+,并且只有一个属性value,可以省略名字
    • 数组赋值时,值使用()包裹,如果数组中只有一个值,则{ }省略
    @Anno(show = 12,per = Person.p1,show1 = "12312",anno2 = @Anno2,str = {"21323","123","123"})
        public int add(int a,int b)
        {
            return a+b;
        }
    

    Ⅳ元注解:用于描述注解的注解

    @Target:描述注解能够作用的位置

    ElementType取值:

    *TYPE:可以作用于类上

    *METHOD:可以作用于方法上

    *FIELD:可以作用于成员变量上

    @Retention:描述注解能被保留的位置

    *@Retention(RetentionPolicy.RUNTIME):当前被描述的注解,会保留class字节码文件中,并被JVM读取到。

    RetentionPolicy.CLASS——>会被保留在class字节码文件中,但不会被JVM读取到

    RetrntionPolicy.SOURCE——>不会保留在class字节码文件中

    @Documented:描述注解是否能被抽取到API文档中

    @Inherited:描述注解是否被子类继承

    @Target(value ={ElementType.TYPE,ElementType.METHOD, ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented()
    @Inherited()
    public @interface Anno3 {
    }
    
    • 在程序中使用(解析)注解:获取注解中定义的属性值
      1. 获取注解定义的位置的对象(Class,Method,Field)
      2. 获取指定注解
      3. 调用注解中的抽象方法获取配置属性值

    小案例:

    需求:

    1. 新建一个Person类,定义一个anno注解
    2. 在AnnoTest类中获取注解
    3. 使用反射创建对象,使用Person类里面的方法

    Person类

    package com.cwstd.domain;
    
    public class Person {
        private  String name;
        private  String password;
        private  void eat()
        {
            System.out.println("eat.....");
        }
    }
    

    anno注解类

    package com.cwstd.annotation;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target(value = {ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    public @interface anno {
        String className();//注解中两个属性类名和方法名
        String methodName();
    }
    

    AnnoTest测试类

    package com.cwstd.reflect;
    import com.cwstd.annotation.anno;
    import com.cwstd.domain.Person;
    import java.lang.reflect.Method;
    @anno(className = "com.cwstd.domain.Student",methodName = "study")
    public class AnnoTest {
        public static void main(String[] args) throws Exception {
    				//解析注解
    				//获取类的字节码文件对象
            Class<AnnoTest> annoTestClass=AnnoTest.class;
    				//获取上边的注解对象
    				//其实就是在内存中生成了一个该注解接口的子类实现对象
            anno a=annoTestClass.getAnnotation(anno.class);
    				//调用注解对象中定义的抽象方法,获取返回值
            String className=a.className();
            String methodName=a.methodName();
            Class cla=Class.forName(className);
            Object obj=cla.newInstance();
            Method method=cla.getDeclaredMethod(methodName);
            method.setAccessible(true);
            method.invoke(obj);
    
        }
    
    }
    
  • 相关阅读:
    python3给socket模块设置代理
    yield、greenlet与协程gevent
    线程池
    并发通信、生产者与消费者模型
    多进程和多线程
    非阻塞套接字与IO多路复用
    14.python模块之subprocess
    判断页面是否滑到底部
    @vue/cli 3.x 版本配置productionGzip提高性能
    vue跳转到指定位置
  • 原文地址:https://www.cnblogs.com/cwstd/p/13994691.html
Copyright © 2011-2022 走看看