2

如果代码调用new int[0][0],条目[[I 将被放入常量池表中。类似的条目将放置在更高维的数组中。

但是,如果代码调用 new int[0],常量池表中将不会出现任何条目,就像 int 类型不会出现任何条目一样。

同样有趣的是,如果 codeit 调用 new String[0][0] 那么“[[java/lang/String;” 被添加到常量池表中,但是如果代码调用 new String() 或 new String[0],则只有“java/lang/String”被添加到常量池表中(没有 [ 或 ; 在第二种情况下) .

假设我的代码和 commons 的 BCEL API 都正确解析了池表,为什么常量池表中没有列出一维数组类型?

4

2 回答 2

4

有几个指令可用于创建数组:newarrayanewarraymultinewarray

newarray 创建一维原始数组,不需要任何常量池条目。

anewarray 接受一个类型并创建一个包含该类型元素的数组,初始化为 null。

multinewarray 采用要创建的数组的类型并自动用子数组填充元素。这使您可以使用单个指令创建多维数组。

其中,只有最后一个需要具有要创建的数组类型的 cp 条目。使用标准编译器,new int[x]使用第一个,new String[x]使用第二个,new int[x][y]或者new String[x][y]使用第三个。

于 2013-09-21T00:11:44.650 回答
1

我想看看你的测试用例。

我的(有限)研究表明,常量池中数组类名字符串的存在(或不存在)取决于是否声明了变量

例如:

public class Test {
    static int[] a = new int[0];  // constant pool entry for "[I"
}

public class Test2 {
    static Object a = new int[0];  // no constant pool entry for "[I"
}

正如@Antimony 的回答所指出的,用于创建数组的字节码指令需要基本类型的常量池条目或根本不需要常量池条目。

于 2013-09-21T00:23:42.523 回答