1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import org.checkerframework.checker.interning.qual.Interned;
public class Generics {
void testGenerics() {
Map<String, @Interned String> map = null;
map = new HashMap<>();
String a = new String("foo");
@Interned String b = "bar";
String notInterned;
@Interned String interned;
map.put(a, b); // valid
// :: error: (argument.type.incompatible)
map.put(b, a); // error
notInterned = map.get(a); // valid
interned = map.get(b); // valid
Collection<@Interned String> internedSet;
Collection<String> notInternedSet;
notInternedSet = map.keySet(); // valid
// :: error: (assignment.type.incompatible)
internedSet = map.keySet(); // error
// :: error: (assignment.type.incompatible)
notInternedSet = map.values(); // error
internedSet = map.values(); // valid
HashMap<@Interned String, Vector<@Interned Integer>> all_nums = new HashMap<>();
Vector<@Interned Integer> v = all_nums.get("Hello");
}
// The cells aren't interned, but their contents are
class CellOfImm<T extends @Interned Object> {
T value;
boolean equals(CellOfImm<T> other) {
return value == other.value; // valid
}
}
List<@Interned String> istrings = new ArrayList<>();
List<String> strings = new ArrayList<>();
@Interned String istring = "interned";
String string = new String("uninterned");
void testGenerics2() {
istrings.add(istring);
// :: error: (argument.type.incompatible)
istrings.add(string); // invalid
strings.add(istring);
strings.add(string);
istring = istrings.get(0);
string = istrings.get(0);
// :: error: (assignment.type.incompatible)
istring = strings.get(0); // invalid
string = strings.get(0);
}
void testCollections() {
Collection<String> strings = Collections.unmodifiableCollection(new ArrayList<String>());
Collection<@Interned String> istrings =
Collections.unmodifiableCollection(new ArrayList<@Interned String>()); // valid
}
class MyList extends ArrayList<@Interned String> {
// Correct return value is Iterator<@Interned String>
// :: error: (override.return.invalid)
public Iterator<String> iterator() {
return null;
}
}
// from VarInfoAux
static class VIA {
private static VIA theDefault = new VIA();
private Map<@Interned String, @Interned String> map;
void testMap() {
Map<@Interned String, @Interned String> mymap;
mymap = theDefault.map;
mymap = new HashMap<@Interned String, @Interned String>(theDefault.map);
mymap = new HashMap<>(theDefault.map);
}
}
// type inference
<T> T id(T m, Object t) {
return m;
}
void useID() {
String o = id("m", null);
}
// raw types again
void testRawTypes() {
ArrayList lst = null;
Collections.sort(lst);
}
public static class Pair<T1, T2> {
public T1 a;
public T2 b;
public Pair(T1 a, T2 b) {
this.a = a;
this.b = b;
}
/** Factory method with short name and no need to name type parameters. */
public static <A, B> Pair<A, B> of(A a, B b) {
return new Pair<>(a, b);
}
}
static class C<T> {
T next1;
// @skip-test
// This test might be faulty
// private Pair<T,T> return1() {
// Pair<T,T> result = Pair.of(next1, (T)null);
// return result;
// }
}
}
|