今日小结0812—Class类
类加载机制的原理
- 采用委托父类加载器,如果父类已经加载则不需要重复加载,如果父类没有加载则由本加载器进行加载。
- 解析类路径,将其转换成文件路径(找到.class在磁盘中的位置)
- 通过文件输入流来读取class文件,得到二进制的字节数组。
- 将字节数组转换成类对象,对象的类型是Class对象。
每当一个.class文件读到JVM内存中都会转成一个Class对象。
类加载器有哪些
类加载器(ClassLoader)共分为三类
- Bootstrap ClassLoader叫启动类加载器,由C++编写,属于JVM的一部分其作用是加载Java\jdk\lib 目录中的文件,并且该类加载器只加载特定名称的文件(如 rt.jar),而不是该目录下所有的文件。随着JVM的启动就会创建一个Bootstrap类加载器对象。
- ExtClassLoader叫扩展类加载器,由Java实现。负责加载扩展类库。
- AppClassLoader叫应用类加载器,由Java实现。负责加载核心类,用户类路径中的文件。
除了上述3种定义好的类还可以通过继承ClassLoader来自定义类加载器。
获得Class对象的方式
-
通过类名.class
Class c1= stu.class; -
通过对象的getClass()方法
Class c2= stu.getClass(); -
通过类加载器获得class对象
Classloader classloader=CLassloader.getSystemClassLoader();
Class c3= Classloader.loaderClass(“包名.类名”) -
通过Class.forName()获得Class对象
Class c4= Class.forName(“包名.类名”);
其他类型获取Class对象的方式
- 基本类型的Class对象
- Class c=int.class;
- 数组类型的Class对象
- Class c=int[].class;
- Class c1=数组对象.getClass();
- 基本类型对应的包装类的Class对象
-
Class c1=Integer.class
-
Class c2=对象.getClass();
Integer t=100; Class c2=t.getClass();
-
Class c3=Class.forName(“java.lang.Integer”);
-
Class c4=Classloader.loaderClass(“java.lang.Integer”);
-
拿到包装类对应的基本类型的Class对象
Class c5=Interger.TYPE;
-
如何通过Class对象获得构造方法对象
创建一个student类
package com.lizhe;
public class Student {
// 声明Student类的属性
private int num;
private String name;
private int age;
private char sex;
// 重写构造方法方便通过Class查看调用
public Student() {
}
// 只有一个参数公开的构造方法
public Student(int num) {
this.num = num;
}
// 有四个参数公开的构造方法
public Student(int num, String name, int age, char sex) {
this.num = num;
this.name = name;
this.age = age;
this.sex = sex;
}
// 有一个参数私有的构造方法
private Student(String name) {
this.name = name;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
};
public String toString() {
return "Student [num=" + num + ", name=" + name +
", age=" + age + ", sex=" + sex + "]";
};
}
通过Test类执行主函数来进行Class类对象获取构造方法
获得可见的构造方法
package com.lizhe;
import java.lang.reflect.Constructor;
public class Test {
public static void main(String[] args) throws Exception {
// 获得Class类对象
Class c = Student.class;
// 通过getConstrucotor()方法来获得指定可查看的构造方法
// 参数为构造方法的类型Class对象
Constructor c1 = c.getConstructor();
System.out.println(c1);
Constructor c2 = c.getConstructor(int.class);
System.out.println(c2);
Constructor c3 = c.getConstructor(int.class, String.class, int.class, char.class);
System.out.println(c3);
System.out.println("-------------------------");
// 通过getConstructors()方法来获得所有可查看的构造方法
// 返回值是一个数组
Constructor[] cc = c.getConstructors();
for (Constructor c4 : cc) {
System.out.println(c4);
}
}
}
运行结果:
获得所有的构造方法
package com.lizhe;
import java.lang.reflect.Constructor;
public class Test2 {
public static void main(String[] args) throws Exception {
// 获得Student的Class类对象
Class c = Student.class;
// 通过getDeclaredConstructor()方法来获得指定的构造方法
Constructor c1 = c.getDeclaredConstructor(String.class);
Constructor c2 = c.getDeclaredConstructor(int.class);
System.out.println(c1);
System.out.println(c2);
System.out.println("------------------------");
// 通过getDeclaredConstructors()方法来获得所有的构造方法
Constructor[] cc = c.getDeclaredConstructors();
for (Constructor c3 : cc) {
System.out.println(c3);
}
}
}
运行结果:
如何通过构造方法对象实例化
package com.lizhe;
import java.lang.reflect.Constructor;
public class Test3 {
public static void main(String[] args) throws Exception {
// 获得Student的Class类对象
Class c = Student.class;
// 通过getDeclaredConstructor()方法来获得指定的构造方法
// 获取私有的构造方法
Constructor c1 = c.getDeclaredConstructor(String.class);
// 由于该构造方法私有不可访问
// 通过setAccessible方法可以设置true来进行访问
c1.setAccessible(true);
// 通过构造方法实例化对象
Object s1 = c1.newInstance("张三");
// 将结果打印
System.out.println(s1.toString());
System.out.println("-----------------------");
// 获取公开的构造方法
Constructor c2 = c.getConstructor(int.class);
// 通过构造方法实例化对象
Object s2 = c2.newInstance(12);
// 将结果打印
System.out.println(s2.toString());
}
}
运行结果: