4

String と Integer が Object のスーパークラスではないのに、次が正当なのはなぜですか?

List<? super Object> mylist = new ArrayList<Object>();
mylist.add("Java"); // no compile error
mylist.add(2);

ワイルド カード ガイドラインでは下限のワイルド カードと「out」変数に super が使用されていることは承知していますが、この場合、Object は「下限」として機能しないようです。

また、これはリストへの任意のタイプの追加を許可する唯一の方法ですか?

4

3 に答える 3

4

それは本当に簡単です。Java では、サブタイプのインスタンスはそのスーパータイプのインスタンスでもあることに注意してください。

のサインを見てadd

public boolean add(E e)

Eこれは、タイプが であるか、 のサブタイプである何かを渡すことを意味しますE

あなたが持っていList<? super Object>ます。したがってmyList.add()、タイプが? super Object(またはそのスーパータイプである可能性がある未知のタイプObject) またはそのサブタイプであるすべてのものに渡すことができます。

Integer は に含まれるすべての型のサブタイプ? super Objectですか? もちろん。Integerは のサブタイプでありObject、これは に含まれるすべてのタイプのサブタイプです? super Object(もちろん、この場合、これObjectを満たすだけです)。

型パラメーターと、メソッドに渡すことができるものを混同しています。の型引数List<? super Object>、 のスーパータイプである不明な型であるObjectため、IntegerまたはString実際の型パラメータにすることはできません。実際、この場合、有効な実際の型の引数は だけですObject。しかし、メソッドに何かを渡すときに尋ねているのは、私が渡しているのはサブタイプですか? 答えはイエスです。

于 2012-08-10T18:45:44.007 に答える
3

紛らわしいことに同意しますが、これが起こっていることです。

このコード行では:

List<? super Object> mylist...

あなたはそれmyListが でありList、各要素が であるタイプObjectまたは のスーパークラスである可能性があると言っていますObject。ただし、myListここでは型を宣言しているだけです。

ワイルドカードが行うことは、 の実装を制限することですmyList

次に、これを行います。

List<? super Object> mylist = new ArrayList<Object>();

あなたがしているのは、ArrayList<Object>. 下限のワイルドカードを使用して、これが有効であることを確認します。Objectが一致するため、有効です? super Object。この時点で、次のList<Object>メソッド呼び出しが許可されます。

于 2012-08-10T18:24:28.147 に答える
3

これは、Object が Integer と String のスーパークラスであるためです。一般的な関係を逆に解釈しています。

編集

この状況について考えてみてください。

List<? extends myClass> listOfMyClass = new ArrayList<Object>();

この場合、Object型要素のリストになりますが、listOfMyClassリストの宣言によって追加された制限を尊重する必要があります。

myClass階層に属する任意のオブジェクトをリストに追加できます。ArrayListインターフェイスを実装している は、要求されたときに型要素Listを保持 (および返し)します。Object

もちろん、次のように定義できます。

List<? extends myClass> listOfMyClass = new ArrayList<mySuperClass>(); 

お分かりかもしれませんが、 にはArrayList、同じタイプまたはスーパータイプのオブジェクトが含まれている必要があります。myClassこの場合、それはmySuperClass. このリストはmySuperClass、要求されたときにオブジェクトを返します。

mySuperClassClassX階層に属さないクラスとして、次の行はコンパイルされません。

List<? extends myClass> listOfMyClass = new ArrayList<ClassX>(); 

ClassXは のスーパークラスではないためですmyClass

于 2012-08-10T18:06:36.450 に答える