java注解记录

1.注解的概念

  • 注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。

2.注解的作用

  • 编写文档:通过代码里标识的注解生成文档【生成文档doc文档】
  • 代码分析:通过代码里标识的注解对代码进行分析【使用反射】
  • 编译检查:通过代码里标识的注解让编译器能够实现基本的编译检查【override】

3.JDK中内置的注解

  1.@Override

@Override 重写 检测被该注解标注的方法是否是继承自父类(接口)的方法

  2.@Suppvisewarnings

@Suppvisewarnings  压制警告

  3.@Deprecated

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

代码演示

package com.annotation.domain;

public class Penson {
   
  public String name="一拳嘤嘤超人";
  
  @Override
  public String toString() {
  	return "通过jdk内置@Override注解 重写Penson [name=" + name + "]";
  }
  
  /**
  * 此方法以弃用 可调用 watch2
  */
  @Deprecated(since="1.5") // since 至...之后  放JDK版本
  public void watch() {
  	System.out.println("看黑猫警长");
  }
  
  public void watch2() {
  	System.out.println("看熊出没");
  }


}

package com.annotation.exercise;

import com.annotation.domain.Penson;

/**
 * @author HeLang 
 * @Override 重写 检测被该注解标注的方法足否是继承自父类(接口) 
 * @Suppvisewarnings  压制警告
 * @Deprecated  该注解标注的内容,表示已过时
 */
public class JdkAnoDemo {
	  @SuppressWarnings("all")  //压制所有警告
	public static void main(String[] args) throws Exception {
		Penson person =new Penson();
		//@Override
		System.out.println(person.toString());
		//@Suppvisewarnings 
		@SuppressWarnings("unused") // 压制未使用变量警告
		int a=0;
	    @SuppressWarnings("rawtypes")  // 压制泛型警告
	    Class jdkAnoClass=JdkAnoDemo.class;
	    @SuppressWarnings("deprecation")  //压制过时方法警告
		Object o1 =jdkAnoClass.newInstance();
	    System.out.println();
	    //@Deprecated  
	    person.watch();
	    person.watch2();
	}
}
运行结果
通过jdk内置@Override注解 重写Penson [name=一拳嘤嘤超人]

看黑猫警长
看熊出没

4.自定义注解

1.格式

public @interface 注解名 {
// 属性值类型
* 基本数据类型八种( 四种整数类型byte、short、int、long
* 两种浮点数类型float、double 一种布尔类型 boolean  一种字符类型char)
* String  枚举  注解  以及它们的数组类型
}

2.演示

package com.annotation.exercise;
/**
 * @author HeLang
 * 自定义注解
 * 	  属性值:基本数据类型八种(四种整数类型byte、short、int、long
 * 		    两种浮点数类型float、double 一种布尔类型 boolean  一种字符类型char)
 * 		    String 枚举  注解  以及它们的数组类型 修饰符只能是public abstract
 *    使用:如果定义了注解的属性时,使用时要将注解中的属性赋初始值
 *         也可以通过使用default可以设置默认初始值 在使用时则不用初始化赋值
 *         如果属性只有一个 且属性名为value时 使用该注解初始化时可以省略属性名
 *         如果属性时数组值应放入{}中 如果{}中只有一个属性值时 可以省略{}
 */

import com.annotation.domain.MyAnoEnum;

public @interface MyAnoDemo {
		//基本数据类型八种
	     byte    byteTest()   default 0;
	     short   shortTest()  default 0;
	     int     intTest()    default 0;
	     long    longTest()   default 0;
	     float   floatTest()  default 0;
	     double  doubleTest() default 0;
	     boolean booleanTest()default false;
	     char    charTest()   default '男';
	     //String
	     String stringTest() default "默认值";
	     //枚举 
	     MyAnoEnum myAnoEnum()default MyAnoEnum.NAME;
	     //注解 
	     MyAnoDemo2 myAnoDemo2() default @MyAnoDemo2 ;
	     //数组类型
	     String[] strs() default {"1","2"};
	     int [] ints()default {3,4};;
	     MyAnoEnum[] myAnoEnums() default { MyAnoEnum.NAME, MyAnoEnum.NAME2};
	     MyAnoDemo2 [] myAnoDemo2s() default {@MyAnoDemo2 };// 可以省略{}
	     
	}

3.使用

@MyAnoDemo(byteTest = 1, stringTest="Use",strs = {"aa","bb"})

5.元注解

1.概念

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

2.常用元注解

1. @Target(ElementType) 描述作用域
  • TYPE 类
  • FIELD 成员变量
  • METHOD 方法
  • PARAMETER 方法参数
  • CONSTRUCTOR 构造方法
  • LOCAL_VARIABLE 局部变量
