Java: getClass() of bounded type

前端 未结 5 1347
旧时难觅i
旧时难觅i 2020-11-30 12:35

I noticed something while I was derping around with generics. In the example below, doStuff1 compiles but doStuff2 doesn\'t:

public         


        
5条回答
  •  时光说笑
    2020-11-30 13:10

    Consider the following program:

    var a = new ArrayList();
    var b = new ArrayList();
    var aType = a.getClass();        
    var bType = b.getClass();        
    
    if (aType == bType) {
      ...
    }
    

    If we execute this, aType and bType will contain the same runtime class object (since all instances of a generic type share the same runtime class), and the body of the if statement will execute.

    It will also compile just fine. In particular, the declared types of aType and bType are both Class, and comparing two references of compatible types makes sense to the compiler.

    However, if getClass were defined to return Class instead, the compile time types of aType would be Class, and the type of bType would be Class>. Since Java defines generics as invariant, these are inconvertible types, and the compiler would thus be required to reject the comparision aType == bType as nonsensical, even though the runtime thinks it true.

    Since fixing this would have required a major extension to the java type system, declaring getClass to return the erasure was likely seen as the simpler option, even though it causes counter-intuitive behavior in other cases, such as the one you encountered. And of course, once defined that way, it could no longer be changed without breaking API ...

    To work around the workaround, you can use an unchecked cast:

    @SuppressWarnings("unchecked")
     Class getTypedClassOf(T t) {
       return (Class) t.getClass();
    }
    

    Of course, this means that you might need to resort to unchecked casts to get the compiler to understand that class objects of inconvertible types might be identical after all ...

提交回复
热议问题