假设我们有一个如下所示的类加载层次结构:
Bootstrap
|
System
|
Custom
假设Custom
Classloader用于加载类com.example.SomeClass
。它检查System
类加载器是否可以加载它,再次检查Bootstrap
类加载器是否可以加载它。由于两者都不能,com.example.SomeClass
所以由Custom
classloader加载。
任何com.example.SomeClass
依赖的类都是一样的。我相信我了解这一过程。
我不明白为什么Custom
会尝试首先加载com.example.SomeClass
。在Java应用程序中如何选择当前的类加载器?
如您所知,默认情况下,Java使用引导类加载器和系统类加载器。第一个负责加载引导程序类(其类路径包含rt.jar之类的工件),第二个负责保存应用程序的类路径。通常,在您的环境变量中定义或在JVM中给定的类路径开始使用该-cp
参数。
仅当发生以下两种情况之一时,com.example.SomeClass
您的自定义类加载器Custom
才会加载该类:在启动时定义自定义类加载器以用作系统类加载器,或者在运行时通过该类显式加载类。
关于每个选项的更多信息:
-Djava.system.class.loader=my.tests.classloaders.Custom
在这种情况下,发生的情况是该类JVM实例中应用程序中的 所有 类实际上将由Custom
类加载器加载。
ClassLoader classloader = new CustomClassLoader();
Class someClass = classloader.loadClass("com.example.SomeClass");
就像@Noofiz在他的回答中所说,一旦您加载了一个类,就需要通过关联的类加载器来加载所有需要且尚未加载的引用类。因此,如果使用自定义类加载器加载一个类,则所有引用的类也将通过该类加载。加载所有类时,您可以执行任何操作,记录正在加载的类,委托给父类加载器,自己加载这些类…
通常,实现自定义类加载器的最佳方法是使用您提到的委托模型。这是因为实际上,一个类不仅由类的字节码定义,而且还由其类加载器定义,这意味着
由两个不同的类加载器加载的类将不是同一类 。
这意味着当您的自定义类加载器委托给它的父类时,您要确保该类可以在 更大范围内使用 。在大多数情况下,这将是您想要的,但并非总是如此。
如果出于某种原因要隔离类,则可以以其他方式实现自定义类加载器。首先,它尝试自行加载该类,并且仅在找不到该类(或者是JVM系统类或您可能要跳过的任何其他类)的情况下,才将其委托给其父类。例如,Web应用程序容器以这种方式工作,从而允许重新部署上下文(基本上它们会丢弃类加载器,并创建一个新的类加载器来再次加载所有内容),并在Web应用程序之间实现完全的类隔离。
正如我已经说过的,处理类加载绝不是一件容易的事,或者您真的知道自己在做什么,或者您肯定会遇到一些奇怪的伏都教麻烦。
也许已经太离题了,但是如果您想更多 地 了解类加载器和隔离的知识,可以查看一个名为classworlds的旧开源项目。即使这个项目很旧,我还是建议您这样做,因为它是一个很小的项目,里面充满了有关类加载机制的知识,您可以轻松地了解这些知识。
我有两个表和 names表有以下列表: -男性姓名从nameID 1到nameID 10 -女性姓名从nameID 11到nameID 21 -两者都从nameID 23到nameID 31 性别表有三个属性: -女性 -男性 -两者 我正在使用引导选择选项,我想显示从nameID11到nameid21的名称,如果用户从gender选择选项中选择女性,等等,这是可能的吗?我看到其他帖子,我注意到他
问题内容: 有没有比以下更有效的方法: 问题答案: 在查询中使用PARTITION(partitionN)语法应该非常少见。 通常,您只想为分区键指定值,并允许Oracle执行分区消除。例如,如果您的表每天根据TRANSACTION_DATE进行分区 将从今天的分区,昨天的分区和前一天的分区中选择所有数据。
我正在用Selenium解析一个网站。 我需要在隐藏类中选择一个选项。该部分的Html代码: 我尝试像往常一样通过选择功能选择一个选项: 我得到了这个错误消息:ElementNotInteractiableException:message:element notinteractiable:element当前不可见,可能无法操作。 完整的错误消息: 我想,我应该先在选项下运行一个脚本,但我不知道该
在这里json 如何使用库boost获得更新的值4? 我知道怎么取这样一个“ts”值。但是我不明白如何取两个括号的值
我将从@Embeddeble Class Certification中选择所有列。但我不能选择它。如何选择可嵌入类。 @嵌入式类认证 如果运行ResultService,则会出现以下异常: 原因:Java . lang . illegalargumentexception:在EntityManager中创建查询时出现异常:异常描述:编译查询时出错[从认证c中选择c]。未知的实体类型[认证]。 如何
问题内容: 在C#中将是这样的: Linq-To-Sql将其转换为以下T-SQL代码: 但是它与MySQL不兼容。 问题答案: 当我写 有用。在其他RDBMS中,IIRC这样的语句是不可能的,因为不属于任何组合键的不属于分组键的列就被引用了。 这种“怪癖”的行为与我想要的行为非常接近。所以我用它来获得想要的结果: