Why does this exceed the 65535 byte limit in Java constructors and static initializers?
Disclaimer: I realize that I can generate this at Java runtime. When testing some code, I need a very special case I found a different way, so now it's just a curiosity than any practical curiosity
I've tried to take the following as a static field, as an instance field, and initialize it directly in the constructor Every time eclipse informs me that "the code of the constructor testdata () exceeds the 65535 byte limit" or "the code of the static initializer exceeds the 65535 byte limit"
There are 10000 integers If each int is 4 bytes (32 bits), wouldn't it be 40000 bytes? In addition to just building the data of the array, is there any more overhead of 250000 bytes?
This data is generated using this small Python:
#!/usr/bin/python import random; print "public final int[] RANDOM_INTEGERS = new int[] {"; for i in range(1,10000): print str(int(random.uniform(0,0x7fffffff))) + ","; print "};";
This is a small sample:
public final int[] RANDOM_INTEGERS = new int[] { 963056418,460816633,1426956928,1836901854,334443802,721185237,488810483,1734703787,1858674527,112552804,1467830977,1533524842,1140643114,1452361499,716999590,652029167,1448309605,1111915190,1032718128,1194366355,112834025,419247979,944166634,205228045,1920916263,1102820742,1504720637,757008315,67604636,1686232265,597601176,1090143513,205960256,1611222388,1997832237,1429883982,1693885243,1987916675,159802771,1092244159,1224816153,1675311441,1873372604,1787757434,1347615328,1868311855,1401477617,508641277,1352501377,1442984254,1468392589,1059757519,1898445041,1368044543,513517087,99625132,1291863875,654253390,169170318,2117466849,1711924068,564675178,208741732,1095240821,1993892374,87422510,1651783681,1536657700,1039420228,674134447,1083424612,2137469237,1294104182,964677542,1506442822,1521039575,64073383,929517073,206993014,466196357,1139633501,1692533218,1934476545,2066226407,550646675,624977767,1494512072,1230119126,1956454185,1321128794,2099617717,//.... to 10,0000 instances
Solution
The following is the bytecode for initializing the array with {1000001100002100003}:
5 iconst_3 6 newarray int [10] 8 dup 9 iconst_0 10 ldc <Integer 1000001> [12] 12 iastore 13 dup 14 iconst_1 15 ldc <Integer 1000002> [13] 17 iastore 18 dup 19 iconst_2 20 ldc <Integer 1000003> [14] 22 iastore 23 putfield net.jstuber.test.TestArrayInitializingConstructor.data : int[] [15]
So for this small array, each element needs 5 bytes of Java bytecode For larger arrays, the array index and the index in the constant pool will use 3 bytes for most elements, resulting in 8 bytes per array element Therefore, for 10000 elements, you have to expect about 80 KB of bytecode
The code for initializing a large array with a 16 bit index is as follows:
2016 dup 2017 sipush 298 2020 ldc_w <Integer 100298> [310] 2023 iastore 2024 dup 2025 sipush 299 2028 ldc_w <Integer 100299> [311]