Last active
October 31, 2016 09:54
-
-
Save matklad/ede24faeb2a1bed85d8251fb9e9a169f to your computer and use it in GitHub Desktop.
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
package org.rust; | |
import java.util.ArrayList; | |
import java.util.List; | |
public class Main { | |
private static class Base { | |
} | |
private static class Derived extends Base { | |
void foo() { | |
} | |
} | |
public static void main(String[] args) { | |
// covariantArray(); | |
covariantGenericArray(); | |
} | |
static void covariantArray() { | |
// Arrays in Java are covariant, which is type unsound. | |
// So, assignments to array elements are checked at | |
// runtime to prevent type errors. | |
Derived[] xs = {new Derived()}; | |
unsafe1(xs); | |
} | |
static void unsafe1(Base[] xs) { | |
// This assignment is type unsound, but it's checked at runtime, | |
// so this is moderately acceptable. | |
xs[0] = new Base(); // ArrayStoreException! | |
} | |
static void covariantGenericArray() { | |
// Generics use type erasure. This is nice by itself, | |
// (no C++ code bloat), but interacts badly with | |
// covariant arrays, because run time checks do not work. | |
// Arrays are to blame, of course, but still... | |
List<Derived>[] bad = new List[1]; | |
unsafe2(bad); | |
List<Derived> listOfBaseActually = bad[0]; | |
System.out.println(listOfBaseActually.get(0)); | |
// Kaboom! There is no `foo`! | |
listOfBaseActually.get(0).foo(); | |
} | |
static void unsafe2(List<? extends Base>[] xs) { | |
ArrayList<Base> bases = new ArrayList<Base>(); | |
bases.add(new Base()); | |
// This assignment violates type safety. | |
// However it is not checked at runtime, because at run time | |
// List<Base> and List<Derived> have exactly the same type. | |
xs[0] = bases; // No exception here :( | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment