关于

反射

目标

  • 理解Class类
  • 理解Java的类加载机制
  • 学会使用ClassLoader进行类加载
  • 理解反射的机制
  • 掌握Constructor 、Method 、Field 类的用法
  • 理解并掌握动态代理

Class类

  • Class类
    —对象照镜子后可以得到的信息:某个类的数据成员名、方法和构造器、某个类到底实现了哪些接口。对于每个类而言,JRE都为其保留一个不便的Class类型的对象。一个Class对象包含了特定某个类的有关信息。
    —Class对象只能由系统建立对象。
    —一个类在JVM中只会有一个Class实例
    —每个类的实例都会记得自己是由哪个Class实例所生成

获取Class对象的方式

//通过类的class属性获取,该方法最为安全可靠,程序性能更高
Class class1 = String.class;
//对过对象的getClass()方法获取
Class class2 = "www.atguigu.com".getClass();
//通过ClassNotFoundException异常
//但可能抛出ClassNotFoundWxception异常
Class class3 = Class.forName("java.lang.String");

Class 类的常用方法

	方法名						功能说明
static Class forName(String name)  	返回指定类名name的Class对象
Object newInstance()			调用缺省构造函数,返回该Class对象的一个实例
Object newInstance(Object[] args)   	调用当前格式构造函数,返回该Class对象的一个实例
getName()				返回此Class对象所表示的实体(类、接口、数组类、基本类型或void)名称
Class getSuperClass()			返回当前Class对象的父类的Class对象
Class [] getInterfaces()		获取当前Class对象的接口
ClassLoader getClassLoader()		返回该类的类加载器
Class getSuperclass()			返回表示此Class所表示的实体的超类Class
  • ClassLoader
    类装载器是用来把类(class)装载进JVM的。JVM规范定义了两种类型的类装载器:启动类装载器(bootstrap)和用户自定义装载器(user-defined class loader)。JVM在运行时会产生3个类加载器组成的初始化加载器层次结构,如下图所示:
    Bootstap Classloader 自底向上检查类是否已加载
    Extension Classloader 自顶向下尝试加载类
    System Classloader

  • 演示类加载机制的层次关系:

public class ClassLoaderDemo{
		public static void main(String[] args){
			ClassLoader classloader;
			//获取系统缺省的ClassLoader
			classloader = ClassLoader.getSystemClassLoader();
			System.out.println(classloadre);
			while(classloader != null){
				//取得父类的ClassLoader
				classloader = classloader.getParent();
				System.out.println(classloader);
			}
		}
}
执行结果如下:
//表示系统类装载器实例化自类sun.misc.Launcher$AppClassLoader
sun.misc.Launcher$AppClassLoader@19821f
//表示系统类装载器的parent实例化自类sun.misc.Launcher$ExtClassLoader
sun.misc.Launcher$ExtClassLoader@addbf1
//表示系统类装载器parent的parent为bootstrap,无法直接获取
null
//表示类Object是由bootstrap装载的
java.lang.Object's loader is  null
//表示用户类是由系统类装载器装载的
ClassLoaderDemo's loader is  sun.misc.Launcher$AppClassLoader@19821f

反射

  • 反射概述
    Reflection (反射) 是Java被视为动态语言的关键,反射机制允许程序在执行期借助于Reflection API取得任何类的内部消息,并能直接操作任意对象的内部属性及方法。
    Java反射机制主要提供了以下功能:
  • 在运行时构造任意一个类的对象
  • 在运行是获取任意一个类所具有的成员变量和方法
  • 在运行时调用任意一个对象的方法(属性)
  • 生成动态代理

在运行时构造一个类的对象

  • 调用Class对象的newInstance()方法
  • 调用Constructor对象的newInstance(Object…initargs)

Constructor 对象

  • 代表构造器对象
  • 获取Constructor:在这里插入图片描述

在这里插入图片描述

  • 相关方法:
    — newInstance (Object…initargs)
    —setAccessible(boolean flag)

Method (Field)对象

  • 代表方法
  • Class 对象获取Method的方法:
    —getDeclaredMethod(String name,Class<?>…parameterTypes)
    —getDeclaredMethods()
    —getMethod(String name,Class<?>…parameterTypes)
    —getMethods()
  • Method对象的方法
    —invoke(Object obj,Object…args)

Annotation相关

  • 以Method为例:
    —获取Annotation实例:
  • getAnnotation(Class annotationClass)
  • getDeclaredAnnotations()
  • getParameterAnnotations()

泛型相关

  • 获取父类泛型类型:Type getGenericSuperclass()
  • 泛型类型:ParameterizedType()
  • 获取实际的泛型类型参数数组:
    —getActuaTypeArguments

创建动态代理

  • Proxy 提供用于创建动态代理类和代理对象的静态方法,他也是所有动态代理类的父类
  • Proxy提供了两个方法来创建动态代理类和动态代理实例。

使用动态代理实现AOP

  • Aop(Aspect Orient Program,面向切面编程)

在这里插入图片描述

非模块化的横切关注点所带来的问题

  • 横切关注点:跨越应用程序多个模块的功能
    在这里插入图片描述

代码实现片段

在这里插入图片描述

非模块化的横切关注点将会导致的问题

  • 代码混乱:每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点
  • 代码分散:以日志需求为例,只是为了满足这个单一需求,就不得不在多个模块里多次重复相同的日志代码。如果日志需求发生变化,必须修改所有模块。

使用动态代理模块化横切关注点

  • 代理设计模式的原理:使用一个代理将对象包装起来,然后用该代理对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时讲方法调用转到原始对象上。
    在这里插入图片描述

代码实现

在这里插入图片描述

在这里插入图片描述

测试代码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值