2009-09-29 3 views
18

byłem zaskoczony w dniu dzisiejszym podczas debugowania kodu, aby znaleźć to coś jak następuje nie rzucać wyjątek podczas kompilacji:Dlaczego ta kompilacja?

public Test() { 
    HashMap map = (HashMap) getList(); 
} 

private List getList(){ 
    return new ArrayList(); 
} 

Jak można sobie wyobrazić, o ClassCastException jest wyrzucane w czasie wykonywania, ale może ktoś wyjaśnić, dlaczego odlewanie List do HashMap jest uważane za legalne w czasie kompilacji?

+0

http://stackoverflow.com/questions/19895304/classcastexception-vs-cannot-cast-compilation-error/37190861#37190861 –

Odpowiedz

29

Ponieważ prawdopodobnie getList() może zwracać podklasę HashMap, która implementuje także List. Jest mało prawdopodobne, tak, ale możliwe, a zatem możliwe do skompilowania.

+9

+1: Wyraźne obsada jest w zasadzie sytuacja, w której programista mówi kompilator „I wiem, co robię, więc rób to po swojemu "- jeśli kompilator nie wie, że naprawdę się mylisz, to pójdzie po twojej myśli. Cóż, to jeden ze sposobów, w jaki mi to wyjaśniono. – weiji

+3

Tak, kompilator powinien narzekać, jeśli zastąpisz 'List' przez' ArrayList'. –

+0

@weiji: To prawda tylko w pewnym stopniu i jest o wiele mniej prawdziwe niż w C lub C++. Kompilator java da ci tylko tyle liny, a jeśli A nie może być instancją B, to się nie skompiluje. – skaffman

17

Po pierwsze lista to interfejs. Nie ma powodu, dla którego nie mogłaby istnieć podklasa HashMap, która również implementuje interfejs List. W tej sytuacji byłaby całkowicie słuszna.