Ich habe eine Klasse voller Dienstprogrammfunktionen. Eine Instanz davon zu instanziieren macht keinen semantischen Sinn, aber ich möchte trotzdem ihre Methoden aufrufen. Was ist der beste Weg, um damit umzugehen? Statische Klasse? Abstrakt?
130
Antworten:
Privater Konstruktor und statische Methoden für eine als final gekennzeichnete Klasse.
quelle
Nach dem großen Buch "Effective Java" :
Punkt 4: Erzwingen Sie die Nichtinstanzierbarkeit mit einem privaten Konstruktor
- Der Versuch, die Nichtinstanzierbarkeit durch eine abstrakte Klasse zu erzwingen, funktioniert nicht.
- Ein Standardkonstruktor wird nur generiert, wenn eine Klasse keine expliziten Konstruktoren enthält. Daher kann eine Klasse durch Einfügen eines privaten Konstruktors nicht instabilisiert werden:
Da der explizite Konstruktor privat ist, kann außerhalb der Klasse nicht auf ihn zugegriffen werden. Der AssertionError ist nicht unbedingt erforderlich, bietet jedoch eine Versicherung für den Fall, dass der Konstruktor versehentlich aus der Klasse heraus aufgerufen wird. Es garantiert, dass die Klasse unter keinen Umständen instanziiert wird. Diese Redewendung ist leicht eingängig, da der Konstruktor ausdrücklich angegeben wird, damit er nicht aufgerufen werden kann. Es ist daher ratsam, einen Kommentar aufzunehmen, wie oben gezeigt.
Als Nebeneffekt verhindert diese Redewendung auch, dass die Klasse in Unterklassen unterteilt wird. Alle Konstruktoren müssen explizit oder implizit einen Konstruktor der Oberklasse aufrufen, und eine Unterklasse hätte keinen zugänglichen Konstruktor der Oberklasse zum Aufrufen.
quelle
AssertionError
andere Alternativen über wieIllegalStateException
,UnsupportedOperationException
usw.?Klingt so, als hätten Sie eine Dienstprogrammklasse ähnlich java.lang.Math .
Der Ansatz dort ist die letzte Klasse mit privatem Konstruktor und statischen Methoden.
Beachten Sie jedoch, was dies für die Testbarkeit bedeutet. Ich empfehle, diesen Artikel zu lesen.
Statische Methoden sind der Tod für die Testbarkeit
quelle
Nur um flussaufwärts zu schwimmen, nehmen statische Mitglieder und Klassen nicht an OO teil und sind daher böse. Nein, nicht böse, aber im Ernst, ich würde eine reguläre Klasse mit einem Singleton-Muster für den Zugriff empfehlen. Auf diese Weise ist es keine größere Umrüstung, wenn Sie das Verhalten in einem späteren Fall außer Kraft setzen müssen. OO ist dein Freund :-)
Meine $ .02
quelle
Kommentar zu den Argumenten des "privaten Konstruktors": Komm schon, Entwickler sind nicht so dumm; aber sie sind faul. ein Objekt erstellen und dann statische Methoden aufrufen? wird nicht passieren.
Verbringen Sie nicht zu viel Zeit, um sicherzustellen, dass Ihre Klasse nicht missbraucht werden kann. Vertrauen Sie Ihren Kollegen. und es gibt immer eine Möglichkeit, Ihre Klasse zu missbrauchen, egal wie Sie sie schützen. Das einzige, was nicht missbraucht werden kann, ist etwas, das völlig nutzlos ist.
quelle
quelle
Es macht keinen Sinn, die Klasse als zu deklarieren
static
. Deklarieren Sie einfach die Methodenstatic
und rufen Sie sie wie gewohnt aus dem Klassennamen auf, wie in der Java- Klasse Math .Auch wenn es nicht unbedingt erforderlich ist, den Konstruktor privat zu machen, ist es eine gute Idee, dies zu tun. Durch Markieren des Konstruktors als privat wird verhindert, dass andere Personen Instanzen Ihrer Klasse erstellen und dann statische Methoden von diesen Instanzen aufrufen. (Diese Aufrufe funktionieren in Java genauso, sie sind nur irreführend und beeinträchtigen die Lesbarkeit Ihres Codes.)
quelle
Sie können die @ UtilityClass-Annotation von lombok https://projectlombok.org/features/experimental/UtilityClass verwenden
quelle