简体   繁体   English

Java 非泛型方法隐藏具有交集类型的泛型方法

[英]Java non-generic method hiding generic method with intersection types

If three public interfaces are defined as:如果三个公共接口定义为:

public interface One{}
public interface Two{}
public interface Three{}

And another class, Super, is defined as:而另一个class,Super,定义为:

public class Super {
    public static <E extends One & Two & Three> void hmm(E item) {}
}

Why does the following subclass of Super give a compile error?为什么 Super 的以下子类会出现编译错误?

public class Subber extends Super{
    public static void hmm(One item) {}
}

I would expect the above method to simply hide the method from Super, but that does not seem to be the case.我希望上述方法可以简单地隐藏 Super 的方法,但似乎并非如此。

The JLS (8.4.8.2) says: 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. 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 否则可以访问(第 6.6 节)以在 C 中进行编码。

where a subsignature is defined in 8.4.2 as:其中子签名在 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.如果两个方法或构造函数 M 和 N 具有相同的名称、相同的类型参数(如果有)(第 8.4.4 节),并且在将 N 的形式参数类型调整为类型参数之后,则它们具有相同的签名的 M,形参类型相同。

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.方法 m1 的签名是方法 m2 签名的子签名,如果: m2 与 m1 具有相同的签名,或者 m1 的签名与 m2 签名的擦除(第 4.6 节)相同。

The erasure of a type variable is the erasure of its leftmost bound, as per JLS 4.6, so: As far as I understand, Subber's hmm method is the same as the erasure of Super's hmm method, and would therefore be a subsignature of Super's hmm, thus meaning it would hide Super's hmm.根据 JLS 4.6,类型变量的擦除是其最左边界的擦除,所以:据我了解,Subber 的 hmm 方法与 Super 的 hmm 方法的擦除相同,因此将是 Super 的 hmm 的子签名,因此意味着它会隐藏 Super 的嗯。 However, the error message I get (from eclipse), which doesn't seem to make sense given the above is: "The method hmm(One) of type Subber has the same erasure as hmm(E) of type Super but does not hide it."但是,我收到的错误消息(来自 eclipse),鉴于上述情况,这似乎没有意义:“Subber 类型的方法 hmm(One) 与 Super 类型的 hmm(E) 具有相同的擦除,但没有把它藏起来。” What am I missing?我错过了什么?

Edit: The precise error message, where the main method simply contains Subber.hmm(null);编辑:精确的错误消息,其中主要方法只包含Subber.hmm(null); is:是:

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)

Could someone explain why Subber's method does not compile, citing a credible source (preferably the JLS)?有人可以引用可靠的来源(最好是 JLS)解释为什么 Subber 的方法无法编译吗?

...Could someone explain why Subber's method does not compile... ……有人能解释一下为什么 Subber 的方法无法编译吗……

I implemented the code you listed ;实现了您列出的代码 verbatim .逐字逐句 And my Main.main(String[]) compiles fine with a call to Subber.hmm(null) and Subber.hmm(One) .我的Main.main(String[])通过调用Subber.hmm(null)Subber.hmm(One)编译得很好。

The only thing different I did was introduce a new Four interface that meets the requirements of the type parameter section of <E extends One & Two & Three> void Super.hmm(E) .我唯一不同的是引入了一个新的Four接口,它满足<E extends One & Two & Three> void Super.hmm(E)的类型参数部分的要求。

Then I passed an instance of Four into Subber.hmm(One) to confirm that Super.hmm(E) wasn't being called;然后我将Four的实例传递给Subber.hmm(One)以确认Super.hmm(E)没有被调用; proving it is actually hidden.证明它实际上是隐藏的。

...citing a credible source (preferably the JLS)?... ...引用可靠来源(最好是 JLS)?...

That implementation behaves exactly as the JLS spec that you cited describes.该实现的行为与您引用的 JLS 规范完全相同。

The type for E is still undefined, you can go and parameterize it via setting the E generic for the Super class and define it in the Subber class: E 的类型仍然未定义,您可以 go 并通过设置 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) {}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM