I'm trying to compile code such as the below using JDK1.5.0_u22. I get two compile errors (further below). It works fine with JDK1.6.0u30, but my project is restricted to Java 5. It also works fine if I repleace float with the wrapper class Float. Does anyone know what's going on here? A simple bug or some general restriction on the use of primitive array types in generic situations?
import java.util.*;
public class A {
public static void main(String[] args) {
List<float[]> list = Arrays.asList(new float[1], new float[3]);
float[] key = new float[2];
int index = Collections.binarySearch(list, key, new Comparator<float[]>() {
public int compare(float[] f1, float[] f2) {
return f1.length - f2.length;
}
});
System.out.println(index);
}
}
Compile errors:
C:\Users\mravn\Desktop>"c:\Program Files\Java\jdk1.5.0_22"\bin\javac A.java
A.java:4: incompatible types
found : java.util.List<<nulltype>[]>
required: java.util.List<float[]>
List<float[]> list = Arrays.asList(new float[1], new float[3]);
^
A.java:6: cannot find symbol
symbol : method binarySearch(java.util.List<float[]>,float[],<anonymous java.util.Comparator<float[]>>)
location: class java.util.Collections
int index = Collections.binarySearch(list, key, new Comparator<float[]>() {
^
2 errors
C:\Users\mravn\Desktop>
I'm going to give the answer for the 1st compiler error and keep digging to see if I can find the one for the 2nd compiler error...
Running the following by itself produces no errors using jdk1.5.0_22:
System.out.println(Arrays.asList(new float[1]).size());
Running this by itself...
System.out.println(Arrays.asList(new float[1], new float[3]).size());
produces this nasty compiler error...
An exception has occurred in the compiler (1.5.0_22). Please file a bug at the Java Developer Connection (http://java.sun.com/webapps/bugreport) after checking the Bug Parade for duplicates. Include your program and the following diagnostic in your report. Thank you.
java.lang.AssertionError: unexpected type: <nulltype>
at com.sun.tools.javac.tree.TreeMaker.Type(TreeMaker.java:531)
at com.sun.tools.javac.tree.TreeMaker.Type(TreeMaker.java:525)
at com.sun.tools.javac.comp.Lower.boxArgs(Lower.java:2510)
at com.sun.tools.javac.comp.Lower.visitApply(Lower.java:2420)
at com.sun.tools.javac.tree.Tree$Apply.accept(Tree.java:813)
at com.sun.tools.javac.comp.Lower.translate(Lower.java:1881)
at com.sun.tools.javac.comp.Lower.visitSelect(Lower.java:3019)
at com.sun.tools.javac.tree.Tree$Select.accept(Tree.java:987)
at com.sun.tools.javac.comp.Lower.translate(Lower.java:1881)
at com.sun.tools.javac.comp.Lower.visitApply(Lower.java:2474)
at com.sun.tools.javac.tree.Tree$Apply.accept(Tree.java:813)
at com.sun.tools.javac.comp.Lower.translate(Lower.java:1881)
at com.sun.tools.javac.comp.Lower.translate(Lower.java:1893)
at com.sun.tools.javac.comp.Lower.boxArgs(Lower.java:2517)
at com.sun.tools.javac.comp.Lower.visitApply(Lower.java:2420)
at com.sun.tools.javac.tree.Tree$Apply.accept(Tree.java:813)
at com.sun.tools.javac.comp.Lower.translate(Lower.java:1881)
at com.sun.tools.javac.tree.TreeTranslator.visitExec(TreeTranslator.java:227)
at com.sun.tools.javac.tree.Tree$Exec.accept(Tree.java:728)
at com.sun.tools.javac.comp.Lower.translate(Lower.java:1881)
at com.sun.tools.javac.tree.TreeTranslator.translate(TreeTranslator.java:54)
at com.sun.tools.javac.tree.TreeTranslator.visitBlock(TreeTranslator.java:145)
at com.sun.tools.javac.comp.Lower.visitBlock(Lower.java:2933)
at com.sun.tools.javac.tree.Tree$Block.accept(Tree.java:535)
at com.sun.tools.javac.comp.Lower.translate(Lower.java:1881)
at com.sun.tools.javac.tree.TreeTranslator.visitMethodDef(TreeTranslator.java:129)
at com.sun.tools.javac.comp.Lower.visitMethodDefInternal(Lower.java:2267)
at com.sun.tools.javac.comp.Lower.visitMethodDef(Lower.java:2186)
at com.sun.tools.javac.tree.Tree$MethodDef.accept(Tree.java:478)
at com.sun.tools.javac.comp.Lower.translate(Lower.java:1881)
at com.sun.tools.javac.comp.Lower.visitClassDef(Lower.java:1989)
at com.sun.tools.javac.tree.Tree$ClassDef.accept(Tree.java:434)
at com.sun.tools.javac.comp.Lower.translate(Lower.java:1881)
at com.sun.tools.javac.comp.Lower.translate(Lower.java:1901)
at com.sun.tools.javac.comp.Lower.translateTopLevelClass(Lower.java:3070)
at com.sun.tools.javac.main.JavaCompiler.compile(JavaCompiler.java:487)
at com.sun.tools.javac.main.Main.compile(Main.java:592)
So I followed the compilers advice and did some searching on Oracle's bug database and found the bug by searching for "java.lang.AssertionError: unexpected type: ". You can check it out here: Primitive arrays and varargs inference leads to crash in TreeMaker.Type(TreeMaker.java:531)
Using the Float wrapper class is the work around as you discovered.
EDIT - answer for 2nd compiler error
I believe the 2nd compiler error to be a bug and I've submitted it to the Bug Database
I was able to compile the following list, key and comparator by themselves with no compiler errors:
List<float[]> list=new ArrayList<float[]>();
list.add(new float[] {0.0f});
list.add(new float[] {1.0f});
float[] key = new float[2];
Comparator<float[]> c = new Comparator<float[]>() {
public int compare(float[] f1, float[] f2) {
return f1.length - f2.length;
}
};
When I try to run "Collections.binarySearch(list, key, c)" with them, I get the "cannot find symbol" error. If I change "float" to "Float", it compiles fine with both cases.
I believe that the list, key and comparator I posted above fulfills the binary search contract completely according to the Java 5 spec on it
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With