【问题标题】:Create a Singleton class with generic instance variable?创建一个带有通用实例变量的单例类?
【发布时间】:2019-01-16 09:15:01
【问题描述】:

我有一个场景,其中有一个带有未来对象的 bean(下面的 A 类)。我有另一个类(下面的 B 类),它是一个单例,并将 HashMap 作为类型的实例变量,并实现了一个接口(下面的 TestInterface),它再次实现了 Callable。

根据当前场景,用户只能传递 Object 类型的 Future,但根据我的新要求,我想要通用类型的 Future Object。我已经修改了似乎可以工作的代码,但是有很多警告,我不确定我的更改是否正确。在某些情况下,我确信代码会失败。我面临的主要问题是在单例类中初始化 GenericType 的 HashMap。谁能帮我解决这个问题?

以下代码是现有代码的示例。

接口测试接口:

interface TestInterface extends Callable<Void>{
    void doSomething(Future<Object> future, String id); 
}

A 类

class A{
 private Future<Object> future;
 private CustomInteraface a;

 public A(Future<Object> future, CustomInteraface a){
    //do init
 }
 //getters and setters
}

B类

Class B implements TestInterface{

    private HashMap<String, A> map = new HashMap();
    private static B monitor = new B();


    public Void call(){
        HashMap.Entry<String, A> pair = (HashMap.Entry<String, A>) it.next();
        A a = (A) pair.getValue();
        Future<Object> future = a.getFuture();
        // Do something
    }

    public void doSomething(Future<Object> future, String id){
        if(map.contains(id)){
            //Do something
        }
        else{
            A a = new A(future, null);
            map.put();
        }
    }

}

我为 Genrics 所做的更改

接口测试接口:

interface TestInterface extends Callable<Void>{
    <T> void doSomething(Future<T> future, String id);  
}

A 类

class A<T>{
 private Future<T> future;
 private CustomInteraface a;

 public A(Future<T> future, CustomInteraface a){
    //do init
 }
 //getters and setters
}

B类

Class B implements TestInterface{

    private HashMap<String, A> map = new HashMap();
    private static B monitor = new B();


    public Void call(){
        HashMap.Entry<String, A> pair = (HashMap.Entry<String, A>) it.next();
        A a = (A) pair.getValue();
        //Code will definitely fail here as I'm trying to cast a future object of generic type to Object class
        Future<Object> future = a.getFuture();
        // Do something
    }

    public void doSomething(Future<T> future, String id){
        if(map.contains(id)){
            //Do something
        }
        else{
            A<T> a = new A<T>(future, null);
            map.put();
        }
    }

}

【问题讨论】:

  • 如果是单例,“泛型”是什么意思?
  • 实际上,该 Singelton 类的实例变量是通用的,即在我的情况下 HashMap 的值。我不知道如何初始化它,因为我的类是 singelton 并且在创建类本身期间我正在实例化 HashMap。

标签: java generics


【解决方案1】:

如果您可能将异构类型的A&lt;T&gt;s 放入映射中,则需要将映射声明为使用通配符:

private HashMap<String, A<?>> map = new HashMap();

然后您将从地图中获得一个值:

    // The cast was only necessary because A by itself is a raw type.
    HashMap.Entry<String, A<?>> pair = it.next();
    A<?> a = pair.getValue();
    Future<?> future = a.getFuture();
    // Note that future.get() yields an Object

并将其放入地图中,如下所示:

public void doSomething(Future<?> future, String id){
    ...
        A<?> a = new A<>(future, null);
        map.put(id, future);
    ...
}

如果需要doSomething中未来的T返回类型,可以在方法上声明一个类型变量:

public <T> void doSomething(Future<T> future, String id){

【讨论】:

  • @utkarsh31 不,使用A&lt;?&gt;,如我的回答所示。
猜你喜欢
  • 2012-08-30
  • 1970-01-01
  • 2013-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-20
相关资源
最近更新 更多