您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 管理学资料 > 12. 尚硅谷_佟刚_Java基础_反射
-2-理解Class类理解Java的类加载机制学会使用ClassLoader进行类加载理解反射的机制掌握Constructor、Method、Field类的用法理解并掌握动态代理目标Class类•Class类–对象照镜子后可以得到的信息:某个类的数据成员名、方法和构造器、某个类到底实现了哪些接口。对于每个类而言,JRE都为其保留一个不变的Class类型的对象。一个Class对象包含了特定某个类的有关信息。–Class对象只能由系统建立对象–一个类在JVM中只会有一个Class实例–每个类的实例都会记得自己是由哪个Class实例所生成获取Class对象的方式Class类的常用方法方法名功能说明staticClassforName(Stringname)返回指定类名name的Class对象ObjectnewInstance()调用缺省构造函数,返回该Class对象的一个实例ObjectnewInstance(Object[]args)调用当前格式构造函数,返回该Class对象的一个实例getName()返回此Class对象所表示的实体(类、接口、数组类、基本类型或void)名称ClassgetSuperClass()返回当前Class对象的父类的Class对象Class[]getInterfaces()获取当前Class对象的接口ClassLoadergetClassLoader()返回该类的类加载器ClassgetSuperclass()返回表示此Class所表示的实体的超类的Class•ClassLoader类装载器是用来把类(class)装载进JVM的。JVM规范定义了两种类型的类装载器:启动类装载器(bootstrap)和用户自定义装载器(user-definedclassloader)。JVM在运行时会产生3个类加载器组成的初始化加载器层次结构,如下图所示:BootstapClassloaderSystemClassloaderExtensionClassloader自底向上检查类是否已装载自顶向下尝试加载类引导类加载器:用C++编写的,是JVM自带的类装载器,负责Java平台核心库,用来装载核心类库。该加载器无法直接获取扩展类加载器:负责jdk_home/lib/ext目录下的jar包或–Djava.ext.dirs指定目录下的jar包装入工作库系统类加载器:负责java–classpath或–Djava.class.path所指的目录下的类与jar包装入工作演示类加载机制的层次关系:publicclassClassLoaderDemo{publicstaticvoidmain(String[]args){ClassLoaderclassloader;//获取系统缺省的ClassLoaderclassloader=ClassLoader.getSystemClassLoader();System.out.println(classloader);while(classloader!=null){//取得父的ClassLoaderclassloader=classloader.getParent();System.out.println(classloader);}try{Classcl=Class.forName(java.lang.Object);classloader=cl.getClassLoader();System.out.println(java.lang.Object'sloaderis+classloader);cl=Class.forName(com.atguigu.javase.reflection.ClassLoaderDemo);classloader=cl.getClassLoader();System.out.println(ClassLoaderDemo'sloaderis+classloader);}catch(Exceptione){System.out.println(Checknameoftheclass);}}}执行结果如下://表示系统类装载器实例化自类sun.misc.Launcher$AppClassLoadersun.misc.Launcher$AppClassLoader@19821f//表示系统类装载器的parent实例化自类sun.misc.Launcher$ExtClassLoadersun.misc.Launcher$ExtClassLoader@addbf1//表示系统类装载器parent的parent为bootstrap,无法直接获取null//表示类Object是由bootstrap装载的java.lang.Object'sloaderisnull//表示用户类是由系统类装载器装载的ClassLoaderDemo'sloaderissun.misc.Launcher$AppClassLoader@19821f反射•反射概述Reflection(反射)是Java被视为动态语言的关键,反射机制允许程序在执行期借助于ReflectionAPI取得任何类的內部信息,并能直接操作任意对象的内部属性及方法。Java反射机制主要提供了以下功能:在运行时构造任意一个类的对象在运行时获取任意一个类所具有的成员变量和方法在运行时调用任意一个对象的方法(属性)生成动态代理在运行时构造一个类的对象•调用Class对象的newInstance()方法•调用Constructor对象的newInstance(Object...initargs)Constructor对象•代表构造器对象•获取Constructor:•相关方法:–newInstance(Object...initargs)–setAccessible(booleanflag)Method(Field)对象•代表方法•Class对象获取Method的方法:–getDeclaredMethod(Stringname,Class?...parameterTypes)–getDeclaredMethods()–getMethod(Stringname,Class?...parameterTypes)–getMethods()•Method对象的方法:–invoke(Objectobj,Object...args)Annotation相关•以Method为例:–获取Annotation实例:•getAnnotation(ClassTannotationClass)•getDeclaredAnnotations()•getParameterAnnotations()泛型相关•获取父类泛型类型:TypegetGenericSuperclass()•泛型类型:ParameterizedType•获取实际的泛型类型参数数组:getActualTypeArguments()创建动态代理•Proxy提供用于创建动态代理类和代理对象的静态方法,它也是所有动态代理类的父类.•Proxy提供了两个方法来创建动态代理类和动态代理实例使用动态代理实现AOP•AOP(AspectOrientProgram,面向切面编程)动态代理增加的普通方法回调目标对象的方法动态代理增加的普通方法AOP代理的方法非模块化的横切关注点所带来的问题•横切关注点:跨越应用程序多个模块的功能.额外需求1:在程序执行期间追踪正在发生的活动额外需求2:希望计算器只能处理正数的运算代码实现片段问题•越来越多的非业务需求(日志和验证)加入后,原有的计算器方法急剧膨胀.•属于系统范围内的需求通常需要跨越多个模块(横切关注点),这些类似的需求包括日志,验证,事务等.算术计算器单元计算器日志验证非模块化的横切关注点将会导致的问题•代码混乱:每个方法在处理核心逻辑的同时还必须兼顾其他多个关注点.•代码分散:以日志需求为例,只是为了满足这个单一需求,就不得不在多个模块里多次重复相同的日志代码.如果日志需求发生变化,必须修改所有模块.使用动态代理模块化横切关注点•代理设计模式的原理:使用一个代理将对象包装起来,然后用该代理对象取代原始对象.任何对原始对象的调用都要通过代理.代理对象决定是否以及何时将方法调用转到原始对象上.调用者计算器日志代理验证代理参数验证方法日志开始方法日志结束代码实现代码实现测试代码
本文标题:12. 尚硅谷_佟刚_Java基础_反射
链接地址:https://www.777doc.com/doc-5232728 .html