2017-12-05 4 views
0

Ich möchte wie so eine Liste machen können -Warum ist diese Zeile nicht Compiler-Liste <Object> l = new ArrayList <String>()?

List<Object> l = new ArrayList<String>(); 

Die Standardbibliothek Implementierung von ArrayList nicht zulassen. Es gibt Kompilierzeitfehler. Also schreibe ich meine eigene Implementierung der ArrayList.

Bisher habe ich schon versucht, diese -

public class ArrayList<Y extends X> implements List<X> {...} 
public class ArrayList<X super Y> implements List<X> {...} 

die kompilieren nicht.

Also, wie kann ich eine ArrayList schreiben, wo ich es wie oben erwähnt verwenden könnte?

List<Object> l = new ArrayList<String>(); 

Menschen haben Is List<Dog> a subclass of List<Animal>? Why aren't Java's generics implicitly polymorphic?

diesen Beitrag wies darauf hin, Aber ich verstehe immer noch nicht. Der Grund wurde angegeben, dass wir Situationen vermeiden, wie so wollen -

List<Object> l = new ArrayList<String>(); 
l.add(new Dog()); 

Während dies Sinn macht, kann ich eine ähnliche Art der Sache mit Java-Arrays tun, das kompiliert aber Ausnahme bei Laufzeit wirft.

Object o[] = new String[10]; 
o[0] = new Dog(); 

Also, was ist der Grund dafür, den letzten Code zu kompilieren, aber nicht ersteren?

EDIT - Ähnliche Frage wurde bereits wie oben angegeben gestellt. Diese Frage hilft auch Why is the ArrayStoreException a RuntimeException?

+2

Warum nicht die verknüpfte Frage Ihre Frage beantworten? Ich meine, es erklärt, warum Java diese Art von Syntax nicht unterstützt. Was genau willst du erreichen, wenn nicht das? Wenn Sie 'new ArrayList ()' schreiben, akzeptiert diese Liste ** nur ** 'String' und Subtypen davon. Wenn Sie 'new ArrayList ()' stattdessen schreiben, können Sie alles hinzufügen, was Sie wollen. – Zabuza

+0

Willst du sagen, dass du zur Laufzeit lieber eine Ausnahme als einen Kompilierfehler hast? Das scheint nicht viel Sinn zu machen. – Marvin

+0

Nein, das sage ich nicht. Ich frage nur, was der Grund dafür ist. –

Antwort

0

können Sie nur

List<Object> l = new ArrayList<Object>(); 

der Typparameter bei der Kompilierung existiert nur schreiben, so macht dies keinen Unterschied.

2

So wie Ihr Link sagt, Ihr List definieren wie folgt:

List<? extends Object> l = new ArrayList<String>(); 

EDIT

Ja, der Grund, dass

List<? extends Object> l = new ArrayList<String>(); l.add("asda"); 

nicht der Fall funktioniert der Laufzeit zu vermeiden Ausnahmen, weil der Typ der Liste sein könnte, ist alles, was Object erweitert, so dass der Compiler es als behandelt so (könnte alles/unbekannt sein). Sie können die Liste jedoch trotzdem bearbeiten, wenn Sie einen Verweis auf das Original beibehalten.

List<String> strList = new ArrayList<>(); 
List<? extends Object> objList = strList; 
strList.add("asdf"); 
// Will return Strings that only have the Object interface 
Object o = objList.get(0); 

Der Zweck List<? extends Object> nur wird Ihrem Code eine Art Garantie zu geben und die Compiler, durch Generika (eine Art Object in diesem Fall erstreckt), ist in der Lage diese Bedingung bei der Kompilierung, um sicherzustellen, aber es muss auch um sicherzustellen, dass Sie nicht gegen die ursprüngliche Liste verstoßen.Nehmen Sie zum Beispiel den folgenden Code:

List<Integer> intList = new ArrayList<>(); 
List<? extends Object> objList = intList; 
// compile error to protect the original list 
objList.add("asdf"); 

so, weil die objList vom Typ ? Sie kein String ihm hinzufügen. Auch wenn String eine Unterklasse von Object ist, ist es möglicherweise nicht (und ist in diesem Fall nicht) der gleiche Typ wie ?.

Vergessen Sie auch nicht, dass generische Typen zur Laufzeit wegen Type Erasure gegangen sind. Generika sind eine Kompilierzeitgarantie.

Auch jetzt sehe ich deine wahre Frage.

Ich brauche den Grund, warum ist das gleiche für Arrays erlaubt, warum nicht kompilieren Zeit Fehler in diesem Fall? Im Grunde frage ich, warum haben wir diese duale Strategie, eine für Arrays und eine andere Richtlinie für generische ArrayLists?

Siehe this Frage und die dazugehörigen Antworten in Bezug auf die

+0

'Liste l = new ArrayList (); ' ' l.add ("asda"); 'Funktioniert immer noch nicht. –

Verwandte Themen