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, @Interned String>(); 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<@Interned String, Vector<@Interned Integer>>(); 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<@Interned String>(); List<String> strings = new ArrayList<String>(); @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); } } // 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>(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; // } } }