-2

I have a type-parameterized method but I can't call getClass on the type-parameterized parameter because it can be null, so the only solution I see is to get the Class from the type parameter itself, somehow:

public <T> Class myMethod(T obj)
{
    //can't do this: return obj.getClass() because null is permitted.
}

This method simply illustrates the problem. My actual method doesn't even return the parameter's class, but uses it in a different way. The core of the problem is this: Is there a way to get the Class object that represents the parameterized type of my method's parameter, without using obj.getClass() (because in case obj is null, I still need to know with what type parameter was the method invoked, for example: <String>myMethod(null) must return the java.lang.String class object).

EDIT This is not a duplicate of the said question because my class is not parameterized, only my method.

FinnTheHuman
  • 1,115
  • 13
  • 29
  • 1
    You can't, period. What is this intended to tell you that `getClass()` wouldn't? – chrylis -cautiouslyoptimistic- Sep 18 '16 at 09:59
  • @chrylis The method is an illustration. My actual method is not like that. I just reduced the problem to its core: I need to know the class of an object that may be null. – FinnTheHuman Sep 18 '16 at 10:03
  • Possible duplicate of [How to get a class instance of generics type T](http://stackoverflow.com/questions/3437897/how-to-get-a-class-instance-of-generics-type-t) – fabian Sep 18 '16 at 10:04
  • Then you've simplified it too far. – chrylis -cautiouslyoptimistic- Sep 18 '16 at 10:10
  • @chrylis I don't think I did. The problem is perfectly demonstrated by this method. – FinnTheHuman Sep 18 '16 at 10:15
  • Quite obviously not perfectly if it's not easily understood, and your "not a duplicate" suggests that you aren't quite getting some detail of Java generics. – chrylis -cautiouslyoptimistic- Sep 18 '16 at 10:20
  • @chrylis About not being a duplicate, the answers relies on the fact that a type can access its own type parameters. My class has no type parameters, so I can't use the answers given there. About my illustration not being enough to convey the nature of the problem, I'll try to edit and somehow be clearer, but all I can do is, more or less, repeat myself. – FinnTheHuman Sep 18 '16 at 10:24
  • @FinnTheHuman The issue is the same regardless of where you declare the type parameter. – fabian Sep 18 '16 at 10:32
  • `if (obj == null) return null; return obj.getClass()` ??? (A null is a null, it has no type) You might also want to change the return type to `Class` –  Sep 18 '16 at 10:33
  • @RC. `myMethod(null)` must return `java.lang.String`, `myMethod(null)` must return `java.lang.Byte`. – FinnTheHuman Sep 18 '16 at 10:36
  • 1
    And where in the world do you expect the `` information to come from? – chrylis -cautiouslyoptimistic- Sep 18 '16 at 10:37
  • @chrylis from the runtime method created when I invoke `myMethod` with the type parameter ``. I was hoping the method would know at runtime the type parameter used to create it, afterall, java language constructs have a lot of metadata associated with them retained at runtime. – FinnTheHuman Sep 18 '16 at 10:40
  • 2
    There *is* no "runtime method created". – chrylis -cautiouslyoptimistic- Sep 18 '16 at 10:51
  • I meant "the runtime version of the method, created by the compiler when I invoke myMethod with some type parameter". – FinnTheHuman Sep 18 '16 at 10:56
  • @FinnTheHuman: There is only ever one version of the method. – newacct Sep 21 '16 at 00:11
  • @newacct oh. I didn't know that. What language I was thinking of? C++ I think. This is why it can't work then. Thank you, now I know the reason behind the feature. – FinnTheHuman Sep 21 '16 at 10:47

2 Answers2

2

The core of the problem is this: Is there a way to get the Class object that represents the parameterized type of my method's parameter [...]

No. Class does not contain any information about the type parameter values. Class only contains data about the definition of the class, but not about a use of a type. In fact you cannot get this kind of information about a type parameter because of type erasure (see https://docs.oracle.com/javase/tutorial/java/generics/genMethods.html (methods) and https://docs.oracle.com/javase/tutorial/java/generics/genTypes.html (types)).

fabian
  • 80,457
  • 12
  • 86
  • 114
0

The solution is to refactor the method to:

public <T> Class<T> myMethod(Class<T> theClass, T obj)
    // other stuffs
    return theClass;
}

but the caller already knows what T is, so the real question is, why do you need that.

=> community wiki

  • This is the approach I was trying to avoid. I'll refactor my method to `Class> myMethod(Class> cls, Object obj)` – FinnTheHuman Sep 18 '16 at 11:01
  • The parameter `obj` is useless here as it is never used. The method in general is also pretty useless as it simply returns one of its arguments, so why not just use the passed argument directly instead of calling the method? – newacct Sep 21 '16 at 00:13
  • @newacct "other stuffs" –  Sep 21 '16 at 05:33