Create a Singleton class with generic instance variable?

Viewed 134

I have a scenario where there is a bean with a Future Object (class A below ). I have another Class (class B below) which is a singleton and has HashMap as an instance variable of type and implements an interface (TestInterface below) which again implements Callable.

As per the current scenario, the user can only pass Future of type Object but as per my new requirements, I want Future Object of Generic Type. I have modified the code which seems to be working but there are a lot of warnings and I'm not sure if my changes are even correct. There are some scenarios for which I'm sure code will fail. The main problem I'm facing is to initialize a HashMap of a GenericType within a singleton class. Can anyone help me with this?

The below code is example of existing code.

Interface Test Interface :

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

Class A

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

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

Class 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();
        }
    }

}

Changes I made for Genrics

Interface Test Interface :

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

Class A

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

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

Class 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();
        }
    }

}
1 Answers

If you are potentially putting in A<T>s of heterogeneous types into the map, the map needs to be declared as with a wildcard:

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

You would then obtain a value from the map thus:

    // 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

And put it into the map like:

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

If you need the T return type of the future in doSomething, you can declare a type variable on the method:

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