Java - 在没有未经检查的强制转换的情况下,混合类型容器(非泛型类)是否可能?

标签 java generics types casting unchecked

我正在尝试创建一个简单的存储类,它将存储不同的类实例。我设法做到的唯一几乎正确的方法是使用未经检查的类型转换。

HashSet<T> result = (HashSet<T>) storage.get(s);

可以在不进行未经检查的转换和不使类通用的情况下完成( 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 s。这是一个简短的例子。为了简单起见,我没有包括 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;
    }
}

不可能消除像这样的混合类型容器中未经检查的强制转换。无法指定 key 是否具有类型 Class<T> ,该值的类型为 Set<T> 。不过,只要Storage的用户类不会忽略任何类型安全警告,这是完全类型安全的。

要使用该类,您可以执行 storage.get(Double.class).add(4.2); ,例如。

关于Java - 在没有未经检查的强制转换的情况下,混合类型容器(非泛型类)是否可能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33985657/

相关文章:

C# 泛型和类型检查混淆

haskell - D 有 'newtype' 吗?

java - java中哪些数据类型可以支持10e+10000个数?

java - 新行\n 在 JButton.setText ("fnord\nfoo"中不起作用);

F Sharp 中的 List<int> 与 int 列表

Java 泛型接口(interface)返回泛型

delphi - Delphi中是否有一个可以用匿名函数调用的foreach泛型方法

java - 列出目录中与文件掩码(又名模式或 Glob)匹配的所有文件

java - 单击按钮时将图标添加到 ActionListener 中的 JLabel

java - Spring Boot 在存在 schema.sql 的情况下创建实体之前运行 data.sql