4

我在同一个包中创建了如下类test。这只是为了测试java是否真的允许它。它确实如此,但随之而来的是问题。

package test;

public class E {
}


package test;

public class T {
}


package test;

import test.E;
import test.T;

public class K<E, T> {

E e;
T t;

public K(E e, T t) {
    this.e = e;
    this.t = t;
}

public static void main(String[] args) {
    K k = new K<E, T>(new E(), new T());
}
}

上面的代码给出了多个编译问题

Multiple markers at this line
- Cannot make a static reference to the non-static type E
- Cannot make a static reference to the non-static type T
- Cannot make a static reference to the non-static type T
- Cannot make a static reference to the non-static type E
- K is a raw type. References to generic type K<E,T> should be 
 parameterized

它清楚地表明编译器在 E 和 E 类之间对 T 相同。

所以解决方法是使用包定义它的真实类型。

 K k = new K<test.E, test.T>(new test.E(), new test.T());

现在,如果所有这些类都在default package其中,则无法解决此编译问题。所以问题是java是否应该允许在中声明这些类default package

4

4 回答 4

3

它清楚地表明编译器在 E 和 E 类之间对 T 相同。

我认为你搞错了。我认为,如果您仔细阅读 JLS 的相关部分(我稍后会查找它们),您会发现它们清楚地说明了在各种情况ET应该解决的问题。如果编译器的分辨率错误,我会感到非常惊讶;即不实施JLS。

实际上,困惑在于编写代码的人的脑海中......

这里的问题是关于什么优先于什么的规则可能不是你(和典型的程序员)所期望的。但他们就像是有充分的理由一样。

通常这无关紧要,但如果您忽略正常的 Java 命名约定并为类使用单字母名称,那么您可能会被烧毁。

所以问题是java应该允许在默认包中声明这些类吗?

或者,“你”是否应该忽略 Java 类命名约定?

坦率地说,如果程序员忽略样式指南/建议,他们可能会以多种方式伤害自己。但是如果你试图过多地保护程序员,你实际上会伤害他/她,因为你无法实现你需要突破极限的东西。最好的政策是(IMO)不要将程序员视为孩子。如果他们真的想用锋利的刀来玩杂耍……就让他们吧。

于 2012-09-07T07:58:31.703 回答
2

这是非常好的研究。

但是,您仍然可以使用 name 创建一个类String,Java 从未抱怨过使用相同的类名。要区分您是否使用 String 类(或)Java 提供的 String 类,您需要附加包(全名)。

正如马特鲍尔所说,不应该使用默认包。

向后兼容性可能是泛型类型未定义为“保留字”的另一个原因

无论是否允许(或)相同的类名,我认为这就是包的用途。只要有办法区分我们指的是哪个类,我认为允许同名是完全可以的。

于 2012-09-07T06:28:41.947 回答
2

如果您愿意,您可能会感到非常困惑。我不确定编译器是否可以防止您编写令人困惑的代码,但我确实认为编译器应该尝试在其错误消息中明确。

public class T<T> {
    public T() {
    }

    public static <T> T T() {
        T T = null;
        return T; // which T is this?
    }
}
于 2012-09-07T07:18:58.783 回答
0

考虑到你可以写

public class String<Object>{}

禁止与您命名类型参数的名称相同的类或禁止您将类型参数命名为任何现有类都是疯狂的(名称冲突的类可以来自将来创建的另一个 jar,因此类型参数的任何名称都可以与名称相同某类的,反之亦然)

于 2012-09-07T07:35:52.673 回答