简体   繁体   English

java是否应该允许类名定义与泛型类型参数相同?

[英]Should java allow classes names to be defined same as generic type parameters?

I created classes like below in the same package test . 我在同一个包test创建了类似下面的类。 It was just to test whether java really allows it. 它只是为了测试java是否真的允许它。 And it does but then it comes in to problems. 确实如此,但问题就出现了。

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());
}
}

Above code give multiple compilation problems 上面的代码给出了多个编译问题

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

It clearly shows compiler is confused between E and class E same for T. 它清楚地表明编译器在E和E类之间混淆了相同的T.

So workaround is define it real types using package. 因此,解决方法是使用包定义它的真实类型。

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

Now if there all these classes are in default package there is no way to solve this compilation issue. 现在,如果所有这些类都在default package ,则无法解决此编译问题。 So Question is should java allow declaration of such classes in default package ? 那么问题是java应该允许在default package声明这样的类吗?

It clearly shows compiler is confused between E and class E same for T. 它清楚地表明编译器在E和E类之间混淆了相同的T.

I think you've got that wrong. 我觉得你错了。 I think that if you read the relevant parts of the JLS carefully (I'll look them up later) you will find that they clearly state what E and T should resolve to in the various contexts. 我认为如果你仔细阅读JLS的相关部分(我稍后会查看),你会发现它们清楚地说明了ET应该在各种情况下解决的问题。 I would be very surprised if the compiler is getting the resolution wrong; 如果编译器得到错误的分辨率,我会非常惊讶; ie not implementing the JLS. 即没有实现JLS。

In reality, the confusion is in the mind of the person who wrote the code ... 实际上,编写代码的人心中存在困惑......

The problem here is that the rules about what takes precedence over what are probably not what you (and typical programmers) expect. 这里的问题是关于什么优先于你(和典型的程序员)所期望的东西的规则。 But they are like they are for a good reason. 但他们就像是有充分理由的。

Normally this doesn't matter, but if you ignore the normal Java naming conventions and use one-letter names for classes, then you might get burnt. 通常这没关系,但是如果忽略了普通的Java命名约定并为类使用单字母名称,那么你可能会被烧毁。

So Question is should java allow declaration of such classes in default package? 那么问题是java应该允许在默认包中声明这样的类吗?

Alternatively, should "you" be ignoring the Java class naming conventions? 或者,“你”是否应该忽略Java类命名约定?

Frankly, there are a lot of ways that a programmer can hurt themselves if they ignore the style guidelines / recommendations. 坦率地说,如果程序员忽略了样式指南/建议,那么程序员可以通过很多方式来伤害自己。 But if you try to protect the programmer too much, you actually hurt him/her by making it impossible to implement stuff where you need to push the envelope. 但是如果你试图过多地保护程序员,你实际上是因为无法实现你需要推动信封的东西而伤害他/她。 The best policy is (IMO) to not treat programmers as children. 最好的政策是(IMO)不要将程序员视为儿童。 If they really want to juggle with sharp knives ... let them. 如果他们真的想要用锋利的刀子来玩......那就让他们吧。

This is very nice research. 这是非常好的研究。

But, you are still allowed to create a class with name String , Java never complained against using same class name. 但是,您仍然可以创建一个名为String的类,Java从不抱怨使用相同的类名。 To differentiate whether you use your String class (or) Java provided String class, you need to append the package (full name). 要区分是否使用String类(或)Java提供的String类,需要附加包(全名)。

As Matt Ball said, default packages are shouldn't be used. 正如Matt Ball所说,不应使用默认包。

Backward compatibility could be another reason why Generic Types not defined as "reserve words" 向后兼容性可能是通用类型未定义为“保留字”的另一个原因

Whether allow same class name (or) not, I think that is what packages are for. 是否允许相同的类名(或),我认为这是包的目的。 As long as there is a way to differentiate which class we are referring to, I think it is perfectly fine to allow same name. 只要有办法区分我们指的是哪个类,我认为允许同名是完全没问题的。

You can get really confused if you want to. 如果你愿意,你可能会感到非常困惑。 I am not sure its up to the compiler to prevent you from writing confusing code but I do think the compiler should try to be clear in its error messages. 我不确定编译器是否会阻止您编写令人困惑的代码,但我认为编译器应该尝试在其错误消息中清楚。

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

    public static <T> T T() {
        T T = null;
        return T; // which T is this?
    }
}

Considering you can write 考虑到你可以写

public class String<Object>{}

Disalowing class with same name as how YOU named type parameter or forbiding you to name type parameter as any existing class would be insane (Class with conflicting name can be from another jar created in future, so any name of type parameter can be same as name of some class, and vice versa) 取消与您命名类型参数或禁止将名称类型参数命名为任何现有类的名称相同的类将是疯狂的(具有冲突名称的类可以来自将来创建的另一个jar,因此任何类型参数的名称都可以与名称相同一些类,反之亦然)

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

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