当我定义一个类型时:
class Bar<S> {
/* non-static */ class Foo<U extends Foo<U>> { }
}
Java编译器为创建的类型生成以下通用签名:
<U:Lfoo/Bar<TS;>.Foo<TU;>;>Ljava/lang/Object;
如果内部类型被定义为静态,则通用签名定义为:
<U:Lfoo/Bar$Foo<TU;>;>Ljava/lang/Object;
不同之处在于Foo
的外部类Bar
的类型变量也存储在签名中。我现在想知道为什么Java编译器会以这种方式在签名中添加此信息。我无法理解为什么它会对U
进行适当的定义有所不同,因为U
绝不依赖于S
或外部类。 Java编译器试图解决什么样的困境?
我想知道这个信息何时实际用于解析类型的示例。此外,我注意到Java反射API不会为静态或非静态情况返回不同的结果。
答案 0 :(得分:2)
你的假设是错误的。您在(JVM)类型签名中看到的是U
的上限。该上限为Foo<U>
,或者在完全限定时为foo.Bar<S>.Foo<U>
。尝试在Foo<U>
范围之外表示Bar
。 javac会对你大喊大叫。 ;)
class Bar<S> {
/* non-static */ class Foo<U extends Foo<U>> {}
}
Bar.Foo<?> foo = null; // error
Bar<String>.Foo<?> foo = null; // fine
编辑:您看到的TS;
不是类型参数,而是类型参数。完全限定边界并使用另一个参数使其显而易见:
class Baz {}
class Bar<S> {
/* non-static */ class Foo<U extends Bar<Baz>.Foo<U>> {}
}