1.类加载机制的原理:
- 启动JVM
- 将需要运行的class文件加载到虚拟机内存中
- 找到主类,开始执行主函数
加载步骤:
1.先委托父类加载类,如果父类已经加载,就不需要再次加载,如果父类没有加载,再由本加载器加载
2.解析类路径,将类路径转换成文件路径
3.通过文件输入流来读取class文件,得到字节数组
4.将字节数组转换成类对象,对象的类型是Class类型
2.有哪些类加载器:
- 扩展类加载器(extensions class loader):它用来加载Java的扩展库
- 应用类加载器:( AppClassLoader ):负责加载核心类,Java应用的类都是由它来完成加载的
- 启动类加载器(Bootstrap ClassLoader):是JVM的一部分,是由C++编写的,用来加载java核心类库
- 用户自定义类加载器,通过继承 java.lang.ClassLoader类的方式实现。
3.获得Class对象的几种方式:
- 通过类名获得Class对象:
//1.通过类名.class
Class c1 = Student.class;
- 通过对象的getClass()方法:
//2.通过对象的getClass()方法
Class c2 = stu.getClass();
3.通过类加载器获得class对象:
//3.通过类加载器获得class对象
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
Class c3 = classLoader.loadClass("com.newer.test.Student");
4.通过 Class.forName()获得Class对象:
//4.通过 Class.forName()获得Class对象;
Class c4 = Class.forName("com.newer.test.Student");
任何一个类都只能被加载一次
4.反射机制
- 为什么需要获得Class对象?
程序在运行时能够动态的获得类的相关信息的机制,叫做反射机制类的所有的信息都在Class对象中,Class类是反射机制中的核心类。
5.如何通过Class对象获得构造方法对象:
- 获得所有可见的构造方法:
//获得所有可见的构造方法
Constructor[] cons= c.getConstructors();
2.获得所有已经声明的构造方法:
//获得所有已经声明的构造方法
Constructor[] cons2= c.getDeclaredConstructors();
3.获得指定的可见的某一个构造方法:
//获得指定的可见的某一个构造方法
Constructor cc = c.getConstructor(int.class,String.class,int.class);
4.从声明的方法中获得指定的构造方法:
//从声明的方法中获得指定的构造方法
Constructor cc2 = c.getDeclaredConstructor(int.class);
6.如何通过构造方法对象实例化:
1.通过构造方法来实例化对象:
//通过构造方法对象得到类的实例对象
Object obj = cc.newInstance(123,"zhangsan",20);
括号中为构造方法的参数,
2.通过访问私有构造方法来实例化对象:
cc2.setAccessible(true);
Object obj2 = cc2.newInstance(22);
Student类的代码如下所示:
package com.newer.test;
public class Student {
private int num;
private String name;
private int age;
public Student(){
}
private Student(int num){
this.num = num;
}
public Student(int num,String name,int age){
this.num = num;
this.name = name;
this.age = age;
}
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;
}
@Override
public String toString() {
return "Student{" +
"num=" + num +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
调用代码如下:
package com.newer.test;
import java.lang.reflect.Constructor;
/**
* 反射机制动态获得类的信息
*/
public class FanShe {
public static void main(String[] args) throws Exception{
//加载类,获得类的Class对象
Class c = Class.forName("com.newer.test.Student");
//通过Class对象获得类的信息
//1.获得所有可见的构造方法
Constructor[] cons= c.getConstructors();
for (Constructor con:cons){
System.out.println(con);
}
//2.获得所有已经声明的构造方法
Constructor[] cons2= c.getDeclaredConstructors();
for (Constructor con:cons2){
System.out.println(con);
}
//3.获得指定的可见的某一个构造方法
Constructor cc = c.getConstructor(int.class,String.class,int.class);
System.out.println(cc);
//4.从声明的方法中获得指定的构造方法
Constructor cc2 = c.getDeclaredConstructor(int.class);
System.out.println(cc2);
//通过构造方法对象得到类的实例对象
Object obj = cc.newInstance(123,"zhangsan",20);
System.out.println(obj);
//通过私有构造方法实例化对象
//设置允许访问私有构造方法
cc2.setAccessible(true);
Object obj2 = cc2.newInstance(22);
System.out.println(obj2);
}
}