相关疑难解决方法(0)

如何选择Classloader?

动机

假设我们有一个类加载层次结构,如下所示:

 Bootstrap
     |
  System
     |
  Custom
Run Code Online (Sandbox Code Playgroud)

假设CustomClassloader用于加载类com.example.SomeClass.它检查System类加载器是否可以加载它,再次检查Bootstrap类加载器是否可以加载它.既然两者都不能,com.example.SomeClass则由Customclassloader加载.

任何com.example.SomeClass依赖的类都是一样的.我相信我理解这个过程.

我不明白为什么Custom会尝试首先加载com.example.SomeClass.如何在Java应用程序中选择当前的类加载器?

java classloader

9
推荐指数
1
解决办法
1595
查看次数

Classloader如何确定它可以加载哪些类?

我正在阅读Java中的类加载.

动机

假设我们有一个看起来像这样的类加载器层次结构,我理解加载的类First不能由加载的类直接访问Second(反之亦然).

 Bootstrap
     |
   System
     |
   Common
   /    \
First Second
Run Code Online (Sandbox Code Playgroud)

我也理解一个类加载器检查它的父类加载器是否可以加载该类,如果是这种情况,则将加载委托给它的父类.

类加载器如何确定它们是否可以加载某个给定的类?

java classloader

4
推荐指数
1
解决办法
332
查看次数

字节码注入在哪里发生?

动机

我有一个SomeObject.java文件:

class SomeObject {
   String name;
}
Run Code Online (Sandbox Code Playgroud)

编译它会创建一个包含字节码的SomeObject.class文件.

0xCAFEBABE...
Run Code Online (Sandbox Code Playgroud)

如果我们在JVM上使用SomeObject,它将由当前的类加载器加载,并且一切正常.

现在让我们假设我想要一些动态代码生成.我可以写我的自定义注释

@Target(ElementType.TYPE)
public @interface Data {
   ...
}
Run Code Online (Sandbox Code Playgroud)

并将其作为修饰符添加到类声明中:

@Data
class SomeObject {
   String name;
}
Run Code Online (Sandbox Code Playgroud)

我也可以在运行时保留它@Retention(RetentionPolicy.RUNTIME):

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Data {
   ...
}
Run Code Online (Sandbox Code Playgroud)

用于字节码注入的注释在哪里?在使用适当的运行时保留注释加载类时,类加载器是否会注入字节码,如下图所示:

source -(compile)-> bytecode -(classloader bytecode injection)-> injected bytecode -(classloading)-> JVM loaded bytecode   
Run Code Online (Sandbox Code Playgroud)

annotations bytecode classloader bytecode-manipulation

2
推荐指数
1
解决办法
1691
查看次数