java JDK8 学习笔记——第17章 反射与类加载器
第十七章 反射与类加载器
17.1 运用反射
反射:.class文档反映了类基本信息,从Class等API取得类信息的方式称为反射。
17.1.1 Class与.class文档
1、java.lang.Class的实例代表Java应用程序运行时加载的.class文档,类、接口、Enum等编译过后,都会生成.class文档。Class类没有公开构造函数,实例时候JVM自动产生,每个.class文档加载时,JVM会自动生成对应的Class对象。
2、取得Class对象的方式:
(1)通过Object的getClass方法
(2)通过.class常量取得每个对象对应的Class对象
(3)如果是基本类型,可以使用对应的打包类加上.TYPE取得Class对象
3、默认首次加载.class文档时会执行静态区块。
4、类信息是在编译时期存储在.class文档,这是java支持执行运行时类型识别的方式。编译时期若使用到相关类,编译程序会检查对应的.class文档中记载的信息,以确定是否可完成编译。执行时期使用某类是,会先检查是否有对应的Class对象,如果没有,会加载对应的.class文档并生成对应的Class实例。
5、默认使用getClass()或.class取得的Class实例会是同一个对象。
17.1.2 使用Class.forName()
1、Class.forName()方法实现动态加载类,可用字符串指定类名称来获得类相关信息。
2、Class.forName()另一个版本可以让指定类名称、加载类时是否执行静态区块与类加载器。
static Class forName(String name,boolean initialize,ClassLoader loader)
17.1.3 从Class获得信息
Class对象代表加载的.class文档,取得Class对象后,就可以取得.class文档中加载的信息,像是包、构造函数、方法成员、数据成员等类型。
17.1.4 从Class建立对象
1、事先不知道类名称时,可以利用Class.forName()动态加载.class文档,取得Class对象之后,利用其newInstance()方法建立类实例。
Class clz = Class.forName(args[0]); Object obj = clz.newInstance();
2、若类定义有多个构造函数,也可以指定使用哪个构造函数生成对象,这必须在调用Class的getConstructor()方法时指定参数类型,取得代表构造函数的Constructor对象,利用Constructor的newInstance()指定创建时的参数值来建立对象。
3、生成数组:数组的Class实例是由JVM生成,也可以通过.class或getClass()取得Class实例。生成动态生成长度为10的java.util.ArrayList数组:
Class clz = java.util.ArrayList.class; Object obj = Array.newInstance(clz,10);
4、从第一个索引取得被手机对象实际的Class实例,此时就可以用它配合Array.newInstance()建立数组实例。
17.1.5 操作对象方法与成员
1、可以使用invoke()方法来动态调用指定的方法。
2、调用受把保护或私有方法,可以使用Class的getDeclaredMethod()取得方法,并在调用Method的setAccessible()时指定为true。
17.1.6 动态代理
1、在反射API中有个Proxy类,可动态建立接口的操作对象。
2、使用代理机制有两种代理方式:静态代理和动态代理。
3、静态代理
在静态代理实现中,代理对象与被代理对象必须实现同一接口,在代理对象中可以实现日志服务,必要时调用被代理对象,,可以这样使用代理对象:
Hello proxy = new HelloProxy(new HelloSpeaker()); proxy.hello("Justin");
创建代理对象HelloProxy时必须指定被代理对象HelloSpeaker,代理对象代理HelloSpeaker执行hello方法。
静态代理必须为个别接口操作出个别代理类,在应用程序行为复杂时,多个接口必须定义多个代理对象,操作与维护代理对象会有不少的负担。
4、动态代理
使用动态代理机制,可使用一个处理者代理多个接口的操作对象,处理者类必须操作java.lang.reflect.InvocationHandler接口。
使用Proxy.newPrxyInstance()方法建立代理对象,调用时必须指定类加载器,告知要代理的接口,以及接口上定义方法被调用时的处理者,Proxy.newPrxyInstance()方法底层会使用原生方式生成代理对象的Class实例,并利用它来生成代理对象。
17.2 了解类加载器
类加载器实际的职责就载入.class文档,JDK本身有默认的类加载器。
17.2.1 类加载器层级架构
1、Bootstrap Loader:产生Exrtended Loader和System Loader
Exrtended Loader:父加载器为Bootstrap Loader
System Loader:父加载器为Exrtended Loader
2、Bootstrap Loader通常由C撰写而成。若是Oracle的JDK,Bootstrap Loader会搜索系统参数sun.boot.class.path中指定位置的类,默认是JRE目录的classes中的.class文档,或lib目录中.jar文档里的类。
3、Exrtended Loader由Java撰写而成,会搜索系统参数java.ext.dirs中指定位置的类,默认是JRE目录lib\ext\classes中的.class文档。
4、System Loader由Java撰写而成,会搜索系统参数java.class.path中指定位置的类,也就是CLASSPATH路径,默认是当前工作路径下的.class文档。
5、加载类是会以Bootstrap Loader->Exrtended Loader->System Loader的顺序寻找类,如果所有类加载器都找不到指定类,就会抛出java.lang.NoClassDefFoundError.
6、对null调用getParent()方法会抛出NullPointedException异常。
7、ClassLoader可以使用loadClass()方法加载类,使用localClass方法加载类时,默认不会执行静态区块,真正使用类建立实例时才会执行静态区块。
17.2.2 建立ClassLoader实例
1、使用URLClassLoader来产生新的类加载器,需要java.net.URL作为其参数来指定类加载的搜索路径。使用URLClassLoader的loadClass()方法加载指定类时,会先委托父加载器代为搜索。
2、由同一类加载器载入的.class文档,只会有一个Class实例。如果同一.class文档由两个不同的类加载器载入,则会有两份不同的Class实例。
3、path可以输入不在System Loader以上层级类加载器搜索路径的其他路径。
java JDK8 学习笔记——第17章 反射与类加载器的更多相关文章
- java JDK8 学习笔记——第16章 整合数据库
第十六章 整合数据库 16.1 JDBC入门 16.1.1 JDBC简介 1.JDBC是java联机数据库的标准规范.它定义了一组标准类与接口,标准API中的接口会有数据库厂商操作,称为JDBC驱动程 ...
- java JDK8 学习笔记——第15章 通用API
第十五章 通用API 15.1 日志 15.1.1 日志API简介 1.java.util.logging包提供了日志功能相关类与接口,不必额外配置日志组件,就可在标准Java平台使用是其好处.使用日 ...
- java JDK8 学习笔记——第13章 时间与日期
第十三章 时间与日期 13.1 认识时间与日期 13.1.1 时间的度量 1.格林威治标准时间GMT 格林威治标准时间的正午是太阳抵达天空最高点之时.现在已经不作为标准时间使用. 2.世界时UT世界时 ...
- java JDK8 学习笔记——第18章 自定义泛型、枚举与注释
第十八章 自定义泛型.枚举与注释 18.1 自定义泛型 泛型定义: (1)仅定义在方法上的泛型语法 (2)用来限制泛型可用类型的extends与super关键字(3)?类型通配字符的使用 18.1.1 ...
- java JDK8 学习笔记——第11章 线程和并行API
第11章 线程与并行API 11.1 线程 11.1.1 线程 在java中,如果想在main()以外独立设计流程,可以撰写类操作java.lang.Runnable接口,流程的进入点是操作在run( ...
- java JDK8 学习笔记——助教学习博客汇总
java JDK8 学习笔记——助教学习博客汇总 1-6章 (by肖昱) Java学习笔记第一章——Java平台概论 Java学习笔记第二章——从JDK到IDEJava学习笔记第三章——基础语法Jav ...
- Android(java)学习笔记108:通过反射获取私有构造方法并且使用
反射获取私有构造方法并且使用: 1.获取字节码文件.class对象: Class c = Class.forName("cn.itcast_01.Person") ...
- CSS3秘笈第三版涵盖HTML5学习笔记13~17章
第13章,构建基于浮动的布局 使用的是float(浮动)属性 注:float:none值将取消所有浮动,通常只用来取消元素中已经应用的浮动. 切记:不需要给正文的div设计宽度,即使设计成固定宽度也不 ...
- Android(java)学习笔记49:通过反射获取私有构造方法并且使用
1. 反射获取私有构造方法并且使用: (1)获取字节码文件.class对象: Class c = Class.forName("cn.itcast_01.Person&qu ...
随机推荐
- C# 中distinct的使用
假设我们有一个类:Product public class Product { public string Id { get; set; } public string Name { get; set ...
- 2016.7.9 计算机网络复习要点第四章之网际控制报文协议ICMP
1.ICMP允许主机或路由器报告差错情况和提交有关异常情况的报告:为了更有效地转发IP数据报和提高交付成功的机会: 2.ICMP不是高层协议,因为ICMP报文是装在IP数据报中的,作为其中数据部分,所 ...
- 水题 ZOJ 3876 May Day Holiday
题目传送门 /* 水题:已知1928年1月1日是星期日,若是闰年加1,总天数对7取余判断就好了: */ #include <cstdio> #include <iostream> ...
- SignalR —— Asp.net RealTime的春天
一般的例子:http://www.asp.net/signalr/overview/signalr-20/getting-started-with-signalr-20/tutorial-gettin ...
- 在Unity3D 4中关联Visual Studio 2012来编写C#
Unity3D自带的MonoDevelop编辑器无论是js还是c#代码提示都很差,很诡异的就是变量名和方法名有的时候提示有的时候不提示.不过用Visual Studio代替MonoDevelop这个问 ...
- BZOJ2837 : 小强的形状
离散化后通过树状数组求出: b[i]为i之前比它小的. c[i]为i之前比它大的=i-1-i之前小于等于它的. d[i]为i之后比它小的. e[i]为i之后比它大的=n-i-f[i]. f[i]为i之 ...
- 【推荐】开放静态文件 CDN服务staticfile.org
虽然国内外有很多类似的服务器,比如最初的google ajax api,还有后来的sae,百度等都有提供,但是也都有不同的弊端,比如国内访问速度慢.提供的静态文件不全等...staticfile有望解 ...
- VSPM虚拟串口使用
(1)打开虚拟串口工具,当你设置好你程序中的串口信息后,打开程序中的串口,然后虚拟串口中所显示的就是程序的所提供的串口信息 (2)选中其中一个串口,修改管理信息,点击”重新连接“ , 直接在管理那里, ...
- Strong TLS configuration on servers
- Use certificates with at least sha-256 hash algorithms (including intermediate certificates).- Use ...
- Java 利用Apache Commons Net 实现 FTP文件上传下载
package woxingwosu; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import ...