How can the generic method called know the type of the generic return?
I couldn't find a duplicate 开发者_高级运维for this question for Java, although there are a lot of them for C#.
I have this method:
public <T> T getSomething() {
//
}
According to the type of T, I will have a different return. For example:
String a = getSomething();
int b = getSomething();
For a
, my method will return a specific String
. For b
, it will return a specific int
. And so on.
It seems that this can be done with typeof()
in C#. How can I achieve it in Java?
Unfortunately this is not possible with Java because it uses a technique called "type erasure" to allow generics to work without changing the JVM. The upshot is that when the method is called, all it knows about are Objects, so it can't ever find out what type it is expected to return.
Your example doesn't work unless you have some code inside the getSomething method. If I write
public <T> T getSomething(){ return null;}
it compiles, but it's meaningless. However, you'd normally get your T from the context:
public class Foo<T>{
public T getSomething()...
}
new Foo<String>().getSomething()...
Presumably there'd have to be something in your implementation that's type aware.
In Java, it would be more normal to write something like:
public <T> List<T> getSomeThings() {
//
}
That works just fine.
Possibly the direct equivalent of what you have seen in C# would go something like:
public <T> T getSomething(Class<? extends T> clazz) {
//
}
But will use reflection, which will almost certainly be a bad idea. You can, of course, avoid reflection using a bog standard factory:
public <T> T getSomething(FactoryThing<? extends T> factory) {
//
}
There are occasional cases where inferring the return type is useful. For instance, reading from a Java serialisation stream where due to pre-1.5 API design, unchecked cast warnings are not reasonably avoidable. I suggest keeping this tight with a package-private method.
精彩评论