0

I have this method that I need to get V type information:

    @Override
    public V get(String key) {
        Preconditions.checkNotNull(key, "Null id object");
        Map<String, Object> map = null;
        String oldNamespace = NamespaceManager.get();
        NamespaceManager.set(_namespace);
        try {
            map = store().get(KeyStructure.createKey("V.class.getName()", key)); // here
        } catch (Exception e) {
            // TODO Handle exception
            e.printStackTrace();
        } finally {
            if (oldNamespace != null)
                NamespaceManager.set(oldNamespace);
        }
        return (V) Mapper.createTObject(V.class, map); // and here
    }

Considering that I need to keep the get method parameters just that.

I think this is possible because at compile time the method will be used:

KVS<String,Friend> kvs = new KVS<String,Friend>();
Friend f = kvs.get("user.123");

Then V would be of class Friend

Update:

I tried:

public class StringObjectKeyValueStore<V> extends AbstractObjectStore<V>
        implements KeyValueStore<String, V> {
}

public abstract class AbstractObjectStore<V> {
     private final Class<V> type;
     public AbstractObjectStore(String namespace, String collection) {
        this.type = (Class<V>) ((ParameterizedType) getClass()
            .getGenericSuperclass()).getActualTypeArguments()[0];
}

However it throws:

java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class
quarks
  • 33,478
  • 73
  • 290
  • 513
  • It's not possible, unless you pass a `Class` while constructing the object and storing it. – Sotirios Delimanolis Apr 09 '14 at 04:10
  • @yshavit I think its similar but I also think that it is not duplicate. As the question is not about having a GenericClass or that sort. :-) – quarks Apr 09 '14 at 04:29
  • @xybrek The problem is the same. You are trying to access the type that the type variable would have for a particular execution. That type is completely unknown at run time. The only way to solve it is with the `Class` as described. – Sotirios Delimanolis Apr 09 '14 at 04:34
  • `GenericClass` there is just an example class name; it could just as well have been `KVS` or anything else. The answer is the same in both cases. – yshavit Apr 09 '14 at 04:34
  • @yshavit See my question update. – quarks Apr 09 '14 at 04:49
  • @SotiriosDelimanolis see my question update. – quarks Apr 09 '14 at 04:56
  • As mentioned above, you need to pass `Class` into your constructor: `StringObjectKeyValueStore(String namespace, String collection, Class valueClass) { this.valueClass = valueClass; /* etc */ }`. Yes, it's ugly. No, there's no way around it. Even the JDK people have to do this; see [`EnumMap`](http://docs.oracle.com/javase/7/docs/api/java/util/EnumMap.html#EnumMap(java.lang.Class)), for instance. – yshavit Apr 09 '14 at 04:56
  • You're meant to pass `Class` as an argument to the constructor, not try to get it from some other place. Here, you're trying to `getGenericSuperclass`, which is `AbstractObjectStore`, but cast it to a `ParameterizedType` which it is not. – Sotirios Delimanolis Apr 09 '14 at 04:56
  • @SotiriosDelimanolis I know, I think what I tried was crazy. So there is not way but to put the Class in the constructor? :-/ – quarks Apr 09 '14 at 05:00
  • @SotiriosDelimanolis However I see from here: https://community.jboss.org/wiki/GenericDataAccessObjects that it is being done by Hibernate – quarks Apr 09 '14 at 05:10
  • 2
    Note how the class is an `abstract` class. In other words, you need a child class to extend it. In _that_ case, the child class will `getGenericSuperclass` and retrieve a `Type` object for `GenericHibernateDAO`. If you can refactor and do that with `AbstractObjectStore`, do it. – Sotirios Delimanolis Apr 09 '14 at 05:17
  • @SotiriosDelimanolis I did refactor and add V into AbstractObjectStore then also Class etc. then I get this error now: java.lang.ClassCastException: sun.reflect.generics.reflectiveObjects.TypeVariableImpl cannot be cast to java.lang.Class – quarks Apr 09 '14 at 05:23
  • 1
    Start by reading what `getGenericSuperclass` and more importantly what `getActualTypeArguments` does. It returns the _actual_ type argument. If your subclass used `V`, a type variable, as an argument, that's what's returned, as a `TypeVariable` object. If you used `String`, then a `Class` object for `String` will be returned, etc. The problem with this solution is that you will need a subclass of `AbstractObjectStore` for each type of `V` you wanted in the first place. – Sotirios Delimanolis Apr 09 '14 at 05:25

0 Answers0