2

Definition in class:

class XXX {
    Map<String, Class> someMap;

    public <K, V>
    Optional<V> get(K key) {
        return Optional.ofNullable(getNullable(key));
    }

    public <K, V>
    V getNullable(K key) {
        //someMap already holds key -> class of V
        String value = DB.fetch(key);

        return gson.fromJson(value, someMap.get(key.toString()));
    }
}

Usage:

//xxx is an instance of XXX
Optional<ClassA> valueOpt = xxx.get(key); //this is fine
ClassA value = valueOpt.get(); //this is fine

//The intermediate valueOpt seems redundant, try to bypass it.
ClassA value = xxx.get(key).get(); //this does not work

My question: in the last line, seems the type info is deducible, why cannot it work? any workaround to make it work in one line?

Workarounds summary:
1) xxx.get(key, ClassA.class)
2) (ClassA)xxx.get(key)
3) xxx.<K,ClassA>get(key)

I still feel those are all workarounds because ClassA value = xxx.getNullable(key); can work.

Yingjie
  • 21
  • 2
  • My current workaround is: `public Optional get(K key, Class valueType); ClassA value = xxx.get(key, ClassA.class).get();` but the 2nd param valueType is actually not used. – Yingjie Apr 26 '17 at 23:40
  • The reason that this fails is that type inference only works for generic parameters. The expression `xxx.get(key).get()` has type `Object`, even though you know you're going to get `ClassA` from it. If you _must_ do it in a single line, then just apply a cast. `ClassA value = (ClassA) xxx.get(key).get();` – Dawood ibn Kareem Apr 26 '17 at 23:41
  • 1
    How is xxx declared? If I declare `Map> xxx`, then `String value = xxx.get("").get()` works. If xxx is declared as a raw type, see http://stackoverflow.com/a/43076991/1076640 – yshavit Apr 26 '17 at 23:43
  • Can you share your implementation of `get()`? I suspect `K` is unnecessary and `V` is unsafe. – shmosel Apr 26 '17 at 23:49
  • @yshavit `xxx` presumably implements the preceding method signature. – shmosel Apr 26 '17 at 23:58
  • 1
    The return type `V` is not deducible. The only guarantee is that your `get` method will return an instance of `Object`. – JimN Apr 27 '17 at 02:45

1 Answers1

0

You could be explicit with your method type params:

ClassA value2 = xxx.<String, ClassA>get(key).get();
Daniel Centore
  • 3,220
  • 1
  • 18
  • 39