0

I am trying to create an object holder util class to be short. Forexample;

public ResponseAbc bringMeStuff(RequestAbc request){
ResponseAbc response = new ResponseAbc();
/* Setting request here.. */
response = bringMeLotsOfStuff(request);

/* Here I am calling the Util class */
Util.putToObjectHolder("myAbcResponse", response);
return response;
}

public void testMe(){
/* Testing objectHolder */
ResponseAbc newResponse = (ResponseAbc) Util.getFromObjectHolder("response");
}

Here is the Util class

public class Util<T> {
private static Util<?> instance = null;
private Map<String, T> objHolder;

private Util() {
}
/* I strongly think Util class should be singleton if I want to hold the map globally */

public static Util<?> getInstance() {
    if (instance == null) {
        instance = new Util();
    }
    return instance;
}

public static <T> void putToObjectHolder(String objectName, T objectType) {
    // Map<String, T> holder = (Map<String, T>) getInstance().getObjHolder();
    // holder.put(objectName, objectType);
    getInstance().getObjHolder().put(objectName, objectType); //-> Argument error
}

public static <T> Object getFromObjectHolder(final String objectName) {
    Map<String, T> holder = (Map<String, T>) getInstance().getObjHolder();
    T obj = null;
    for (Entry<String, T> entry : holder.entrySet()) {
        if (entry.getKey().equals(objectName)) {
            obj = entry.getValue();
        } else {
            obj = null;
        }
    }
    return obj;
}

public Map<String, T> getObjHolder() {
    if (objHolder == null) {
        objHolder = new HashMap<String, T>();
    }
    return objHolder;
}

public void setObjHolder(Map<String, T> objHolder) {
    this.objHolder = objHolder;
}
}

If I uncomment putToObjectHolder method, it works but I am not pretty sure it supposed to work that way. I mean creating an other map and assigning to it should do the trick.

What I intent to do is holding a static Map holder with single instance so I can put whatever object I want with a name and get that object whenever I want if it exist in that 'global holder'.

PS: It is pretty messy with type safety warnings for sure, I would love to improve that aswell though I am not sure how to.

Thanks in advance.

gterdem
  • 757
  • 5
  • 14

2 Answers2

1

Putting aside the singleton part, are you trying to use generics to get objects (of varying types) into and out of the same Map whilst retaining type safety? That is, if you put into the map (for a given key) say a String then getting this value out will only compile if it is assigned to (or used as) a string. (And, also, there are no casts in the code.)

This can be done but it is a bit involved as you need to define keys that have the type of the corresponding value.

See: Java map with values limited by key's type parameter

Joshua Block also had a good article on this somewhere but I don't seem to be able to find it.

This seems to be what you are trying to achieve with your put method. You won't be able to do it with strings as keys though - you'll need a genericized, typed key.

Community
  • 1
  • 1
Paul
  • 3,009
  • 16
  • 33
0

You are not using generic the way they are meant to be used. Take a look at the ArrayList class to learn the true potential of generics.

Also singleton of this class serves no purpose as you only need a "singleton" of a HashMap.

Maybe I do not see what you are trying to accomplish but this is essentially what you are trying to do. Why don't you just use a HashMap and be done with it?

import java.util.HashMap;

public class Util {

    private static HashMap<String, Object> values = new HashMap<String, Object>;        

    private Util() {
    }

    public static void put(String key, Object value) {
        values.put(key, value);
    }

    public static Object get(String key) {
        return values.get(key);
    }

    public static void main(String[] args) {
        String s = "This is a test.";
        Util.put("test", s);
        System.out.println(Util.get("test"));
        System.out.println(Util.get("another test"));
    }
}
Logan Murphy
  • 6,120
  • 3
  • 24
  • 42