new String[]{"s","s"}
jest typu String[]
nie String
. T[]
nie jest podklasą T
(chyba że T
stanie się Object
).
Object[]
to podtyp Object
, dlatego pierwszy działa. W rzeczywistości wszystkie typy tablic to subtype of Object
, w tym, co może zaskakujące, tablice prymitywów, takie jak int[]
, chociaż int
nie jest Object
(*).
Można napisać pierwszy z nich przy użyciu bardziej konkretne typy:
Object[] c = new Object[] {1,2,"22" };
Możesz napisać drugi jako jedną z następujących czynności:
String[] s1 = new String[]{"s","s"};
Object[] s2 = new String[]{"s","s"};
Object s3 = new String[]{"s","s"};
Nawiasem mówiąc, s2
pokazuje, że tablice w Java jest kowariantna. Jest to problematyczne, ponieważ można legalnie napisać:
s2[0] = new Object();
które niepowodzenie przy starcie z ArrayStoreException
, ponieważ nie można zapisać Object
z odwołań w String[]
.
Jest to jeden z powodów, dlaczego autorzy jak Josh Bloch dają radę „wolą list do tablic” (patrz Efektywna Java 2. wyd pozycja 25), ponieważ kolekcje Java jak List
nie są kowariantna, a więc nie cierpią na ten sam problem.
(*) Wystarczy dodać do zamieszania, prymitywne tablice nie są podtypy Object[]
, jako prymitywy nie są podtypy Object
. Na przykład, byłby to błąd kompilacji czas, aby napisać:
Object[] illegal = new int[5];
'new String [] { "s", "s"}' 'jest typu String []', 'nie String'. 'Object []' jest podklasą 'Object', dlatego też działa pierwsza. –
Ciąg [] s = nowy ciąg [] {"s", "s"}; – star
@AndyTurner Ok, a następnie 'String []' nie jest podklasą ciągu 'String'. –