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);

    }

}
原文地址:https://www.cnblogs.com/cwstd/p/13994691.html