共计 4470 个字符,预计需要花费 12 分钟才能阅读完成。
今日分享开始啦,请大家多多指教~
这篇文章给大家先简简单单地说下类的加载,以及具体实现,能够本人操作一下哦!
类的加载
在程序运行后,首次应用某个类,会把这个类的字节码文件读取到内存,并且会将这个类的所有信息存到一个 Class 对象中。
简略步骤:
1:jvm 执行代码,例如读到 new Student()
2 : 读取 Student 的字节码文件
3:把字节码文件的内容(读取成字节码对象)存储到办法区(以前的说法),1.8 当前叫做元空间(貌似)
4:最初类加载实现当前,在堆空间创立内存空间。
类的加载机会(上面六种)
- 创立类的实例。(new 一个类)
- 类的动态变量,或者为动态变量赋值。
- 类的静态方法。
- 应用反射形式来强制创立某个类或接口对应的 java.lang.Class 对象。
- 初始化某个类的子类。
- 间接应用 java.exe 命令来运行某个主类。(编译 javac 类名.java, 运行 java. 类名)
明天的反射也属于类加载机会的一种
先上代码:
类加载机会代码演示
- 创立类的实例。动态代码块随着类的加载而加载,并且只执行一次。
- 类的动态变量,或者为动态变量赋值。
- 类的静态方法。
4. 反射通过 Class.forName(“ 全类名 ”) 进行反射
5. 通过子类实例
运行后果
都证实了这个 stu 类被加载了。
类加载器(临时先理解理解)
上面说说类加载器,类加载器是负责将理论空间中的某个 class 文件读取到内存中并且生成 Class 的对象。
Java 中有三品种加载器,它们别离用于加载不同品种的 class:
Java 中有三品种加载器,它们别离用于加载不同品种的 class:
- 启动类加载器 (Bootstrap ClassLoader):用于加载零碎类库 <JAVA_HOME>\bin 目录下的 class,例如:rt.jar。
- 扩大类加载器 (Extension ClassLoader):用于加载扩大类库 <JAVA_HOME>\lib\ext 目录下的 class。
- 应用程序类加载器 (Application ClassLoader):用于加载咱们自定义类的加载器。
进去代码看看,咱们是如何取得类加载器的
再点进 getClassLoader() 办法看看 jdk 是怎么形容的
图中看到,一些实现可能应用 null 来示意疏导类加载器,可能在此类中的实现返回 null.
举个例子。
好了,接下来该回到反射的主题
反射的概念
它一种机制,利用这个机制就能够在程序中对类进行解析,并且能够操作类中所有成员(变量,办法,构造方法)。
应用反射须要一个前提,获取须要反射的那个类的字节码对象。
Class 对象的获取形式
通过类名.class 取得
通过对象名.getClass() 办法取得
通过 Class 类的静态方法取得:static Class forName(“类全名”)
Tips: 每个类的 Class 对象都只有一个
Class 类罕用的办法
String getSimpleName(); 获取类名字符串 String getName(); 获取全类名字符串
创立类的对象
1.T newInstance(): 创立 Class 对象关联类的对象。
2. 通过 Constructor 类来创建对象
首先要获取结构器类
Class 类中与 Constructor 相干的办法
1.Constructor getConstructor(Class… parameterTypes)* 依据参数类型取得对应的 Constructor 对象。
getConstructor()的源码形容
上个应用的代码
Java | |
/** | |
* 先用 getConstructor() 获取 Constructor<T> 类对象 | |
* 再通过这个对象实例 T。没有参数的用法 | |
* @throws Exception | |
*/ | |
@Test | |
public void getPublicConstructorWithoutParameter() throws Exception { | |
Class<Student> studentClass = Student.class; | |
// 先获取无参结构类对象。Constructor<Student> constructor=studentClass.getConstructor(); | |
// 再通过这个实例办法,实例这个类 | |
Student student = constructor.newInstance();} | |
/** | |
* 先用 getConstructor() 获取 Constructor<T> 类对象 | |
* 再通过这个对象实例 T。有参数的用法 | |
* @throws Exception | |
*/ | |
@Test | |
public void getPublicConstructor() throws Exception { | |
Class<Student> studentClass = Student.class; | |
// 获取有参结构类 | |
Constructor<Student> constructor=studentClass.getConstructor(int.class); | |
// 输出参数实例化 Student 类 | |
Student student = constructor.newInstance(1); | |
} |
如图所述,如果传入了没有相干参数重载的结构器,会报 NoSuchMethodException 异样
2.Constructor getDeclaredConstructor(Class… parameterTypes)
- 依据参数类型取得对应的 Constructor 对象
- 能够是 public、protected、(默认)、private 修饰符的构造方法。
- 如果是被 protected、(默认)、private 修饰符润饰的结构器,须要确定自身是否拜访到,如果不能拜访到就要设置权限,用 setAccessible(true)。
暴力获取结构器,能获取包含 public protected default private
通过 getDeclaredConstructor() 暴力获取 Student 类中除了 public 其余修饰符的结构器, 但这个结构类对象须要设置权限,setAccessible(true)
具体要不要设置,得看这个修饰符自身是否拜访到相干资源。
图上是个反例。
3.Constructor[] getConstructors() 取得类中的所有构造方法对象,只能取得 public 的
上代码:
通过 getConstructors() 获取所有 public 润饰的结构器类对象。
@Test | |
public void getAllPublicConstructor(){ | |
Class<Student> studentClass = Student.class; | |
Constructor<Student>[] constructors = (Constructor<Student>[]) studentClass.getConstructors(); | |
for (Constructor<Student> constructor : constructors) {System.out.println(constructor); | |
} | |
} |
遍历打印的后果:
4.Constructor[] getDeclaredConstructors() 取得类中的所有构造方法对象
能够是 public、protected、(默认)、private 修饰符的构造方法。
通过 getDeclaredConstructors() 获取所有 p 润饰的结构器类对象。
@Test | |
public void getAllAccessConstructor(){ | |
Class<Student> studentClass = Student.class; | |
Constructor<Student>[] constructors = (Constructor<Student>[]) studentClass.getDeclaredConstructors(); | |
for (Constructor<Student> constructor : constructors) {System.out.println(constructor); | |
} | |
} |
遍历打印的后果:
获取成员办法
接下来的局部就不放代码演示了,就提供下 api。
1 Method getMethod(String name,Class…args);
办法名和参数类型取得对应的成员办法对象,只能取得 public 的
2 Method getDeclaredMethod(String name,Class…args);
依据办法名和参数类型取得对应的成员办法对象,包含 public、protected、(默认)、private 的
3 Method[] getMethods();
取得类中的所有成员办法对象,返回数组,只能取得 public 润饰的且蕴含父类的
4Method[] getDeclaredMethods();
取得类中的所有成员办法对象,返回数组, 只取得本类的,包含 public、protected、(默认)、private 的
通过反射拜访成员变量
Method 对象罕用办法
- Object invoke(Object obj, Object… args)
- 调用指定对象 obj 的该办法
- args:调用办法时传递的参数
- void setAccessible(true)
设置 ” 暴力拜访 ”——是否勾销权限查看,true 勾销权限查看,false 示意不勾销
通过反射获取类的成员变量
Class 类中与 Field 相干的办法
- Field getField(String name);
- 依据成员变量名取得对应 Field 对象,只能取得 public 润饰
- Field getDeclaredField(String name);
- 依据成员变量名取得对应 Field 对象,包含 public、protected、(默认)、private 的
- Field[] getFields();
- 取得所有的成员变量对应的 Field 对象,只能取得 public 的
- Field[] getDeclaredFields();
- 取得所有的成员变量对应的 Field 对象,包含 public、protected、(默认)、private 的
通过反射拜访成员变量
Field 对象罕用办法
**void set(Object obj, Object value)** | |
**void setInt(Object obj, int i)** | |
**void setLong(Object obj, long l)** | |
**void setBoolean(Object obj, boolean z)** | |
**void setDouble(Object obj, double d)** | |
**Object get(Object obj) | |
int getInt(Object obj)** | |
**long getLong(Object obj)** | |
**boolean getBoolean(Object ob)** | |
**double getDouble(Object obj)** | |
**void setAccessible(true); 暴力反射,设置为能够间接拜访公有类型的属性。** | |
**Class getType(); 获取属性的类型,返回 Class 对象。** |
今日份分享已完结,请大家多多包涵和指导!