程序员社区

Java之注解相关知识点整理

注解

  • JDK中预定义的注解
  • 自定义注解
  • 演示
  • 元注解: 描述注解的注解
  • 在程序中使用(解析)注解:获取注解中定义的属性值
  • 简单的测试框架

JDK中预定义的注解

@override: 检测被注解标注的方法是否继承至父类(接口)的

@Deprecated:该注解标注的内容表示已过时

@SuppressWarnings:压制警告

//压制当前类可能弹出的所有警告被压制
@SuppressWarnings("all")
public class stu
{
    String name;
    //当前方法的所有警告被压制
    @SuppressWarnings("all")
        public void show()
        {
            System.out.println("学生的姓名:"+name);
        }
}

自定义注解

格式:

元注解
public @interface 注解名称()
{
   属性列表;
}

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

属性: 接口中的抽象方法

要求:

属性的返回类型由以下取值:

  • 基本数据类型
  • String
  • 枚举
  • 注解
  • 以上类型的数组

定义了属性,在使用时需要给属性赋值

  • 如果定义属性时,使用default关键字给默认初始化值,则使用注解时,可以不进行属性的赋值
  • 如果只有一个属性需要赋值,并且属性的名称叫value,则value可以省略,直接定义值即可
  • 数组赋值时,值使用{}包裹,如果数组中只有一个值,{}可以省略

演示

自定义注解类:

package reflect;

public @interface annto {
    int age();
    String name();
     Per p();
     ann2 anno2();

     String[] strs();
}

stu类:

package reflect;
@annto(age=18,name="大忽悠",p=Per.perople,anno2=@ann2,strs={"大忽悠","小朋友"})
public class stu
{
    String name;
        public void show()
        {
            System.out.println("学生的姓名:"+name);
        }
}


元注解: 描述注解的注解

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

ElementType取值:

  1. TYPE: 可以作用于类上
  2. METHOD: 可以作用于方法上
  3. FIELD:可以作用于成员变量上
//value可以省略,下面的写法可以同时作用于类上,方法上,成员变量上
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
//@Target(value={ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
public @interface ann2 {
}

@Retention:描述注解被保留的阶段

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

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

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

@Inherited
public @interface ann2 {
}

下面使用ann2注解的类或者成员方法,其子类也会带上ann2注解


在程序中使用(解析)注解:获取注解中定义的属性值

获取注解定义位置的对象(Class , Method ,Field)

获取指定注解

getAnnotation(class)
//其实就是在内存中生成一个该注解接口的子类实现对象
public class ProImp1 implements ann2
{
   public String ClassName()
   {
   return "reflect.stu";
   }
   public String MethodName()
   {
     return "show";
    }
}

调用注解中的抽象方法,获取配置的属性值

演示:

需求: 不改变类的任意代码,创建类的任意对象,执行类的任意方法

ann2注解类:

package reflect;
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 ann2
{
 String ClassName();
 String MethodName();
}

stu类:

package reflect;

public class stu
{
    String name;
    public void show()
    {
        System.out.println("学生的姓名:"+name);
    }
}

main函数:

package reflect;

import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;
@ann2(ClassName = "reflect.stu",MethodName = "show")
public class main {
    public static void main(String[] args) throws Exception
    {

        //1.获取该类的字节码文件对象
        Class<main>  mainClass=main.class;
        //2.获取上面的注解对象
        ann2 a2=mainClass.getAnnotation(ann2.class);
        //其实就是在内存中生成一个该注解接口的子类实现对象
/*        public class ProImp1 implements ann2
        {
            public String ClassName()
            {
                return "reflect.stu";
            }
            public String MethodName()
            {
                return "show";
            }
        }*/
        //3.调用注解对象中定义的抽象方法,获取返回值
        String className=a2.ClassName();
        String methodName=a2.MethodName();
        //3.加载该类进内存
        Class cls=Class.forName(className);
        //4.创建对象
        Object obj=cls.newInstance();
        //5.获取方法对象
        Method method=cls.getMethod(methodName);
       //6.执行方法
        method.invoke(obj);
    }
}

在这里插入图片描述


简单的测试框架

main:

package reflect;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
/*
*  当主方法执行后,会自动去执行所有被检测的方法(加了check注解的方法),如果方法有异常,那么将异常记录到文件中
* */
public class checkTest {
    public static void main(String[] args) throws IOException {
      //1.创建计算机对象
        calculator c=new calculator();
        //2.获取字节码文件对象
        Class cls=c.getClass();
        //3.获取所有方法
        Method[] methods=cls.getDeclaredMethods();

        //记录异常出现的次数
        int number=0;
        BufferedWriter bw=new BufferedWriter(new FileWriter("bug.txt"));
        for(Method method:methods)
        {
            //4.判断方法上是否有check注解
            if(method.isAnnotationPresent(check.class))
            {
                //5.有,执行
                try {
                    method.invoke(c);
                } catch (Exception e) {
                    //6.捕获异常
                    //记录到文件中
                    number++;
                    bw.write(method.getName()+"方法出异常了");
                    bw.newLine();
                    bw.write("异常的名称:"+e.getCause().getClass().getSimpleName());
                    bw.newLine();
                    bw.write("异常的原因"+e.getCause().getMessage());
                    bw.newLine();
                    bw.write("------------------------------------------");
                    bw.newLine();
                }
            }
        }
        bw.write("本次测试一共出现"+number+"次异常");
        bw.flush();
        bw.close();
    }
}

calculator:

package reflect;
public class calculator {
    @check
   public  void add()
    {
        System.out.println("a+b=大忽悠");
    }
    @check
    public void minus()
    {
        System.out.println("1/0="+1/0);
    }
    @check
    public  void div()
    {
        String str=null;
        str.toString();
    }

}

check:

package reflect;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/*需要在自定义注解上加 @Retention(RetentionPolicy.RUNTIME),声明该注解的存活策略可以保留到运行时,再通过反射获取时才可以正确获取。*/
@Retention(RetentionPolicy.RUNTIME)
public @interface check {
}

测试结果:

bug.txt:

minus方法出异常了
异常的名称:ArithmeticException
异常的原因/ by zero
------------------------------------------
div方法出异常了
异常的名称:NullPointerException
异常的原因Cannot invoke "String.toString()" because "str" is null
------------------------------------------
本次测试一共出现2次异常

在这里插入图片描述

赞(0) 打赏
未经允许不得转载:IDEA激活码 » Java之注解相关知识点整理

相关推荐

  • 暂无文章

一个分享Java & Python知识的社区