Java虚拟机之对象创建过程
Java中的对象在内存中的实现是由Java虚拟机(JVM)负责完成的。对象的创建过程分为三步:
- 分配内存空间:JVM为对象在堆内存中分配一块连续的内存空间。
- 初始化对象:JVM为对象的成员变量赋初始值。
- 调用构造函数:JVM调用对象的构造函数来完成对象的初始化。
例子说明
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public void sayHello() {
System.out.println("Hello, my name is " + name + ", I am " + age + " years old.");
}
}
public class Main {
public static void main(String[] args) {
Person p = new Person("Tom", 20);
p.sayHello();
}
}
在这个例子中,Person
类表示一个人,包含了name
和age
两个成员变量以及sayHello()
方法。在Main
类的main()
方法中,创建了一个Person
类型的对象p
。JVM在创建p
对象时,首先为其分配了一块内存空间,并将name
和age
成员变量初始化为默认值(null
和0
),随后调用了Person
类的构造函数Person("Tom", 20)
,将name
和age
设置为指定值。
Java虚拟机之类加载机制及双亲委派模型
Java中的类加载顺序是由Java虚拟机的类加载器完成的。类加载器会将类文件加载到内存中,并转换为Java虚拟机可识别的格式。在Java中,类加载器采用了双亲委派模型。
双亲委派模型的核心思想是:当一个类加载器收到加载请求时,首先将请求委托给父类加载器进行加载,只有在父类加载器找不到类时才由当前类加载器进行加载。这样可以避免重复加载,并保证加载的类能被所有类加载器共享。
例子说明
public class Main {
public static void main(String[] args) {
MyClassLoader classLoader = new MyClassLoader();
try {
Class<?> clazz = classLoader.loadClass("Worker");
System.out.println("class loaded by " + clazz.getClassLoader());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
public class MyClassLoader extends ClassLoader {
@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
if (name.equals("Worker")) {
byte[] bytes = loadClassDataFromNetwork();
return defineClass(name, bytes, 0, bytes.length);
}
return super.loadClass(name);
}
private byte[] loadClassDataFromNetwork() {
// 从网络中加载类文件并转换为二进制数组
return null;
}
}
在这个例子中,自定义了一个MyClassLoader
类加载器,并重写了loadClass()
方法。在loadClass()
方法中,当要加载的类是Worker
时,加载类文件,并调用defineClass()
方法将其转换为Java虚拟机可识别格式的二进制流,并生成相应的Class
对象。随后,在main()
方法中,创建了一个MyClassLoader
实例,并调用其loadClass()
方法来加载Worker
类。由于Worker
类不在当前类加载器的搜索路径中,因此MyClassLoader
会将其委托给父类加载器进行加载。由于父类加载器依然找不到Worker
类,因此最后由MyClassLoader
进行加载。在加载完成后,输出了Worker
类的加载器信息,验证了双亲委派模型的正确性。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java虚拟机之对象创建过程与类加载机制及双亲委派模型 - Python技术站