1

Maybe this have been answered before, but I did not find it here. Consider the following line of code:

public static <T> T getAs() { ... }

It is possible to obtain the object Class<T>, by reflection ?

For clarification, im not looking the generic type of a class, like in

class Foo<T> {
   public T get() { ...}
}

This can be done in c# at it is really handy, for example

class Foo {
    private List<A> items;

    public <T extends A> T first() {
        Class<T> clazz = //Magic??
        foreach (A a : items) {
           if (clazz.isInstance(a)) return (T)a;
        }
        return null;
    }

}

Used like this:

SubClass s = fooInst.<SubClass>first();
  • Did you go trough http://stackoverflow.com/questions/3403909/get-generic-type-of-class-at-runtime ? – reto Nov 24 '14 at 12:34
  • Check out this one, as well: https://docs.oracle.com/javase/tutorial/reflect/member/methodType.html – Konstantin Yovkov Nov 24 '14 at 12:35
  • i don't think this is duplicate, i think her really wants the Class and not the current class – No Idea For Name Nov 24 '14 at 12:35
  • 1
    The problem for this scenario is that `T` is a type parameter of a method and therefore depends on the call site. And exact generic type meta data at the expression level is not available at runtime. – SpaceTrucker Nov 24 '14 at 12:47

1 Answers1

0

Sometimes, it is indeed possible to get hold of generic type information even after compilation. In theory, this would even be possible for generic method calls. Spoiler, this is a bad idea. For academic reasons, let's however consider how this would be possible:

  1. Check the execution stack from within the method.
  2. Extract the calling class.
  3. Locate and interpret the calling class's class file and parse its calling method's byte code.
  4. Find the line where the method is called from.
  5. Emulate javac's type inference mechanism and locate the same type for T that javac would have infered.
  6. Load the class by its name you found for T.

This will of course not work very well and it would be broken if a type for T was specified explicitly in the source code. And you would not want to do this as your method call would suddenly require IO.

What you probably want is to return :

<T> T getAs(Class<? extends T> type) { ... }

In this case, you require the user to supply you with the required type but you do it in a type-safe manner.

Rafael Winterhalter
  • 42,759
  • 13
  • 108
  • 192