21 Stimmen

Vermeiden Sie die Instanziierung einer Klasse in Java

Kürzlich habe ich mir eine Frage gestellt: Wie lässt sich die Instanziierung einer Java-Klasse vermeiden?

Ich habe jedoch geantwortet, indem ich gesagt habe:

  1. Wenn Sie eine Klasse nicht instanziieren wollen, verwenden Sie den Modifikator "abstract". Beispiel: javax.servlet.HttpServlet wird als abstrakt deklariert (obwohl keine seiner Methoden abstrakt ist), um eine Instanziierung zu vermeiden.

  2. Deklarieren Sie einen privaten Konstruktor ohne Argumente.

Meine Frage lautet nun a) gibt es noch andere Möglichkeiten? b) warum will jemand eine Klasse nicht instanziieren? - nachdem ich in SO gesucht habe, habe ich erfahren, dass diese dass Util-Klassen nicht instanziert werden können. Gibt es noch andere Stellen, an denen wir eine Klasse in OOP nicht instanziieren wollen?

29voto

cletus Punkte 596503

Vier Gründe fallen mir dazu ein:

  1. Erlaubt die Instanziierung von Unterklassen, aber nicht der übergeordneten Klasse;
  2. Nicht zulassen direkt Instanziierung zu vermeiden und stattdessen eine Factory-Methode bereitzustellen, die Instanzen zurückgibt und bei Bedarf erstellt;
  3. Weil alle Instanzen vordefiniert sind (z. B. Farben in einem Kartenspiel), obwohl seit Java 5 stattdessen typsichere Enums empfohlen werden; und
  4. Die Klasse ist eigentlich keine Klasse. Sie ist nur ein Behälter für statische Konstanten und/oder Methoden.

Als Beispiel für (2) können Sie kanonische Objekte erstellen. Zum Beispiel RGB-Farbkombinationen. Sie möchten nicht mehr als eine Instanz einer RGB-Kombination erstellen, also tun Sie dies:

public class MyColor {
  private final int red, green, blue;

  private MyColor(int red, int green, int blue) {
    this.red = red;
    this.green = green;
    this.blue = blue;
  }

  public static MyColor getInstance(int red, int green, int blue) {
    // if combo already exists, return it, otherwise create new instance
  }
}

Nota: ist kein no-arg-Konstruktor erforderlich, da ein anderer Konstruktor explizit definiert ist.

14voto

Kolibri Punkte 557

Nicht wirklich eine Antwort auf Ihre Frage, sondern nur eine Anmerkung:

Wenn Sie einen privaten no-arg-Konstruktor erstellen, um die Instanziierung Ihrer Utility-Klassen zu verhindern, sollten Sie den Konstruktor eine Ausnahme auslösen lassen (z. B. UnsupportedOperationException). Der Grund dafür ist, dass Sie über Reflection auf private Mitglieder (einschließlich Konstruktoren) zugreifen können. Beachten Sie, dass Sie in diesem Fall einen Kommentar hinzufügen sollten, da es etwas kontraintuitiv ist, dass Sie einen Konstruktor definieren, um verhindern. eine Klasse nicht instanziiert werden.

Es ist keine gute Idee, die Utility-Klasse abstrakt zu machen, denn dann sieht es so aus, als ob die Klasse erweitert werden soll, und außerdem kann man die Klasse erweitern und sie dadurch instanziieren.

3voto

Zed Punkte 55390

Manchmal möchten Sie nur verhindern, dass andere Ihre Objekte instanziieren, um die volle Kontrolle über alle vorhandenen Instanzen zu haben. Ein Beispiel ist die Singleton-Muster .

2voto

jW. Punkte 8980

Ich denke, der häufigste Grund, eine Klasse nicht instanziieren zu wollen, ist, wenn es sich um eine statische Klasse und damit um ihre statischen Methoden handelt. Sie wollen nicht, dass jemand versucht, diese Klasse zu instanziieren. Ähnlich verhält es sich mit Factory-Klassen oder in einigen Fällen mit Singleton-Klassen, die ihren Konstruktor verbergen, um nicht auf normalem Wege instanziert zu werden.

1voto

Stephen C Punkte 665668

Eine andere Möglichkeit, eine Klasse nicht instanzierbar zu machen, wäre, sie als private innere Klasse zu deklarieren und dann keine Möglichkeit zu bieten, sie in der umgebenden Klasse zu instanzieren. Aber das ist (IMO) ziemlich sinnlos.

Eine Klasse soll nicht instanzierbar sein, wenn es keinen Sinn macht, sie zu instanziieren. Dies ist in der Regel dann der Fall, wenn die Klasse eigentlich nur eine Sammlung von (statischen) Hilfsmethoden ist, oder wenn die Klasse "unvollständig" ist. Die Unvollständigkeit kann syntaktisch offensichtlich sein (z. B. abstrakte Methoden), aber es gibt auch andere Arten der Unvollständigkeit. So könnten Sie beispielsweise Standardimplementierungen für alle Methoden vorsehen und verlangen, dass eine oder mehrere von ihnen überschrieben werden, damit die Klasse etwas Nützliches tun kann.

Ein weiterer Grund, eine Klasse nicht instanzierbar (oder zumindest nicht direkt instanzierbar) zu machen, ist, wenn Ihre Anwendung die Instanziierung kontrollieren muss. Zum Beispiel kann die Klasse java.util.regex.Pattern nicht direkt instanziert werden, damit die JRE einen Cache mit vorkompilierten Regexen pflegen kann (könnte).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X