getClass() of a Generic Method Parameter in a Java

后端 未结 2 1654
日久生厌
日久生厌 2021-02-14 17:24

The following Java method fails to compile:

 void foo(T t)
{
    Class klass = t.getClass();
}

Error

相关标签:
2条回答
  • 2021-02-14 18:01

    Because the T class' type doesn't extend from T. Instead, it extends from Number, exactly as you have declared yourself in <T extends Number>. Simple as that.

    A better question would be:

    Why doesn't the following compile?

    <T extends Number> void foo(T t)
    {
        Class<T> class1 = t.getClass();
    }
    

    The answer to that is that the Object#getClass() returns Class<?> with an unbounded wildcard ? because the object itself is not directly aware about its generic type which is been expected in an arbitrary method.

    0 讨论(0)
  • 2021-02-14 18:09

    It is kind of silly. It would have been better, for most use cases, if x.getClass() returns Class<? extends X>, instead of the erased Class<? extends |X|>.

    The erasure is the cause of loss of information, making your code, apparently safe, fail to compile. t.getClass() returns Class<? extends |T|>, and |T| = Number, so it returns Class<? extends Number>.

    The erasure (mandated by the language spec) is to maintain theoretical correctness. For example

    List<String> x = ...;
    Class<List> c1 = x.getClass(); // ok
    Class<List<String>> c2 = x.getClass(); // error
    

    Although c2 seems very reasonable, in Java, there is really no such class for List<String>. There is only the class for List. So allowing c2 would be, theoretically incorrect.

    This formality created lots of problem in real world usages, where programmers can reason that Class<? extends X> is safe for their purposes, but have to cope with the erased version.

    You can simply define your own getClass that returns the un-erased type

    static public <X> Class<? extends X> getFullClass(X x)
        return (Class<? extends X>)(Class) x.getClass() ;
    
    <T extends Number> void foo(T t)
    {
        Class<? extends T> klass = getFullClass(t);
    }
    
    0 讨论(0)
提交回复
热议问题