有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

从泛型类集合中进行java类型安全检索

我有一个通用容器,其中包含类型E的对象:

public class Container<E> {

    private final E e;

    public Container(E e) {
        this.e = e;
    }

    public E get() {
        return e;
    }
}

我有一个可以装各种容器的桶:

public class Bucket {
    private final Map<String, Container<?>> containers = new HashMap<>();

    public void put(String name, Container<?> container) {
        containers.put(name, container);
    }

    public Container<?> get(String name) {
        Container<?> container = containers.get(name);
        return container;
    }
}

我希望能够将容器(各种类型)放入桶中,并以类型安全的方式将其取回

    Container<Long> longs = new Container<>(100L);
    Container<String> strings = new Container<>("Hello");

    Bucket bucket = new Bucket();
    bucket.put("longs", longs);
    bucket.put("strings", strings);

但正如你所能看到的,我失去了类型安全:

   Container<?> longs1 = bucket.get("longs");
   Container<?> strings1 = bucket.get("strings");

我似乎不知道需要什么才能实现以下目标:

   Container<Long> longs1 = bucket.get("longs");
   Container<String> strings1 = bucket.get("strings");


共 (1) 个答案

  1. # 1 楼答案

    我的解决方案。我想它很好地满足了我的需要:

    public class Container<E> {
    
        private final E e;
    
        public Container(E e) {
            this.e = e;
        }
    
        public <T> T get(Class<T> target) {
            if (target.isAssignableFrom(e.getClass())) {
                return (T) e;
            }
            throw new ClassCastException(e.getClass().getName() + " '" + e + "' cannot be converted to " + target.getName());
        }
    }
    
    public class Bucket {
        private final Map<String, Container<?>> containers = new HashMap<>();
    
        public void put(String name, Container<?> container) {
            containers.put(name, container);
        }
    
        public Container<?> getContainer(String name) {
            return containers.get(name);
        }
    }
    

    进行测试:

    Container<Long> longs = new Container<>(100L);
    Container<String> strings = new Container<>("Hello");
    
    Bucket bucket = new Bucket();
    bucket.put("longs", longs);
    bucket.put("strings", strings);
    
    Container<?> longContainer = bucket.getContainer("longs");
    Long aLong = longContainer.get(Long.class);
    log.debug("{}", aLong); // Prints 100
    
    Container<?> stringContainer = bucket.getContainer("strings");
    String aString = stringContainer.get(String.class);
    log.debug("{}", aString); // Prints Hello
    
    log.debug("{}", stringContainer.get(Long.class)); // Throws java.lang.ClassCastException: java.lang.String 'Hello' cannot be converted to java.lang.Long