2014-08-28 20 views
7

Ich lerne über Generika in Java und fragte mich, ob dies als schlechte Codierung betrachtet werden würde.Mehrere Arten von Objekten in Java-Containern

Wenn ich eine ArrayList<Object> deklariere, weiß ich, dass ich einen beliebigen Objekttyp in diese Liste einfügen kann, da alle Objekte von Object abstammen. Ich weiß auch, dass, wenn ich ArrayList.remove(index) rufe das Objekt, das aus dem Array herausgenommen wird, vom Typ Object ist, und dass ich es auf den Typ des Objekts typisieren muss, das ich verwenden möchte.

Nun angenommen, ich habe Objekt von Dog, Cat und Car. Wäre es nicht gut, alle drei Objekte in das Array zu schreiben, wenn man bedenkt, dass sie keine ähnlichen Klassen sind?

+0

Ja. Dies kann zu Laufzeit-Classcast-Ausnahmen führen. Generics soll Kompilierungszeitprüfungen sicherstellen, so dass Ihr Code typsicher ist – Adi

+0

Am Ende hängt es vom Kontext ab. Es gibt überhaupt nichts zu sagen, dass es an sich falsch ist, "Hunde", "Katzen" und "Autos" in derselben Liste zu speichern, und es gibt sicherlich Fälle, in denen es richtig ist; Es hängt nur davon ab, warum Sie es tun. Wenn Sie ein wenig mehr Kontext dazu angeben könnten, warum Sie dies tun möchten, würde das helfen, eine gute Antwort zu geben. – Dolda2000

Antwort

4

Lassen Sie uns die Definition eine

Eine Sammlung Collection revidieren - manchmal einen Container genannt - ist einfach ein Objekt, dass Gruppen mehr Elemente in eine einzige Einheit. Sammlungen werden zum Speichern, Abrufen, Bearbeiten und Kommunizieren von aggregierten Daten verwendet. In der Regel stellen sie Datenelemente dar, die eine natürliche Gruppe bilden .... (Fortsetzung).

Schauen Sie sich die fett gedruckten Worte an. Das sollte dir deine Antwort geben.

Wenn Sie Objekte in ArrayList einfügen, die nicht zu den gleichen Implementierungen gehören, werden Sie in Situationen, in denen Sie Objekte aus der Liste abrufen und sie an geeignete Typen übergeben möchten, auf jeden Fall Probleme verursachen. Also sollten Sie AVOID dabei tun.

Betrachten Sie speichern Objekte von Dog und Car in ArrayList. Dann möchten Sie für jedes gespeicherte Objekt eine Methode aufrufen, z. B. barkLoudly(). Nun wird diese Methode mit dem Objekt Dog gut funktionieren. Aber wenn dies angerufen wird Car, boooom .... Eine Exception wird entstehen.

2

Ich denke, die Antwort ist "normalerweise, aber nicht immer." Es gibt nicht viele harte und schnelle Regeln in der Codierung; Wenn Sie hart genug suchen, können Sie immer eine Ausnahme finden. Aber wenn Sie Objekte aus einer Sammlung ziehen, die Sie dann in den richtigen Typ umwandeln müssen, ist das normalerweise ein Konstruktionsfehler.

Versuchen Sie, Code so zu machen, dass die Objekte, mit denen Sie arbeiten, bereits den richtigen Typ für das haben, was Sie tun möchten. Wenn Sie nicht casten müssen, kann das Objekt in Ordnung sein. Wenn Sie casten müssen, sollten Sie Ihr Design wahrscheinlich überdenken.

1

Das Design wird wirklich schlecht sein, um all diese Probleme zu vermeiden, wurden Generika eingeführt. Aber das selbe können Sie unten benutzen, vorausgesetzt Sie haben die gleiche Art von Objekten.

Katze und Hund erstreckt Tier

Auto und Motorrad erstreckt Fahrzeug

Aber die nicht die beiden oben genannten Aussagen mischen.

Tierklasse:

public abstract class Animal { 
    protected String name; 
} 

Hundeklasse:

public class Dog extends Animal { 
    public Dog(String name) { 
     this.name=name; 
    } 
} 

Cat Klasse:

public class Cat extends Animal { 
    public Cat(String name) { 
     this.name=name; 
    } 
} 

Hauptklasse:

public class Main { 
    public static void main(String[] args) { 
     Cat Cat = new Cat("C"); 
     Dog Dog = new Dog("D"); 
     ArrayList<Animal> list = new ArrayList<Animal>(); 
     list.add(Cat); 
     list.add(Dog); 
    } 
} 
1

Sie sollten dies nicht tun

Ermöglicht es betrachten diese Weise, wenn ein wir ein generisches Object nur ein „Ding“ nennen und Sie erstellen (n) (Array) Liste der nur "Dinge" dann, wie nützlich ist das für Sie? Diese drei Dinge, die scheinbar nichts gemeinsam haben, in einer Liste zu speichern, macht keinen Sinn. Container wurden hinzugefügt, so dass Programmierer Gruppen von ähnliche Dinge speichern können.

Wenn wir es aus einer eher programmatischen Sicht als aus einer realen Sicht betrachten, wirft das mehr Probleme auf. Ihr Code könnte versuchen, eine Aktion durchzuführen, die nur Car tun kann, der Compiler mag nicht, dass Ihre Dog Klasse nur versucht, turnOnEngine(), und wirft einen Fehler, den Sie nicht erwartet haben.

Kurz gesagt, es ist eine schlechte Übung, unzusammenhängende Elemente zu einer Sammlung hinzuzufügen.

0

Es hängt davon ab, was Sie für die List verwenden möchten.

Sie sollten den generischen Typ Wert der List als die restriktivste, die Ihren Anforderungen entspricht, zu deklarieren, und auf diese Weise erhalten Sie die stärkste Prüfung vom Compiler, um die Fehler bei der Kompilierung zu beseitigen.

Es kann Fälle geben, in denen Sie wirklich nur jede Art von Objekten in einem List speichern möchten. In diesem Fall würden Sie List<Object> verwenden. Auch hier kommt es darauf an, was Sie für die List und die Elemente verwenden möchten.

1

Der Zweck von Generika ist es, den Compiler die Typüberprüfung für uns durchführen zu lassen. Damit müssen wir uns keine Gedanken über das Casting machen oder daran erinnern, welche Typen wirklich in der Liste stehen. So hilft auch die Verwendung von Generika Dokumentieren Ihren Code, indem Sie den enthaltenen Typ expliziter machen.

Sie könnten:

  • nicht Generika verwenden und Ihre eigene Typprüfung erzwingen (durch sicheren Downcasting mit instanceof)
  • Verwendung Generika mit separaten Listen für jeden Typen
  • Verwendung Generika mit einer Abstraktion für verwandte Klasse, zum Beispiel:
Verwandte Themen