Caused by: java.lang.ClassCastException: [I cannot be cast to java.util.List.Initially, I was confused by seeing the sentence "I cannot be cast to..." However, it turns out that it should be read as:
"[I" cannot be cast to "java.util.List"In this article, we will look at the class name (i.e., "[I") used in the class file.
What Is "[I"?
"[I" means array of "ints." If you use jrcmd to generate a heap histogram,[1] you will see the following contents:
--------- Detailed Heap Statistics: ---------
30.0% 65027k 672176 -1k [C
10.2% 22119k 943754 -2k java/lang/String
10.0% 21592k 183036 -3k [Ljava/lang/Object;
4.7% 10185k 434587 +0k java/util/HashMap$Entry
4.7% 10114k 27029 -1254k [B
4.5% 9783k 111539 +0k [Ljava/util/HashMap$Entry;
1.9% 4075k 34777 +0k java/lang/Class
1.9% 4058k 86590 +0k java/util/HashMap
1.6% 3448k 147156 +0k javax/management/ObjectName$Property
1.2% 2593k 82994 +0k java/util/LinkedHashMap$Entry
1.1% 2398k 76765 +0k java/util/concurrent/ConcurrentHashMap$Segment
1.0% 2215k 9311 +0k [I
0.9% 1975k 18469 +0k [J
Besides "[I", we also find other array's class names:
- [C
- [B
- [J
Array Representation[2]
In Java, arrays are full-fledged objects. Like objects, arrays are always stored on the heap. Also, multi-dimensional arrays are represented as arrays of arrays.
Arrays have a Class instance associated with their class, just like any other object. All arrays of the same dimension and type have the same class. The length of an array (or the lengths of each dimension of a multidimensional array) does not play any role in establishing the array's class. For example, an array of three ints has the same class as an array of three hundred ints. The length of an array is considered part of its instance data.
The name of an array's class has one open square bracket for each dimension plus a letter or string representing the array's type. For example, the class name for an array of ints is "[I". The class name for a three-dimensional array of bytes is "[[[B". The class name for a two-dimensional array of Objects is "[[Ljava.lang.Object". Read [3] for more details of this naming convention for array classes.
Conclusions
This exception
java.lang.ClassCastException: [I cannot be cast to java.util.List
while (iter.hasNext())
{
key = iter.next();
val = (List) mEDefToVOAttrsMap.get(key); <=== this line threw the Exception
The object returned from get() method was created in this way:
iArr = new int[val.size()];
This bug was exposed when we switched from JDK 6 to 7 in our tests. Maybe due to security enforcements or other reasons, JDK 7 provides more runtime checking than JDK 6 does. Therefore, this hidden bug has been revealed.
To conclude:
The compiler is not backwards compatible[4] because bytecode generated with JDK 7 won't run in Java 1.6 VM (unless compiled with the -target 1.6 flag[5]). But the JVM is backwards compatible, as it can run older bytecodes.
References
- Diagnosing OutOfMemoryError or Memory Leaks in JRockit (Xml and More)
- Array Representation (The Java Virtual Machine)
- The class File Format
- Is JDK “upward” or “backward” compatible?
- Cross-Compilation Options
- Java Products: All About Versions (Xml and More)
ReplyDeletebegumzarakhan.blogspot.com
http://onlineproblemsolution.com/vashikaran-specialist-in-the-world/