一、类加载机制
1、基础知识
当系统使用某类的时,该类还未被加载到内存,则系统会通过加载、连接、初始化,实现对这个类进行初始化。
加载:
将class文件读入内存中,并为之创建一个 Class 对象;
任何类被使用时系统都会建立一个 Class 对象;
连接:
验证 是否有正确的内部结构,并和其他类协调一致;
准备 复制为类的静态成员分配内存,并设置默认初始化值;
解析 将类的二进制数据中的符号引用替换为直接引用;
初始化:
就是对象初始化、方法初始化等类似的初始化过程;
2、类初始化时机
创建类的实例;
方法类的静态变量、或者静态变量赋值;
调用类的静态方法;
使用反射方式强调创建某个类或接口对应的 java.lang.Class 对象;
初始化某个类的子类;
直接使用 Java.exe 命令来运行某个注类;
3、类加载器的组成
Bootstrap ClassLoader 根类加载器------>核心类的加载 例如 System 、 String 类
Extension ClassLoader 扩展类加载起---->加载拓展的类
System ClassLoader 系统类加载器----->加载程序员编写的文件
二、反射
1、基础知识
Java 反射机制是在运行状态中,对于任意一个类,都可以知道这个类的所有属性和方法;对于任意一个对象,都能够调用他的任意一个方法和属性;
2、获取 class 文件对象的方式
a、使用Object 的 getClass( )方法;
b、数据类型的静态属性 class
c、class 类中的静态方法
public static class forName(String className)
实体类:
package com.company;
public class WangZhe {
private String name;
private String sex;
int age;
WangZhe() {
}
private WangZhe(String name) {
this.name = name;
}
public WangZhe(String name, String sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
使用反射的类
package com.company;
public class Main {
public static void main(String[] args) {
WangZhe wangZhe1 = new WangZhe();
Class c1 = wangZhe1.getClass();
Class c2 = WangZhe.class;
try {
Class c3=Class.forName("com.company.WangZhe");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
3、获取类的构造方法
public constructor [ ] getConstructors ( );
所有的公共构造方法
public constructor <?> [ ] getDeclaredConstructors( )
获取所有的构造方法
代码演示
package com.company;
import java.lang.reflect.Constructor;
import java.util.Objects;
public class Main {
public static void main(String[] args) {
Class c = null;
try {
c = Class.forName("com.company.WangZhe");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//获取类内的所有的公共的构造方法
Constructor[] constructors = Objects.requireNonNull(c).getConstructors();
//获取所有的构造方法
// Constructor[] constructors = Objects.requireNonNull(c).getDeclaredConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
}
}
public constructor <T> getConstructor( Class<?>...parameterType)
获取单个构造方法,,
代码演示 并且获取目标类的 对象 使用无参构造方法
package com.company;
import java.lang.reflect.Constructor;
import java.util.Objects;
public class Main {
public static void main(String[] args) throws Exception {
Class c = Class.forName("com.company.WangZhe");
//获取单个构造方法
Constructor constructor = c.getConstructor();
//获取目标类的对象 obj 相当于 WangZhe 的对象
Object obj = Objects.requireNonNull(constructor).newInstance();
System.out.println(obj);
}
}
使用参数构造方法
package com.company;
import java.lang.reflect.Constructor;
import java.util.Objects;
public class Main {
public static void main(String[] args) throws Exception {
Class c = Class.forName("com.company.WangZhe");
//获取单个构造方法
Constructor constructor = c.getConstructor(String.class, String.class, int.class);
//获取目标类的对象 obj 相当于 WangZhe 的对象
Object obj = Objects.requireNonNull(constructor).newInstance("荆轲", "男", 13);
System.out.println(obj);
}
}
使用私有的构造方法:
import java.lang.reflect.Constructor;
public class TestOne {
public static void main(String[] args) throws Exception {
//获取字节码文件对象
Class c = Class.forName("test.People");
//获取私有的构造方法 getDeclaredConstructor
Constructor constructor = c.getDeclaredConstructor(String.class);
//创造临时访问私有权限
constructor.setAccessible(true);
//创造对象
Object obj=constructor.newInstance("韩小呆");
System.out.println(obj);
}
}
3、获取成员变量并使用
获取所有公共的成员变量
import java.lang.reflect.Field;
public class TestOne {
public static void main(String[] args) throws Exception {
//获取字节码文件对象
Class c = Class.forName("test.People");
//获取所有的成员变量 只能获得到公用的成员变量
Field[] fields = c.getFields();
for (Field field : fields) {
System.out.println(field);
}
}
}
获取全部成员变量
import java.lang.reflect.Field;
public class TestOne {
public static void main(String[] args) throws Exception {
//获取字节码文件对象
Class c = Class.forName("test.People");
//获取所有的成员变量
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}
}
}
使用公共的成员变量
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class TestOne {
public static void main(String[] args) throws Exception {
//获取字节码文件对象
Class c = Class.forName("test.People");
//创建目标类对象
Constructor constructor = c.getConstructor();
Object obj = constructor.newInstance();
//获取公共的成员变量
Field fieldAge = c.getField("age");
//为常用变量赋值
fieldAge.set(obj, 18);
System.out.println(obj);
}
}
使用私有的成员变量
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
public class TestOne {
public static void main(String[] args) throws Exception {
//获取字节码文件对象
Class c = Class.forName("test.People");
//创建目标类对象
Constructor constructor = c.getConstructor();
Object obj = constructor.newInstance();
//获取私有的成员变量
Field fieldAge = c.getDeclaredField("name");
//获取临时访问权限
fieldAge.setAccessible(true);
//为常用变量赋值
fieldAge.set(obj, "韩小呆");
System.out.println(obj);
}
}
4、获取类的方法
获取自己的以及父类的所有的公共方法
import java.lang.reflect.Method;
public class TestOne {
public static void main(String[] args) throws Exception {
//获取字节码文件对象
Class c = Class.forName("test.People");
//获取所有的公共方法
Method[] methods = c.getMethods();
//输出方法
for (Method method : methods) {
System.out.println(method);
}
}
}
获取所有自己的方法
import java.lang.reflect.Method;
public class TestOne {
public static void main(String[] args) throws Exception {
//获取字节码文件对象
Class c = Class.forName("test.People");
//获取自己所有的方法
Method[] methods = c.getDeclaredMethods();
//输出方法
for (Method method : methods) {
System.out.println(method);
}
}
}
调用对象的公共无参方法
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class TestOne {
public static void main(String[] args) throws Exception {
//获取字节码文件对象
Class c = Class.forName("test.People");
//创建类对象
Constructor constructor = c.getConstructor();
Object obj = constructor.newInstance();
//获取无参公共的方法
//第一个参数为方法名,第二个参数为方法参数的class类型
Method method = c.getMethod("settingTest");
//调用目标对象方法
//第一个参数为 对象; 第二个参数为具体参数值
method.invoke(obj);
}
}
调用对象的私有无参方法
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class TestOne {
public static void main(String[] args) throws Exception {
//获取字节码文件对象
Class c = Class.forName("test.People");
//创建类对象
Constructor constructor = c.getConstructor();
Object obj = constructor.newInstance();
//获取无参私有的方法
//第一个参数为方法名,第二个参数为方法参数的class类型
Method method = c.getDeclaredMethod("myTest");
//创造临时权限
method.setAccessible(true);
//调用目标对象方法
//第一个参数为 对象; 第二个参数为具体参数值
method.invoke(obj);
}
}
调用有参有返回值的方法
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class TestOne {
public static void main(String[] args) throws Exception {
//获取字节码文件对象
Class c = Class.forName("test.People");
//创建类对象
Constructor constructor = c.getConstructor();
Object obj = constructor.newInstance();
//获取有参带返回值公共方法
//第一个参数为方法名,第二个参数为方法参数的class类型
Method method = c.getMethod("settingTest", String.class);
//调用目标对象方法 并获取返回值
//第一个参数为 对象; 第二个参数为具体参数值
Object objString = method.invoke(obj,"私有方法被调用");
//打印返回值
System.out.println(objString);
}
}