2016-04-18 14 views
7

Jeśli mamy Typ [], możemy przechowywać w nim Typ lub jego podtypy. To samo dotyczy ArrayList. Dlaczego więc mówi się, że jedno jest homogeniczne, a drugie nie?Co to znaczy, że tablice Java są jednorodne, ale ArrayLists nie są?

+5

Kto powiedział, że ArrayLists są niejednorodne? Dopóki nie ominąłeś generycznych, są one dokładnie tak jednorodne jak tablice. (Jeśli * pominiesz * generyczne, powinieneś prawdopodobnie porównać do 'Object []'.) – user2357112

+2

Chciałbym, żeby to była odpowiedź. – totoro

+0

Każdy element dowolnej tablicy musi być tym samym typem pierwotnym lub tym samym typem odniesienia. Każdy element tablicy ArrayList musi mieć ten sam typ odniesienia. –

Odpowiedz

10

Tablice mają sprawdzanie czasu pracy na typ dodanego elementu. Oznacza to, że jeśli zostanie dodany nowy element, który nie jest tego samego typu, w środowisku wykonawczym zostanie zgłoszony kod ArrayStoreException. Dlatego są one uważane za "homogeniczne".

To nie jest prawda dla ArrayList s (List s w ogóle). Ze względu na wymazywanie typu w czasie wykonywania może on praktycznie pomieścić dowolny obiekt.

Poniższy zgłasza wyjątek podczas uruchamiania:

Object[] array = new String[3]; 
array[0] = "a"; 
array[1] = 1; // throws java.lang.ArrayStoreException 

przeciwieństwie następujących składników, które kompiluje i działa bez problemu (chociaż z ostrzeżeniem kompilatora, ponieważ nie poprawnie używać rodzajowych):

ArrayList list = new ArrayList<String>(); 
list.add("a"); 
list.add(1); // OK 
list.add(new Object()); // OK 

Przy prawidłowym użyciu generycznych, tj. Deklarowaniu zmiennej list powyżej typu ArrayList<String> zamiast ArrayList, problem jest unikany podczas kompilacji:

ArrayList<String> list = new ArrayList<String>(); 
list.add("a"); 
list.add(1); // compilation error 
list.add(new Object()); // compilation error 

Ale nawet z ogólnie zadeklarowanej liście, można mieć coś podobnego do tego dzieła bez wyjątku w czasie wykonywania:

ArrayList<String> list = new ArrayList<String>(); 
list.add("a"); 
Method[] methods = List.class.getMethods(); 
for(Method m : methods) { 
    if(m.getName().equals("add")) { 
     m.invoke(list, 1); 
     break; 
    } 
} 
System.out.println(list.get(0)); 
System.out.println((Object) list.get(1)); 

wyjściowa:

+0

Czy możesz osadzić "omijanie leków generycznych" i pokazać generykom, że rzeczywiście jest to odpowiedź jednorodna? – totoro

+0

"Poniższe kompiluje i działa bez problemu" Podczas kompilacji otrzymasz ostrzeżenie podczas kompilacji. – Powerlord

0

Tak. JavaArrays są jednorodne, ponieważ gdy zadeklarujesz jakąkolwiek tablicę w Javie, musisz zadeklarować jej type. np

int arr[]; //type is int 
    String arr[]; //type is String 
    float arr[]; //type is float 

teraz, jeśli starają się przechowywać żadnych innych danych typu w zadeklarowanej tablicy, to będzie błąd kompilacji czas. np

int arr=new int[5]; 
    arr[0]="I am a String not int"; //compile time error 

ale ArrayList są częścią Collection „s, trzymają Objects, zamiast konkretnej data-type [jeśli nie mówimy o generics], a ponieważ każda rzecz w Java jest bezpośrednio lub pośrednio odziedziczony Objectclass, więc to nie daje compile-time error, sprawdzanie typu będzie na run-time.

np

ArrayList al=new ArrayList();//type is Object 
    al.add("I am a String"); //Bacause String class in inherited from Object Class 
    al.add(1);//the int 1 will first autobox into Integer class then stored in al ArrayList.Now bacause Integer class is also inherited from Object class,it will*/ allow you to store 
    al.add(UserDefinedClass); //because every User defined class is also inherited from Object class,so it will also allow you. 

teraz zauważyłaś, ponieważ nie określono żadnego typu danych ArrayList al, ale nadal jesteśmy przechowywania różnych wartości typu: to jest wiedzieć dlaczego ArrayList Stores Object nie specyficzne dane typu , dlatego są heterogeniczne, a nie jednorodne.