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

Tと同じように、コンパイラがEとクラスEの間で混同されていることを明確に示しています。

したがって、回避策は、パッケージを使用して実際の型を定義することです。

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

これらのクラスがすべて含まれている場合、default packageこのコンパイルの問題を解決する方法はありません。質問は、Java でそのようなクラスの宣言を許可する必要があるdefault packageかどうかです。

4

4 に答える 4

3

これは、コンパイラがTと同じEとクラスEの間で混同されていることを明確に示しています。

私はあなたがそれを間違っていると思います。JLSの関連部分を注意深く読むと(後で調べ​​ます)、さまざまな状況で何ET解決すべきかが明確に示されていることがわかると思います。コンパイラが解像度を間違えているとしたら、私は非常に驚きます。つまり、JLSを実装していません。

実際には、混乱はコードを書いた人の心の中にあります...

ここでの問題は、おそらくあなた(そして典型的なプログラマー)が期待するものよりも優先されるものに関する規則です。しかし、彼らは正当な理由があるようです。

通常、これは問題ではありませんが、通常のJava命名規則を無視し、クラスに1文字の名前を使用すると、やけどを負う可能性があります。

では、質問は、Javaがデフォルトパッケージでそのようなクラスの宣言を許可する必要があるかどうかです。

あるいは、「あなた」はJavaクラスの命名規則を無視する必要がありますか?

率直に言って、スタイルガイドライン/推奨事項を無視した場合、プログラマーが自分自身を傷つける可能性のある方法はたくさんあります。しかし、プログラマーを保護しすぎると、実際には、エンベロープをプッシュする必要のある場所にプログラマーを実装できなくなるため、プログラマーを傷つけることになります。最良のポリシーは、プログラマーを子供として扱わないことです(IMO)。彼らが本当に鋭いナイフでジャグリングしたいのなら...彼らに任せてください。

于 2012-09-07T07:58:31.703 に答える
2

これはとてもいい研究です。

ただし、 name を使用してクラスを作成することは引き続き許可されておりString、Java は同じクラス名の使用に対して文句を言うことはありませんでした。String クラス (または Java 提供の String クラス) を使用するかどうかを区別するには、パッケージ (完全な名前) を追加する必要があります。

Matt Ball が言ったように、デフォルトのパッケージは使用すべきではありません。

下位互換性は、ジェネリック型が「予約語」として定義されていない別の理由である可能性があります

同じクラス名を許可するかどうかに関係なく、それがパッケージの目的だと思います。参照しているクラスを区別する方法がある限り、同じ名前を許可してもまったく問題ないと思います。

于 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>{}

YOUが型パラメーターに名前を付けた方法と同じ名前のクラスを禁止するか、既存のクラスが正気でないため、型パラメーターに名前を付けることを禁止します(競合する名前を持つクラスは、将来作成される別のjarからのものになる可能性があるため、型パラメーターの名前は名前と同じになる可能性がありますあるクラスの、およびその逆)

于 2012-09-07T07:35:52.673 に答える