我对类加载的理解是一个类在第一次需要时被加载(以非常简单的方式放置).使用-verbose:class和Iterators类的修改版本运行以下示例,该类在调用其clinit时打印消息我观察到了一些我无法解释的内容:
public class IteratorsTest
{
public static void main(String[] args)
{
com.google.common.collect.Iterators.forArray(1, 2, 3);
}
}
(清理)输出如下:
[Loaded com.google.common.collect.Iterators from file:...]
[Loaded com.google.common.collect.Iterators$1 from file:...]
---------> Iterators
为什么在调用clinit之前加载Iterators $1?它只在临床中定义,不是吗?
static final UnmodifiableListIterator EMPTY_LIST_ITERATOR =
new UnmodifiableListIterator() {
...
}
这导致以下字节代码:
static ()V
L0
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "---------> Iterators clinit --------------"**
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
L1
NEW com/google/common/collect/Iterators$1
DUP
INVOKESPECIAL com/google/common/collect/Iterators$1. ()V
L2
PUTSTATIC com/google/common/collect/Iterators.EMPTY_LIST_ITERATOR : Lcom/google/common/collect/UnmodifiableListIterator;
为了让我更加困惑,我还有一个样本(太复杂了,无法在此处发布),其中与上面主要内容相同的代码行导致以下输出:
[Loaded com.google.common.collect.Iterators from file:...]
---------> Iterators
[Loaded com.google.common.collect.Iterators$1 from file:...]
这实际上也是我对简单测试程序的期望.
>有时可能首先执行诊所,有时首先加载匿名类的原因是什么?
>有没有办法跟踪JVM何时调用类的临时?类似于-verbose:class或-XX:TraceClassLoading等?