Java - 混合类型容器(非泛型 class)是否可以在没有未经检查的转换的情况下使用?
Java - is mixed type container (non-generic class) possible without unchecked cast?
我正在尝试制作一个简单的存储 class,它将存储不同的 classes 实例。我设法做到的唯一几乎正确的方法是使用未经检查的类型转换。
HashSet<T> result = (HashSet<T>) storage.get(s);
是否可以在不进行未经检查的转换和不使 class 泛型 (class Storage<T> { }
) 的情况下完成?
import java.util.*;
import org.junit.*;
class Tests {
@Test
public static void main (String[] args) {
Storage storage = new Storage();
HashSet<Child1> child1Set = storage.get("child1");
HashSet<Child1> duplicateChild1Set = storage.get("child1");
Assert.assertNotNull(child1Set);
Assert.assertSame(child1Set, duplicateChild1Set);
HashSet<Child2> child2Set = storage.get("child2");
Assert.assertNotNull(child2Set);
Assert.assertNotSame(child1Set, child2Set);
}
}
class Storage {
public Map<String, HashSet<? extends Parent>> storage = new HashMap<>();
public <T extends Parent> HashSet<T> get(String s) {
HashSet<T> result = (HashSet<T>) storage.get(s);
if (result == null) {
result = new HashSet<>();
storage.put(s, result);
}
return result;
}
}
class Parent { }
class Child1 extends Parent { }
class Child2 extends Parent { }
您可以使用 Class
个对象作为键,而不是 String
个对象。这是一个简短的例子。为简单起见,我没有包括 extends Parent
- 你可以把它们放回去。
public final class Storage {
private final Map<Class<?>, Set<?>> storage = new HashMap<>();
public <T> Set<T> get(Class<T> s) {
Set<T> result = (Set<T>) storage.get(s); // Unchecked cast
if (result == null) {
result = new HashSet<>();
storage.put(s, result);
}
return result;
}
}
像这样消除混合类型容器中未经检查的转换是不可能的。无法指定如果键的类型为 Class<T>
,则值的类型为 Set<T>
。但是,只要 Storage
class 的用户不忽略任何类型安全警告,这就是完全类型安全的。
要使用 class 你可以做 storage.get(Double.class).add(4.2);
,例如。
我正在尝试制作一个简单的存储 class,它将存储不同的 classes 实例。我设法做到的唯一几乎正确的方法是使用未经检查的类型转换。
HashSet<T> result = (HashSet<T>) storage.get(s);
是否可以在不进行未经检查的转换和不使 class 泛型 (class Storage<T> { }
) 的情况下完成?
import java.util.*;
import org.junit.*;
class Tests {
@Test
public static void main (String[] args) {
Storage storage = new Storage();
HashSet<Child1> child1Set = storage.get("child1");
HashSet<Child1> duplicateChild1Set = storage.get("child1");
Assert.assertNotNull(child1Set);
Assert.assertSame(child1Set, duplicateChild1Set);
HashSet<Child2> child2Set = storage.get("child2");
Assert.assertNotNull(child2Set);
Assert.assertNotSame(child1Set, child2Set);
}
}
class Storage {
public Map<String, HashSet<? extends Parent>> storage = new HashMap<>();
public <T extends Parent> HashSet<T> get(String s) {
HashSet<T> result = (HashSet<T>) storage.get(s);
if (result == null) {
result = new HashSet<>();
storage.put(s, result);
}
return result;
}
}
class Parent { }
class Child1 extends Parent { }
class Child2 extends Parent { }
您可以使用 Class
个对象作为键,而不是 String
个对象。这是一个简短的例子。为简单起见,我没有包括 extends Parent
- 你可以把它们放回去。
public final class Storage {
private final Map<Class<?>, Set<?>> storage = new HashMap<>();
public <T> Set<T> get(Class<T> s) {
Set<T> result = (Set<T>) storage.get(s); // Unchecked cast
if (result == null) {
result = new HashSet<>();
storage.put(s, result);
}
return result;
}
}
像这样消除混合类型容器中未经检查的转换是不可能的。无法指定如果键的类型为 Class<T>
,则值的类型为 Set<T>
。但是,只要 Storage
class 的用户不忽略任何类型安全警告,这就是完全类型安全的。
要使用 class 你可以做 storage.get(Double.class).add(4.2);
,例如。