自动型铸造

时间:2017-01-07 16:26:13

标签: java casting

我有一个程序需要接受只在运行时才知道类类型的对象。我想知道是否有可能让程序自动将对象强制转换为正确的类类型?

以下代码是我目前拥有的代码;我将逐步解释我希望它做什么:

  1. 创建一个TryingSomething实例,添加两个集合(类类型Foo之一,类类型Bar之一)。
  2. 应该将这些集添加到hashmap中。此时我已经收到Eclipse的警告,警告我这些集合在某种程度上是不兼容的。但类型是相同的。这里出了什么问题?
  3. 继续前进,假设上一步确实按预期工作。我希望再次在main方法中检索集合,但已经转换为正确的类类型(FooBar)。这会有用吗?如果没有,是否有替代方案允许我以正确的类类型检索对象?
  4. (Bonus)引入了每个集合附加的名称String,以便我区分不同的类类型。如果可以在步骤3中实现结果,而不需要String,那就更好了。
  5. 感谢任何能给我一些指示的人。

    class TryingSomething<T> {
        private Map<String, Set<T>> map = new HashMap<String, Set<T>>();
    
        public void addCollection(Set<T> s, String name){
            this.map.put(name, s);
        }
    
        public void test(){
            Set<Foo> foo = new HashSet<Foo>();
            Set<Bar> bar = new HashSet<Bar>();
            addCollection(foo, "foo");
            addCollection(bar, "bar");
        }
    
        public Set<T> getCollections(String name){
            return this.map.get(name);
        }
    
        @SuppressWarnings("unchecked")
        public static void main(String[] args){
            TryingSomething t = new TryingSomething();
            Set<Foo> foo = new HashSet<Foo>();
            Set<Bar> bar = new HashSet<Bar>();
            t.addCollection(foo, "foo");
            t.addCollection(bar, "bar");
            Set<Foo> fooList = t.getCollections("foo");
            Set<Bar> barList = t.getCollections("bar");
        }
    
    }
    
    class Foo{
    }
    
    class Bar{
    }
    

1 个答案:

答案 0 :(得分:1)

您可以使用类的类对象(运行时类型)作为映射键:

class TryingSomething {
    private Map<Class<?>, Set<?>> map = new HashMap<>();

    public <T> void addCollection(Set<T> s, Class<T> clazz){
        map.put(clazz, s);
    }

    public void test(){
        Set<Foo> foo = new HashSet<Foo>();
        Set<Bar> bar = new HashSet<Bar>();
        addCollection(foo, Foo.class);
        addCollection(bar, Bar.class);
    }

    @SuppressWarnings("unchecked")
    public <T> Set<T> getCollections(Class<T> clazz){
        return (Set<T>)this.map.get(clazz);
    }


    public static void main(String[] args){
        TryingSomething t = new TryingSomething();
        Set<Foo> foo = new HashSet<Foo>();
        Set<Bar> bar = new HashSet<Bar>();
        t.addCollection(foo, Foo.class);
        t.addCollection(bar, Bar.class);
        Set<Foo> fooList = t.getCollections(Foo.class);
        Set<Bar> barList = t.getCollections(Bar.class);
    }

}

class Foo{
}

class Bar{
}

TryingSomething不应该是通用的,因为您要存储任意类型的集合(在运行时动态选择)。请注意,此实现不会检查插入的集合是否实际上包含指定类型的对象(无论是在插入还是在检索时) - 此处的可重用性取决于此容器类的用户。