Java 非泛型方法隐藏具有交集类型的泛型方法
Java non-generic method hiding generic method with intersection types
如果三个public接口定义为:
public interface One{}
public interface Two{}
public interface Three{}
还有一个class,超级,定义为:
public class Super {
public static <E extends One & Two & Three> void hmm(E item) {}
}
为什么下面的Super的subclass会报编译错误?
public class Subber extends Super{
public static void hmm(One item) {}
}
我希望上面的方法只是对 Super 隐藏该方法,但事实似乎并非如此。
JLS (8.4.8.2) 说:
If a class C declares or inherits a static method m, then m is said to hide any method m', where the signature of m is a subsignature (§8.4.2) of the signature of m', in the superclasses and superinterfaces of C that would otherwise be accessible (§6.6) to code in C.
其中子签名在 8.4.2 中定义为:
Two methods or constructors, M and N, have the same signature if they have the same name, the same type parameters (if any) (§8.4.4), and, after adapting the formal parameter types of N to the the type parameters of M, the same formal parameter types.
The signature of a method m1 is a subsignature of the signature of a method m2 if either: m2 has the same signature as m1, or the signature of m1 is the same as the erasure (§4.6) of the signature of m2.
根据 JLS 4.6,类型变量的擦除是其最左边边界的擦除,因此:
据我了解,Subber 的 hmm 方法与 Super 的 hmm 方法的擦除相同,因此将成为 Super 的 hmm 的子签名,这意味着它将隐藏 Super 的 hmm。但是,我得到的错误消息(来自 eclipse)似乎没有意义,因为上面的内容是:“Subber 类型的方法 hmm(One) 与 Super 类型的 hmm(E) 具有相同的擦除,但不把它藏起来。”我错过了什么?
编辑:准确的错误消息,其中主要方法仅包含 Subber.hmm(null);
是:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Name clash: The method hmm(One) of type Subber has the same erasure as hmm(E) of type Super but does not hide it
at base/testpack4.Subber.hmm(Subber.java:4)
at base/testpack4.Main.main(Main.java:5)
有人可以引用可靠的来源(最好是 JLS)来解释为什么 Subber 的方法无法编译吗?
E 的类型仍未定义,您可以通过为 Super class 设置 E 泛型来参数化它,并在 Subber class:
中定义它
public class Super<E> {
public static <E extends One & Two & Three> void hmm(E item) {}
}
public class Subber extends Super<One> {
public static void hmm(One item) {}
}
„...Could someone explain why Subber's method does not compile...“
我implemented the code you listed; 逐字。我的 Main.main(String[])
通过调用 Subber.hmm(null)
和 Subber.hmm(One)
[ 编译得很好=40=].
唯一不同的是我引入了一个新的Four
接口,满足[=14=的类型参数部分的要求].
然后我将 Four
的实例传递给 Subber.hmm(One)
以确认 Super.hmm(E)
没有被调用;证明它实际上是隐藏的。
„...citing a credible source (preferably the JLS)?...“
That implementation 的行为与您引用的 JLS 规范描述的完全相同。
如果三个public接口定义为:
public interface One{}
public interface Two{}
public interface Three{}
还有一个class,超级,定义为:
public class Super {
public static <E extends One & Two & Three> void hmm(E item) {}
}
为什么下面的Super的subclass会报编译错误?
public class Subber extends Super{
public static void hmm(One item) {}
}
我希望上面的方法只是对 Super 隐藏该方法,但事实似乎并非如此。
JLS (8.4.8.2) 说:
If a class C declares or inherits a static method m, then m is said to hide any method m', where the signature of m is a subsignature (§8.4.2) of the signature of m', in the superclasses and superinterfaces of C that would otherwise be accessible (§6.6) to code in C.
其中子签名在 8.4.2 中定义为:
Two methods or constructors, M and N, have the same signature if they have the same name, the same type parameters (if any) (§8.4.4), and, after adapting the formal parameter types of N to the the type parameters of M, the same formal parameter types.
The signature of a method m1 is a subsignature of the signature of a method m2 if either: m2 has the same signature as m1, or the signature of m1 is the same as the erasure (§4.6) of the signature of m2.
根据 JLS 4.6,类型变量的擦除是其最左边边界的擦除,因此: 据我了解,Subber 的 hmm 方法与 Super 的 hmm 方法的擦除相同,因此将成为 Super 的 hmm 的子签名,这意味着它将隐藏 Super 的 hmm。但是,我得到的错误消息(来自 eclipse)似乎没有意义,因为上面的内容是:“Subber 类型的方法 hmm(One) 与 Super 类型的 hmm(E) 具有相同的擦除,但不把它藏起来。”我错过了什么?
编辑:准确的错误消息,其中主要方法仅包含 Subber.hmm(null);
是:
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Name clash: The method hmm(One) of type Subber has the same erasure as hmm(E) of type Super but does not hide it
at base/testpack4.Subber.hmm(Subber.java:4)
at base/testpack4.Main.main(Main.java:5)
有人可以引用可靠的来源(最好是 JLS)来解释为什么 Subber 的方法无法编译吗?
E 的类型仍未定义,您可以通过为 Super class 设置 E 泛型来参数化它,并在 Subber class:
中定义它public class Super<E> {
public static <E extends One & Two & Three> void hmm(E item) {}
}
public class Subber extends Super<One> {
public static void hmm(One item) {}
}
„...Could someone explain why Subber's method does not compile...“
我implemented the code you listed; 逐字。我的 Main.main(String[])
通过调用 Subber.hmm(null)
和 Subber.hmm(One)
[ 编译得很好=40=].
唯一不同的是我引入了一个新的Four
接口,满足[=14=的类型参数部分的要求].
然后我将 Four
的实例传递给 Subber.hmm(One)
以确认 Super.hmm(E)
没有被调用;证明它实际上是隐藏的。
„...citing a credible source (preferably the JLS)?...“
That implementation 的行为与您引用的 JLS 规范描述的完全相同。