第十八次总结 注解
- 什么是注解?
- 什么是元注解?
- 通过注解的方式实现自动注入?
1.什么是注解?
注解是程序的一部分
@Override 限定方法必须是重写的方法
@Deprecated 标记一个已经过时的方法
@SuppressWarnings("rawtypes") 忽略警告
自定义一个注解

2.什么是元注解?
元注解:用在注解中的注解
@Target 用来定义注解的使用范围
ElementType.ANNOTATION_TYPE 用在注解中
PACKAGE 用在包中
TYPE 用在类型上
CONSTRUCTOR 用在构造方法上
FIELD 用在属性上
METHOD 用在方法上
@Retention 用来定义注解的存在时间
RetentionPolicy.SOURCE 注解只存在于源代码中,编译成class的时候会丢弃注解
RetentionPolicy.CLASS 注解存在于class文件中,在加载到JVM中的时候会丢弃注解
RetentionPolicy.RUNTIME 注解在程序运行中依然存在
@Documented 注解文档化
@@Inherited 是否能被子类自动继承
3.通过注解的方式实现自动注入?
MyTest
import java.lang.annotation.*; /** * 自定义一个注解 * 注解 Annotation */ @Target({ElementType.METHOD,ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface MyTest { String value(); }
Teacher
public class Teacher { @MyTest("张三") private String name; public void teachJava(){ System.out.println(name+"在教Java课"); } @Override public String toString() { return "Teacher{" + "name='" + name + '\'' + '}'; } }
AutoCreate
import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 自定义创建对象的注解 */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface AutoCreate { }
AnnotationUtil
import java.lang.annotation.Annotation; import java.lang.reflect.Field; /** * 自定义注解的处理工具 */ public class AnnotationUtil { //解析obj对象的注解 public static void initData(Object obj){ try { //获得obj对象的Class对象 Class c = obj.getClass(); //获得name属性对象 Field name = c.getDeclaredField("name"); //获得name属性上的MyTest注解对象 MyTest an = name.getAnnotation(MyTest.class); //获得注解中的value值 String value = an.value(); //将注解中的值设置给属性 name.setAccessible(true); name.set(obj,value); }catch (Exception ef){ ef.printStackTrace(); } } }
AutoCreateUtil
import java.lang.reflect.Constructor; import java.lang.reflect.Field; public class AutoCreateUtil { public static void init(Object obj){ try { //拿到Manager类的Class对象 Class c = obj.getClass(); //获得Manager类中的teacher属性 Field f = c.getDeclaredField("teacher"); //获得f变量的类型的Class对象[Teacher类的Class对象] Class c2 = f.getType(); //获得Teacher类的无参构造方法 Constructor con = c2.getDeclaredConstructor(); //实例化对象 Object teacher = con.newInstance(); //处理Teacher的MyTest注解 AnnotationUtil.initData(teacher); //将teacher对象作为f的值 f.setAccessible(true); f.set(obj,teacher); }catch (Exception ef){ ef.printStackTrace(); } } }
Teachertest
public class Teachertest { public static void main(String[] args) { Teacher t = new Teacher(); //通过注解的方式设置属性的值 AnnotationUtil.initData(t); System.out.println(t); } }
输出结果:

如何在多个属性中设置指点属性?
Manager
public class Manager { @AutoCreate private Teacher teacher; @AutoCreate private Book book; @AutoCreate private Book book2; public void teach(){ System.out.println(book); teacher.teachJava(); System.out.println(book2); } }
Book
public class Book { private String name; public Book() { name="java"; } @Override public String toString() { return "Book{" + "name='" + name + '\'' + '}'; } }
AutoCreateUtil2
import java.lang.reflect.Constructor; import java.lang.reflect.Field; public class AutoCreateUtil2 { public static void init(Object obj){ try { //拿到Manager类的Class对象 Class c = obj.getClass(); Field[] fs = c.getDeclaredFields(); for(Field f:fs){ AutoCreate ac = f.getAnnotation(AutoCreate.class); if(ac!=null){ //获得f变量的类型的Class对象[Teacher类的Class对象] Class c2 = f.getType(); //获得Teacher类的无参构造方法 Constructor con = c2.getDeclaredConstructor(); //实例化对象 Object obj2 = con.newInstance(); //将teacher对象作为f的值 f.setAccessible(true); f.set(obj, obj2); if(f.getName().equals("teacher")){ AnnotationUtil.initData(obj2); } } } }catch (Exception ef){ ef.printStackTrace(); } } }
ManagerTest
public class ManagerTest { public static void main(String[] args) { Manager m = new Manager(); AutoCreateUtil2.init(m); m.teach(); } }
输出结果:


浙公网安备 33010602011771号