016_反射、注解和动态代理

反射

  • 反射就是:加载类,并允许以编程的方式解剖类中的各种成分(成员变量、方法、构造器等)。
    • 反射第一步:加载类,获取类的字节码:Class对象。
    • 获取类的构造器:Constructor对象。
    • 获取类的成员变量:Field对象。
    • 获取类的成员方法:Method对象。

反射第一步:获取Class对象

  • [Student.java] ——> [Student.class] ——> 字节码文件 ——> 加载 —— [内存 (Studdent.class)]
  • 获取Class对象的三种方式
    • Class c1 = 类名.class
    • 调用Class提供方法:public static Class forName(String package);
    • Object提供的方法: public Class getClass(); Class c3 = 对象.getClass();

获取类中的成分、并对其进行操作

  • Class提供了从类中获取构造器的方法。
方法说明
Constructor<?>[] getConstructors()获取全部构造器(只能获取public修饰的)
Constructor<?>[] getDeclaredConstructors()获取全部构造器(只要存在就能拿到)
Constructor getConstructor(Class<?>… parameterTypes)获取某个构造器(只能获取public修饰的)
Constructor getDeclaredConstructor(Class<?>… parameterTypes)获取某个构造器(只要存在就能拿到)
  • 获取类构造器的作用:依然是初始化对象返回
Constructor 提供的方法说明
T newInstance(Object… initargs)调用此构造器对象表示的构造器,并传入参数,完成对象的初始化并返回
public void setAccessible(boolean flag)设置为true,表示禁止检查访问控制(暴力反射)
  • 获取类的成员变量
方法说明
public Field[] getFields()获取类的全部成员变量(只能获取public修饰的)
public Field[] getDeclaredFields()获取类的全部成员变量(只要存在就能拿到)
public Field getField(String name)获取类的某个成员变量(只能获取public修饰的)
public Field getDeclaredField(String name)获取类的某个成员变量(只要存在就能拿到)
  • 获取到成员变量的作用:依然是赋值、取值。
方法说明
void set(Object obj, Object value):赋值
Object get(Object obj)取值
public void setAccessible(boolean flag)设置为true,表示禁止检查访问控制(暴力反射)
  • 获取类的成员方法
Method 提供的方法说明
public Object invoke(Object obj, Object… args)触发某个对象的该方法执行。
public void setAccessible(boolean flag)设置为true,表示禁止检查访问控制(暴力反射)

反射的作用

  • 基本作用:可以得到一个类的全部成分然后操作。
  • 可以破坏封装性。
  • 可以绕过泛型的约束
  • 适合做Java的框架,基本上,主流的框架都会基于反射设计出一些通用的功能。

注解

  • 就是Java代码里的特殊标记,比如:@Override、@Test等,作用是:让其他程序根据注解信息来决定怎么执行该程序。
  • 注解可以用在类上、构造器上、方法上、成员变量上、参数上、等位置处。
  • 自定义注解
public @interface 注解名称 {
    public 属性类型 属性名() default 默认值 ;
}
  • 特殊属性名: value
    • 如果注解中只有一个value属性,使用注解时,value名称可以不写。
  • 注解的作用
    • 对Java中类、方法、成员变量做标记,然后进行特殊处理。

元注解

  • 指的是:注解注解的注解。
  • @Target:声明被修饰的注解只能在哪些位置使用
@Target(ElementType.TYPE)
TYPE,类,接口
FIELD, 成员变量
METHOD, 成员方法
PARAMETER, 方法参数
CONSTRUCTOR, 构造器
LOCAL_VARIABLE, 局部变量
  • @Retention:声明注解的保留周期。
@Retention(RetentionPolicy.RUNTIME)
1. SOURCE 
只作用在源码阶段,字节码文件中不存在。
2. CLASS(默认值)
保留到字节码文件阶段,运行阶段不存在.
3. RUNTIME(开发常用)
一直保留到运行阶段。

注解的解析

  • 就是判断类上、方法上、成员变量上是否存在注解,并把注解里的内容给解析出来。
    • 要解析谁上面的注解,就应该先拿到谁。
    • 比如要解析类上面的注解,则应该先获取该类的Class对象,再通过Class对象解析其上面的注解。
    • 比如要解析成员方法上的注解,则应该获取到该成员方法的Method对象,再通过Method对象解析其上面的注解。
    • Class 、 Method 、 Field , Constructor、都实现了AnnotatedElement接口,它们都拥有解析注解的能力。
AnnotatedElement 接口提供了解析注解的方法说明
public Annotation[] getDeclaredAnnotations()获取当前对象上面的注解。
public T getDeclaredAnnotation(Class annotationClass)获取指定的注解对象
public boolean isAnnotationPresent(Class annotationClass)判断当前对象上是否存在某个注解

动态代理

  • 对象如果嫌身上干的事太多的话,可以通过代理来转移部分职责。
  • 对象有什么方法想被代理,代理就一定要有对应的方法。
  • 用接口表示代理。

为Java对象创建一个代理对象

  • java.lang.reflect.Proxy类:提供了为对象产生代理对象的方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 
参数一:用于指定用哪个类加载器,去加载生成的代理类
参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法
参数三:用来指定生成的代理对象要干什么事情
  • 对象 ——> Spring ——> 代理对象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

莫魂魂

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值