Community
Participate
Working Groups
This was raised against AspectJ but I think it is a JDT issue. This snippet of code: import java.lang.Object; import java.util.*; public class GenericVarargsBug { public static void main(String... args) { List<byte[]> sth = new ArrayList<>(); sth.add(new byte[]{23, 23}); isItWorking(sth.get(0)); } private static void isItWorking(Object... os) { System.out.println("yes"); } } Compiles with javac (1.8 u45) and runs, printing 'yes'. When compiled with Mars (4.5.0) it compiles OK but fails when you run it: Exception in thread "main" java.lang.ClassCastException: [B cannot be cast to [Ljava.lang.Object; at GenericVarargsBug.main(GenericVarargsBug.java:9) I haven't checked if it is addressed in JDT master.
The same behavior can be observed in versions 3.1.2 up-to and including HEAD (i.e., all versions that accept generics). The compiler can't decide whether or not byte[] is compatible with Object[]. Cast to Object[] indicates we are attempting a fixed-args invocation, interpreting the varargs arg as an array arg. But then the value casted to Object[] is wrapped in a new Object[] (for a true varargs invocation), perhaps because the compiler now remembers that byte[] is *not* compatible with Object[]. Typecheck seems to be correct, just a dangling conversion messes things up. Interesting mess actually, which probably went undetected through all these years, because mixing generics and arrays isn't really the style that is taught in school ;P
This sounds quite similar (albeit a different scenario) to the following - I wasn't sure whether to raise a new bug or to comment. The following test harness fails on Test 2 with the error: Exception in thread "main" java.lang.ClassCastException: java.lang.Object cannot be cast to [Ljava.lang.Object; at test.Test.main(Test.java:10) Test Harness: public class Test { public static void main(final String[] args) { final Object test1 = getParamaterisedObject(); System.out.println("Test A result: " + varargTest(test1)); System.out.println("Test B result: " + varargTest(getParamaterisedObject())); } public static int varargTest(final Object... o) { return 1; } @SuppressWarnings("unchecked") public static <T> T getParamaterisedObject() { return (T) new Object(); } } Both tests run on 4.4.2, but the second test errors on 4.5.1. Cheers, Ron.
Bulk move out of 4.8
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. As such, we're closing this bug. If you have further information on the current state of the bug, please add it and reopen this bug. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie.
The bug still persists in Version 4.15: Exception in thread "main" java.lang.ClassCastException: class [B cannot be cast to class [Ljava.lang.Object; ([B and [Ljava.lang.Object; are in module java.base of loader 'bootstrap') at Test.main(Test.java:8)
Stephan, I am not a JLS spec expert. Eclipse compiler adds a checkcast when invoking the isWorking method. javac doesn't add that checkcast call. I think it is worth investigating why this checkcast call is inserted. FYI here are the bytecodes: 0: new #16 // class java/util/ArrayList 3: dup 4: invokespecial #18 // Method java/util/ArrayList."<init>":()V 7: astore_1 8: aload_1 9: iconst_2 10: newarray byte 12: dup 13: iconst_0 14: bipush 23 16: bastore 17: dup 18: iconst_1 19: bipush 23 21: bastore 22: invokeinterface #19, 2 // InterfaceMethod java/util/List.add:(Ljava/lang/Object;)Z 27: pop 28: iconst_1 29: anewarray #3 // class java/lang/Object 32: dup 33: iconst_0 34: aload_1 35: iconst_0 36: invokeinterface #25, 2 // InterfaceMethod java/util/List.get:(I)Ljava/lang/Object; 41: checkcast #29 // class "[Ljava/lang/Object;" 44: aastore 45: invokestatic #31 // Method isItWorking:([Ljava/lang/Object;)V 48: return so javac doesn't add the checkcast at pc 41. Everything else is the same. If I code what is actually done under the cover, we don't generate the checkcast anymore. Object[] r = new Object[1]; r[0] = sth.get(0); isItWorking(r); Reopening.
seems to be some problem of communication between resolve and generateCode. I acknowledged above that this is probably a bug, but for me this is not high priority. Independently of this bug I would strongly recommend against mixing generics plus arrays plus varargs. There's actually a quite reasonable workaround to disambiguate the array-vs-varargs conflict: isItWorking((Object)sth.get(0)); Smth like this is always a good idea when passing an array as a single element into a varargs method.
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant. -- The automated Eclipse Genie.