javagenerics边界类型

以下两个签名是否相同?

public static  void work(Class type, T instance); 

 public static  void work(Class type, S instance); 

不,这两个签名不一样。 从Java语言规范,第8章 :

如果两个方法具有相同的名称和参数类型,则它们具有相同的签名。

如果满足以下所有条件,则两个方法或构造函数声明M和N具有相同的参数类型:

  • 它们具有相同数量的forms参数(可能为零)
  • 它们具有相同数量的类型参数 (可能为零)

由于您的两种方法不共享相同数量的类型参数,因此签名不同。

在使用隐式类型参数调用方法的实际情况中,它们可能被视为可互换。 但这只是在源级别,而不是二进制级别。 换句话说,如果你在类Foo有一个类型参数版本的work()并且它被类Bar的方法调用,然后你切换到work()的两个类型参数版本并重新编译Foo ,你还需要重新编译Bar

编辑

@onepotato问道:

如果他们没有相同的签名,那么为什么当我将它们复制并粘贴到一个类Eclipse时告诉我他们有相同的方法签名?

两个签名相等且两个签名冲突 (“覆盖等效”)之间存在差异。 如果一个是另一个的子签名,则两个签名冲突。 稍后将在同一部分对此进行说明:

如果m1是m2的子签名或m2是m1的子签名,则两个方法签名m1和m2是覆盖等价的。

在类中声明具有覆盖等效签名的两个方法是编译时错误。

方法m1的签名是方法m2的签名的子签名,如果:

  • m2与m1具有相同的签名,或
  • m1的签名与m2签名的擦除(§4.6)相同。

只看字节码我们就可以看到它们没有:

为了第一:

 // access flags 0x9 // signature (Ljava/lang/Class;TT;)V // declaration: void work(java.lang.Class, T) public static work(Ljava/lang/Class;Ljava/lang/Object;)V L0 LINENUMBER 86 L0 RETURN L1 LOCALVARIABLE type Ljava/lang/Class; L0 L1 0 // signature Ljava/lang/Class; // declaration: java.lang.Class LOCALVARIABLE instance Ljava/lang/Object; L0 L1 1 // signature TT; // declaration: T MAXSTACK = 0 MAXLOCALS = 2 

对于第二个:

 // access flags 0x9 // signature (Ljava/lang/Class;TS;)V // declaration: void work( extends java.lang.Class, S) public static work(Ljava/lang/Class;Ljava/lang/Object;)V L0 LINENUMBER 86 L0 RETURN L1 LOCALVARIABLE type Ljava/lang/Class; L0 L1 0 // signature Ljava/lang/Class; // declaration: java.lang.Class LOCALVARIABLE instance Ljava/lang/Object; L0 L1 1 // signature TS; // declaration: S MAXSTACK = 0 MAXLOCALS = 2 

对于任何参数集,如果存在有效的T选择

void work(Class type, T instance)

然后存在有效的TS选择

void work(Class type, S instance)

反之亦然。

所以从理论的角度来看,它们是等价的。 但是,由于推理有限,可能会出现这样的情况:当没有给出类型参数时,一个会编译,而另一个不会针对某些参数。 在这种情况下,始终可以为不编译的情况显式指定一组有效的类型参数,以使其进行编译。

由于它们是等价的,API应该总是更喜欢更简单的forms,即没有S