我刚刚开始学习Java的内部架构.我已经粗略地理解了类加载的概念,它在jvm运行时加载所需的类,ClassNotFoundException在没有找到类时抛出,特定的类加载器加载类引用的类.
有人可以清楚地解释类加载的流程,即下面的示例Java代码中的引导类加载和用户定义的类加载的顺序.
import java.io.File;
public class Sample
{
public static void main(String[] args)
{
String fileName = "sample";
File file = new File(fileName);
file.isFile();
}
}
Run Code Online (Sandbox Code Playgroud)
我还从一个参考资料中学到了" classloader维护它加载的类的名称空间".通过名称空间,这是否意味着类的文字名称?也有人可以解释一下这个含义/优点吗?
San*_*osh 56
您将按Sample如下方式运行您的课程
> java Sample
对于小魔术,检查-verbose:class选项的输出,你会看到大量的以下行..
[Opened C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded java.lang.Object from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded java.io.Serializable from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded java.lang.Comparable from C:\jdk1.6.0_14\jre\lib\rt.jar]
.
.
.
.
.
.
[Loaded java.security.cert.Certificate from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded Sample from file:/D:/tmp/]
[Loaded java.lang.Shutdown from C:\jdk1.6.0_14\jre\lib\rt.jar]
[Loaded java.lang.Shutdown$Lock from C:\jdk1.6.0_14\jre\lib\rt.jar]
Run Code Online (Sandbox Code Playgroud)
\jre\lib\rt.jar在类加载Bootstrap器(或Primordial)加载类之前,您会看到一堆类被加载.这些是运行任何由Bootstrap加载的Java程序的先决条件.
另一组jar由Extension类加载器加载.在这个特定的例子中,不需要lib中的任何类,\jre\lib\ext因此它没有被加载.但Extension类加载器专门分配了从扩展lib加载类的任务.
编辑:除了标准平台java类之外,Sun/Oracle还提供了一组用于扩展平台核心API的jar .放置在扩展lib文件夹中的jar自动放在类路径中,因此不需要显式地包含在类路径中.这是关于同一主题的好官方文章.
最后,在Bootstrap和Extension完成加载后,您的类Sample由Application类加载器加载.
Nar*_*hai 50
每当启动新的JVM时,引导类加载器都负责将关键Java类(从java.lang包)和其他运行时类首先加载到内存中.引导类加载器是所有其他类加载器的父级.因此,它是唯一没有父母的人.
接下来是扩展类加载器.它有bootstrap类加载器作为父类,负责从.jar保存在java.ext.dirs路径中的所有文件加载类- 无论JVM的类路径如何,它们都可用.
从开发人员的角度来看,第三个也是最重要的类加载器是系统类路径类加载器,它是扩展类加载器的直接子代.它从CLASSPATH环境变量,java.class.path系统属性或-classpath命令行选项指定的目录和jar文件中加载类.

ClassLoader命名空间
在Java中,使用唯一标识的类,
ClassLoader + Class因为同一个类可以由两个不同的类加载器加载.
Class A loaded by ClassLoader A != Class A loaded by ClassLoader B
Run Code Online (Sandbox Code Playgroud)
它有什么用?
为不同的类加载器定义不同的保护和访问策略很有帮助.举一个使用不同类加载器加载的applet的例子,你不希望第三方应用程序访问你的资源.因此,对于安全性,维护不同名称空间非常重要.
Ani*_*kur 11
JVM在加载类的permgen区域中维护一个运行时池.每当引用类时,默认类加载器都会在类路径中找到该类并将其加载到此池中.这不是特定于JDK中提供的用户定义的类或类.引用类时,它将加载到内存中.
由ClassLoader加载的类内部存储在ClassLoader实例中
// The classes loaded by this class loader. The only purpose of this table
// is to keep the classes from being GC'ed until the loader is GC'ed.
private final Vector<Class<?>> classes = new Vector<>();
Run Code Online (Sandbox Code Playgroud)
当需要将类添加到内存后,调用以下函数:
// Invoked by the VM to record every loaded class with this loader.
void addClass(Class c) {
classes.addElement(c);
}
Run Code Online (Sandbox Code Playgroud)
找到了有关类加载器如何工作的有用图表.

| 归档时间: |
|
| 查看次数: |
39879 次 |
| 最近记录: |