Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is wrong with using a primitive array as an actual type parameter in Java 5?

Tags:

java

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>
like image 253
mravn Avatar asked Jan 09 '12 15:01

mravn


1 Answers

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

like image 190
Zack Macomber Avatar answered Nov 04 '22 09:11

Zack Macomber