注解和反射

注解

什么是注解Annotation

  • JDK5.0开始引入的技术
  • 不是程序本身,可以对程序作出解释
  • 可以被其他程序(比如:编译器等)读取
  • 可以附加在package,class,method,field等上面,相当于给添加了额外的辅助信息,可以通过反射机制编程实现对这些元数据的访问

内置注解

  • @Override 重写
  • @Deprecated 不推荐使用被注解的对象
  • @SuppressWarnings 抑制编译时的警告信息

自定义注解、元注解

@Documented
@Retention(RetentionPolicy.RUNTIME)  //注解的生命周期SOURCE<CLASS<RUNTIME
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})  //注解的使用范围
public @interface Deprecated {
	//注解参数:参数类型 + 参数名();
	//String value1() default -1; 设置默认值-1
	//反射机制变成可以实现对这些元数据的访问
	}

反射

Java反射机制

  • 反射机制可以使Java获取类似动态语言的特性:允许程序在执行区间借助反射API获取类的全部信息
  • 正常方式:引入需要的“包类”名称->通过new实例化->取得实例化数据
  • 反射方式:实例化对象->getClass()方法->得到完整的“包类”

创建运行时类的对象、获取运行时类的完整结构调

//java.lang.Class代表一个类
//java.lang.reflect.Method 
//java.lang.reflect.Field代表类的属性
//java.lang.reflect..Constructor代表类的构造器
	Class c4 = Class.forName("com.example.demo.User");
	//无参构造函数的情况下创建对象
        //User user1 = (User)c4.newInstance();
	//有参构造函数的情况下创建对象
        Constructor constructor = c4.getDeclaredConstructor(String.class,String.class);
        User user2 = (User)constructor.newInstance("name","id");
        System.out.println(user2.getId());
	//获取方法
        Method setName = c4.getDeclaredMethod("setName",String.class);
        setName.invoke(user2,"lily");
        System.out.println(user2.getName());
	//获取对象
        Field name = c4.getDeclaredField("name");
        name.set(user2,"tony");
        //name.setAccessible(true);可访问private 取消访问安全检查开关
        System.out.println(user2.getName());

类的加载与ClassLoader

  • 内存分布
    image
  • 类的加载
    image

反射操作注解

public class DemoApplication {
    public static void main(String[] args) throws Exception{
        //反射操作注释
        Class c1 = Class.forName("com.example.demo.Student");
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation:annotations){
            System.out.println(annotation);
        }
	//获取类注释
        TableAnnotation tableAnnotation = (TableAnnotation)c1.getAnnotation(TableAnnotation.class);
        System.out.println(tableAnnotation.value());
	//获取属性注释
        Field field = c1.getDeclaredField("name");
        FieldAnnotation a1 = field.getAnnotation(FieldAnnotation.class);
        System.out.println(a1.columnName() + a1.type() + a1.length());
    }
}

@TableAnnotation("db_Student")
class Student {
    @FieldAnnotation(columnName = "db_name", type = "String", length = 10)
    private String name;
    @FieldAnnotation(columnName = "db_id", type = "int", length = 10)
    private int id;

    public Student(String name, int id) {
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", id=" + id +
                '}';
    }
}

//类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TableAnnotation{
    String value();
}

//属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldAnnotation{
    String columnName();
    String type();
    int length();
}
posted @ 2022-08-11 18:16  不知名的呆毛  阅读(21)  评论(0编辑  收藏  举报