Created
March 16, 2020 13:33
-
-
Save martijndwars/a356368586b8304c9acc6e044e440909 to your computer and use it in GitHub Desktop.
Generics: why does this work?
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} | |
} |
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
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
this compiles with:
but running gives:
note how "Foo" still prints, although it would have wrong type here as well.
in the bytecode: