Skip to content

Instantly share code, notes, and snippets.

@martijndwars
Created March 16, 2020 13:33
Show Gist options
  • Save martijndwars/a356368586b8304c9acc6e044e440909 to your computer and use it in GitHub Desktop.
Save martijndwars/a356368586b8304c9acc6e044e440909 to your computer and use it in GitHub Desktop.
Generics: why does this work?
import java.util.ArrayList;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
ArrayConstructor<Integer> inner = new ArrayConstructor<Integer>();
inner.add("Foo");
inner.add("Bar");
inner.add("Baz");
inner.add(42);
System.out.println(Arrays.toString(inner.materialize()));
System.out.println("Done");
}
public static class ArrayConstructor<T> {
public ArrayList<T> instance;
public ArrayConstructor() {
instance = new ArrayList<T>();
}
public void add(Object value) {
instance.add((T) value);
}
public T[] materialize() {
return (T[]) instance.toArray();
}
}
}
@xicalango
Copy link

compiling with -Xlint:unchecked gives you this btw:

Main.java:31: warning: [unchecked] unchecked cast
      instance.add((T) value);
                       ^
  required: T
  found:    Object
  where T is a type-variable:
    T extends Object declared in class ArrayConstructor
Main.java:35: warning: [unchecked] unchecked cast
      return (T[]) instance.toArray();
                                   ^
  required: T[]
  found:    Object[]
  where T is a type-variable:
    T extends Object declared in class ArrayConstructor
2 warnings

@xicalango
Copy link

ah one last thing: the bytecode for some methods in ArrayConstructor:

// aweld: no cast here at all
  public void add(java.lang.Object); 
    Code:
       0: aload_0
       1: getfield      #4                  // Field instance:Ljava/util/ArrayList;
       4: aload_1
       5: invokevirtual #6                  // Method java/util/ArrayList.add:(Ljava/lang/Object;)Z
       8: pop
       9: return

// aweld: here we just have a checkcast for "object array"
  public T[] materialize();
    Code:
       0: aload_0
       1: getfield      #4                  // Field instance:Ljava/util/ArrayList;
       4: invokevirtual #7                  // Method java/util/ArrayList.toArray:()[Ljava/lang/Object;
       7: checkcast     #8                  // class "[Ljava/lang/Object;"
      10: areturn

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment