注解:
常用JDK预定义注解 @Override 检查是否重写 @Deprecated 标志已过时 @SuppressWarnings("all") 压制警告经过对其class文件进行反编译后:
Compiled from "TestAnnotation.java" public interface Day_8.TestAnnotation extends java.lang.annotation.Annotation得知:
注解 都继承于Annotation接口创建注解:
元注解 public @interface 注解名称 { 属性列表; //也是抽象方法,注解本质是一个借口 } 元注解主要是这些; @Target({ElementType.FIELD,ElementType.TYPE}) //可以作用的位置,method(方法),field(变量),type(类).. @Retention(RetentionPolicy.RUNTIME) //被保留的阶段(SOURCE源代码,CLASS类对象,RUNTIME运行时) @Documented //是否被抽取到api,即命令行下执行后javadoc后可否看见注解 @Inherited //是否可被子类继承该注释属性列表:
String,8种基本类型,注解,枚举类,以及前面这些的数组类型 在注解里添加了属性后,在设置注解时,需要进行赋值 @MyAnnotation(intType = 5,stringArray = {"add","sub"}, annotationType = @TestAnnotation1,enumType=Season.spring) 1.如果是数组,则值使用{} 2.可以为属性设默认值 default 值;演示:
TestAnnotation.java @Target({ElementType.FIELD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface TestAnnotation { int happyDegree() default 6; String className() default "ac"; Season happySeason(); TestAnnotation1 happyAnnotation(); String[] methodsName(); }实际上生成一个类继承注解接口实现对象,并根据赋值的内容,重写抽象方法(返回出来);
public tempClass implements MyAnnotation{ public int intType(){ return 5; } public String[] stringArray(){ String[] tempString = {"add","sub"}; return tempString; } ... }通过注解创建任意对象并执行任意方法 0.前提是有className,methodName属性,并被有效赋值 1.通过加了注解的类,使用其类对象来获取注解对象 2.注解属性赋值后,通过注解对象的方法(属性)可以获取值 3.通过反射Class.forName获取类对象,在使用该类对象获取构造器和method方法 4.完成method方法的invoke()
Class class1 = Calculate.class; TestAnnotation testAnnotation = (TestAnnotation) class1.getAnnotation(TestAnnotation.class); Class class2 = Class.forName(testAnnotation.className()); Object object = class2.getConstructor(String.class,int.class).newInstance("美团",11); Method method = class2.getMethod(testAnnotation.methodsName()[0],int.class,int.class); Method method1 = class2.getMethod(testAnnotation.methodsName()[1],int.class,int.class); System.out.println(method.invoke(object, 3,4)); System.out.println(method1.invoke(object, 3,4));注解作为解析代码的一种方式,可以供编译器使用, 通过对各种类型的isAnnotationPresent(Annotation.class)的判断,对注解进行自定义的处理
附件: Calculate.java
package Day_8; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Properties; @TestAnnotation(happyDegree = 5, className = "Day_8.Calculate", methodsName = {"add","sub"},happyAnnotation = @TestAnnotation1 ,happySeason=Season.spring) @SuppressWarnings("all") public class Calculate { private int a=5,b=3; private String name="helloWorld"; public String ya = "a"; public String ua = "a"; public String ia = "a"; public static int age = 10; public int add(int a,int b) { return a+b; } public int sub(int a,int b) { return a-b; } public Calculate(String name,int priority) { this.name = name; System.out.println(name+" is a priority "+priority+" calculator"); } public Calculate(String name,String priority) { this(name,Integer.parseInt(priority)); } public Calculate() { super(); } @Override public String toString() { return "Calculate [a=" + a + ", b=" + b + ", name=" + name + " , ya=" + ya + ", ua=" + ua + ", ia=" + ia + "]"; } public static void main(String[] args) throws Exception { Class class1 = Calculate.class; TestAnnotation testAnnotation = (TestAnnotation) class1.getAnnotation(TestAnnotation.class); Class class2 = Class.forName(testAnnotation.className()); Object object = class2.getConstructor(String.class,int.class).newInstance("美团",11); Method method = class2.getMethod(testAnnotation.methodsName()[0],int.class,int.class); Method method1 = class2.getMethod(testAnnotation.methodsName()[1],int.class,int.class); System.out.println(method.invoke(object, 3,4)); System.out.println(method1.invoke(object, 3,4)); } }Season.java
public enum Season { spring,summer,fall,winter; }Check.java
package Day_8Test; import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Check { }Problem.java
package Day_8Test; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @SuppressWarnings("all") public class Problem { @Check public static void add() { int result = 1+0; System.out.println("1 + 0 = "+result); } @Check public static void sub() { int result = 1-0; System.out.println("1 - 0 = "+result); } @Check public static void mul() { int result = 1*0; System.out.println("1 * 0 = "+result); } @Check public static void div() { int result = 1/0; System.out.println("1 / 0 = "+result); } public static void main(String[] args) throws Exception { Class class1 = Problem.class; Method[] methods = class1.getMethods(); BufferedWriter bw = new BufferedWriter(new FileWriter(".\\bugs.txt")); for(Method m:methods) { if(m.isAnnotationPresent(Check.class)) { try{ m.invoke(class1); } catch (Exception e) { bw.append(m.getName() + "() 出现异常"); bw.newLine(); bw.append("异常名称: "+ e.getCause().getClass().getSimpleName()); bw.newLine(); bw.append("异常原因: "+e.getCause().getMessage()); bw.newLine(); } } } bw.flush(); bw.close(); } }