2012-01-11 15 views
7

私はここに何か基本的なものがないと思う。以前に尋ねられた質問に対する説明や指針は非常に役立ちます。オブジェクト配列の文字列配列サブクラスですか?

import java.util.Arrays; 
import java.util.List; 

public class St { 

    public static void bla(Object[] gaga) { 
      gaga[0] = new Date(); // throws ArrayStoreException 
     System.out.println(gaga[0]); 
    } 

    public static void bla(List<Object> gaga) { 
     System.out.println(gaga.get(0)); 
    } 

    public static void main(String[] args) { 
      String[] nana = { "bla" }; 
     bla(nana); // Works fine 

     List<String> bla1 = Arrays.asList(args); 
     bla(bla1); // Wont compile 

      System.out.println(new String[0] instanceof Object[]); // prints true 
      System.out.println(nana.getClass().getSuperclass().getSimpleName()); // prints Object 
    } 

} 

List<String>List<Object>のサブクラスではありませんが、String[]Object[]のサブクラスであるようなので、それはそうです。

これは正当な前提ですか?もしそうなら、なぜですか?そうでない場合、なぜですか?

おかげ

答えて

10

Java arrays are covariant、すなわち、彼らはObject[] foo = new String[2];を許します。しかし、これは彼らがサブクラスであることを意味するものではありません。 String[]は、あなたが正しいです(String[].class.getSuperclass()戻りObjectinstanceof trueを返しますが)

+0

以下の@maericsのコメントから、 'new [インスタンス]オブジェクト[]はtrueを返します。したがって、String []はObjectの型であり、Object []の型であり、CharSequence []などの型です。 – Kal

+0

@Kalは、共分散をカバーする特殊なケースのようです。私の更新を参照してください – Bozho

+0

ありがとう..ちょうどあなたの編集を見た。 – Kal

3
(new String[0] instanceof Object[]) // => true 
3

Objectのサブクラスです。配列型は、Javaでは設計上共変ですが、Foo<Sub>は-Foo<Super>です。

5

はい、あなたの前提が有効です。 @Bozho配列によると共変はありますが、ジェネリックコレクション(generic Listなど)は共変しません。アレイにおける

共分散が危険である:

String[] strings = new String[] { "a", "b" } 
Object[] objects = strings; 
objects[0] = new Date(); // <-- Runtime error here 
String s = strings[0]; 
s.substring(5, 3);  // ????!! s is not a String 

3行目は、実行時例外が発生します。この例外が発生していない場合は、String変数(s)を取得できます。この変数は、String(またはそのサブタイプではありません):Dateでない値を参照します。

+0

ありがとう。私は前にArrayStoreExceptionを見たことがない。 – Kal

2

のString []は[]

修正、参照オブジェクトのサブクラスである4.10.3 Subtyping among Array Types

S及びTは両方の参照型は、S []> 1 Tは、[している場合】IFF S> 1 T.

String >1 ObjectのでそうString[] >1 Object[]

String[]直接サブタイプ

Object[]のOBJECT> 1つのオブジェクト[]

Object > String[]

そのためです。 String[]は(間接的な?)サブタイプ

Objectのそのような関係は、ジェネリック医薬品のために存在していないので、 List<String> > List<Object>は本当ではないです。 xない List<I>ある List<C>allFを呼び出しているので、それはコンパイルされません

import java.util.*; 

class G { 
    interface I { 
    void f(); 
    } 
    class C implements I { 
    public void f() {} 
    } 

    void allF(List<I> li) { 
    for (I i : li) { i.f(); } 
    } 

    void x(List<C> lc) { 
    allF(lc); 
    } 
} 

さて、次の簡単な例を考えてみましょう。 List<C>を使用できるようにするには、署名をわずかに変更する必要があります。

void allF(List<? extends I> li) { 

今すぐコンパイルします。非公式に、liは/拡張List<C>List<? extends I>に割り当てあるのでI.を実装し、いくつかのタイプListです。そのようなリストでできることは限られています。基本的には、それを読む/アクセスすることはできますが、それはwrite/modifyできません。

+0

Umm ...サブタイプとサブクラスは異なることを意味します。 –

+1

@StephenC、クラスのサブタイプについては、[4.10.2](http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls- 4.10.2)。私は正しい答えは "配列はクラスではないので、サブクラスの関係を持つことはできませんが、String [] *はObject []"の* a * sybtype *です。それはあなたが何を示唆しているのでしょうか? –