2. @Retention(RetentionPolicy) 描述保留阶段
  • SOURCE 在编译器编译成class文件前就会被移除
  • CLASS 会保留到class字节码文件中,不会被jvm读取到
  • RUNTIME 会保留到class字节码文件中,并被jvm读取到
3. @Documented: 描述是否被抽取到api文档中
  • javadoc xx.java(生成文档)
  • javac xx.java(编译)
  • javap xx.java(反编译)
4. @Inherited:描述是否被子类继承
  • 被作用的类的子类也会继承@Inherited注解
  • 被作用的类实现的接口 子接口不会继承@Inherited注解
  • 被作用的接口的子接口 不会继承@Inherited注解

注意:如果出现元注解无法解析 可能是源文件损坏了 找到源文件路径去把他更换掉

6.解析注解

package com.annotation.project;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

/**
 * @author HeLang
 * 注解解析   Annotation_parsing
 * 模拟框架类 在不改变该类的任何代码的情况下,可以创建任意类的对象,执行任意方法
 * 使用注解代替配置文件 
 *
 */
@SuppressWarnings("all")
@Parse(className = "com.annotation.domain.Person", methodName = "watch2")
public class Annotation_parsing {

	public static void main(String[] args) throws Exception {
		// 获取该类的字节码文件对象 
		Class<Annotation_parsing> cls =Annotation_parsing.class;
		// 获取该类上的注解对象(注解的实现类) 
		/*
		 * public class CheckImpl implements  Check{
		 *	 String methodName(){
		 * 		}
		 *   String className(){
		 *   }
		 */
		Parse parsing=cls.getAnnotation(Parse.class);
		// 获取注解中的属性值
		String methodName= parsing.methodName();
		String className =parsing.className();
		System.out.println(methodName);
		System.out.println(className);
		// 根据属性值来需要执行的类对象和方法 
		Class person=Class.forName(className);
		Method watch =person.getMethod(methodName);
		// 执行方法 
		watch.invoke(person.newInstance()); 
	}
}

package com.annotation.project;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 
 * @author HeLang
 * 解析注解
 */
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Parse {
	 String methodName();
	 String className();
}

7.注解案例

package com.annotation.project;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author HeLang
 * Annotation_case_execute 注解案例执行类
 * 将添加@Check的方法 验证该方法是否存在bug  
 */
@SuppressWarnings("all")
public class Annotation_case_execute {

	public static void main(String[] args) throws IOException {
		System.out.println("启动了");
		//获取使用check注解类的字节码文件
		Annotation_case annotation_case =new Annotation_case();
		int number =0;
		Class caseClass =annotation_case.getClass();
	    //获取被check注解的所有方法
		Method [] method =caseClass.getDeclaredMethods();
		
		BufferedWriter bw =new BufferedWriter(new FileWriter("bug.txt"));
		for (Method method2 : method) {
			method2.setAccessible(true); //开启暴力反射
			// 判断该方法是否有check注解
			if(method2.isAnnotationPresent(Check.class)) {
				//执行该方法
				try {
					method2.invoke(annotation_case);
				} catch (Exception e) {
					number++;
					bw.write("方法:"+method2.getName());
					System.out.println("方法:"+method2.getName());
					bw.newLine();
					bw.write("异常名字:"+e.getCause().getClass().getSimpleName());
					System.out.println("异常名字:"+e.getCause().getClass().getSimpleName());
					bw.newLine();
				    bw.write("异常的原因:"+e.getCause().getMessage());	
				    System.out.println("异常的原因:"+e.getCause().getMessage());
				    bw.newLine();
				    bw.write("------------------------------------");
				}
			}
		}
		            bw.write("捕获异常次数:"+number);
		            System.out.println("捕获异常次数:"+number);
		            bw.flush();
		            bw.close();
	}
}

方法:nullException
异常名字:NullPointerException
异常的原因:Cannot invoke "String.toString()" because "test" is null

方法:arithmeticException
异常名字:ArithmeticException
异常的原因:/ by zero
jin
方法:arithmeticException2
异常名字:ArithmeticException
异常的原因:/ by zero
捕获异常次数:3


package com.annotation.project;
/**
 * @author HeLang
 * 注解案列
 * 使用check注解 来实现检查方法的异常 并记录起来 
 */
@SuppressWarnings("all")
public class Annotation_case {
   
  @Check()
  private  void  nullException() {
	  String test= null;
	  test.toString();
  }
  @Check
  protected  void arithmeticException() {
	 int i =1/0;
  }

  @Check
  public  void arithmeticException2() {
	 int i =1/0;
  }

}


目录
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值