2010-05-23 10 views
9

Wir können die Erstellung eines Objekts einer Klasse einschränken, indem Sie den Konstruktor privat machen. Aber dieser Konstruktor konnte immer noch innerhalb der Klasse aufgerufen werden. Gibt es eine Möglichkeit, dies in Java zu verhindern?Verhindern des Aufrufs eines privaten Konstruktors innerhalb der Klasse in Java

Danke.

+0

Sie könnten Aspectj verwenden, um dies sicherzustellen. Es ist jedoch nur ratsam, dies zu tun, es sei denn, Sie möchten dies an mehr als einem Ort, da dies eine große Abhängigkeit und Komplexität mit sich bringen würde. In den meisten Fällen werden Ihnen Standards und Verfahren in diesem Fall besser als Werkzeuge und Kontrolle dienen. –

+12

Wir werfen eine UnsupportedOperationException von unseren privaten Konstruktoren, die nicht instanziiert werden sollen. Eigentlich ist dieses Idiom so üblich für uns, dass unsere IDEs so konfiguriert sind, dass wir * pct * (vier Tastenkombinationen) eingeben und es einen privaten Konstruktor generiert, der eine UnsupportedOperationException auslöst. – SyntaxT3rr0r

Antwort

14

Nein, es gibt keinen sauberen Weg, dies zu tun. Und ich sehe wirklich keinen Grund dafür. Wenn der Konstruktor privat ist, bedeutet dies, dass er nur aus Code innerhalb dieser exakten Klasse aufgerufen werden kann (keine Unterklassen oder andere Klassen im Paket). Wenn Sie also nicht möchten, dass der Konstruktor aufgerufen wird, geben Sie einen Kommentar ab was das sagt.

Da jeder, der in der Lage ist, den Konstruktor zu verwenden, in der Lage wäre, alle Maßnahmen zu entfernen, die Sie dort setzen, um den Aufruf des Konstruktors zu verhindern, hätte das keine wirkliche Auswirkung.

Außerdem, wenn Sie ein Singleton benötigen, dann möchten Sie vielleicht, dass der Konstruktor mindestens einmal ausgeführt wird (außer wenn Ihre Idee eines Singleton eine rein statische Klasse ist).

+0

Werfen Ausnahme, die es verhindern würde und es ist sauberer Weg. Sie können sogar Test dafür schreiben. Jeder kann es innerhalb der Klasse oder durch Reflexion und Ausnahme aufrufen. Da ist also ein Grund: Nachdenken. – Ewoks

3

Nein, es gibt keine Möglichkeit, eine einzelne Instanz eines bestimmten Typs zu erzwingen. Das Nächste, was Sie erreichen können, ist, wie Sie beschreiben, dass der Konstruktor privat ist, so dass nur Funktionen innerhalb dieser Klasse ihn aufrufen können. Sie könnten etwas zur Laufzeit ausführen (z. B. wenn Sie eine Ausnahme auslösen, wenn Ihre statische Instanz bereits existiert), aber das würde Sie zur Kompilierungszeit nichts bringen.

6

Die offizielle Antwort ist nein. Wenn jemand privaten Zugang zu Ihrer Klasse bekommen kann, kann er sie instanziieren.

aber Sie können dies tun:

private static int count = 0; 

private MyClass(){ 
    if(++count>1)throw new IllegalStateException(); //allow exactly one instantiation 
} 
+0

Richtig, aber die Synchronisation muss kugelsicher sein. Sie möchten wahrscheinlich einen CountDownLatch dafür verwenden, wenn Sie diesen Weg gehen. –

+0

Falsch wieder ..... – duffymo

+1

Nicht sicher, was zu sagen Duffymo, nach dem Lesen der OP, das ist die hellste Antwort hier (wirklich, um die OP-Anfrage entsprechen, sollte es nur immer eine Ausnahme werfen, aber dies zeigt Wie könnte man diese Bedingung noch erzwingen, während man eine Singleton-Instanz zulässt, was ein realistischeres Szenario ist. Wenn Sie glauben, dass die Frage Unsinn ist, ist das ein Kommentar zu der Frage, keine Antwort. Aber die Frage hat eine Antwort. –

9

Wenn es privat ist, und Sie wollen es nicht innerhalb der eigenen Klasse genannt, gibt es eine einfache Möglichkeit, so etwas zu verhindern: Schreiben Sie nicht den Code das nennt es mehr als einmal. Du bist der Autor der Klasse. Warum würdest du Code schreiben, um dich daran zu hindern, etwas zu tun, das du kontrollieren kannst?

Es kann nicht außerhalb der Klasse ohne Reflexion aufgerufen werden. Wenn Sie nicht möchten, dass es mehrmals in der Klasse aufgerufen wird, tun Sie es einfach nicht. Warum Code schreiben, um eine Aktion zu verhindern, die Sie nicht ausführen können?

Lassen Sie uns Bewertung:

Wir resrict die Erstellung von Objekt einer Klasse von seinem Konstruktor machen privat.

Constructor ist privat, so kann es nicht außerhalb der Klasse aufgerufen werden, wenn ein Client des Reflection-API verwendet Zugangsbeschränkungen zu untergraben.

Aber dieser Konstruktor noch von innerhalb der Klasse aufgerufen werden könnte. Gibt es auf jeden Fall zu verhindern dies in Java?

Das OP möchte verhindern, dass der eingeschränkte Konstruktor in der Klasse aufgerufen wird.

Wenn diese beiden Anweisungen korrekt sind, erläutern Sie bitte, warum Logik zum Verhindern von Aufrufen des Konstruktors erforderlich ist.

Hier ist eine typische Verwendung eines privaten Konstruktor:

public class Singleton 
{ 
    private static final Singleton instance = new Singleton(); 

    public static void main(String[] args) 
    { 
     Singleton singleton = Singleton.getInstance(); 

     System.out.println(singleton); 
    } 

    private Singleton() {}; 

    public static Singleton getInstance() { return Singleton.instance; } 

    public String toString() { return Singleton.class.getName(); } 
} 

Ich kann nicht den Punkt der disallowing den Anruf an den privaten Konstruktor sehen.

+0

Aber jede Klasse wird mindestens einen Konstruktor haben, und es scheint die Frage zu sein, Aufrufe innerhalb der Klasse zu beschränken. –

+4

Ja, aber wenn Sie meine Antwort lesen, werden Sie feststellen, wie lächerlich die Frage ist. Ihre Down-Abstimmung ist nicht gerechtfertigt. – duffymo

+1

Der Konstruktor muss noch geschrieben werden, denn wenn kein Konstruktor vorhanden ist, fügt der Compiler eine öffentliche hinzu, was noch schlimmer ist. – Alfonso

2

Wenn Sie einen Singleton machen, sind Aufzählungen der beste Weg zu gehen:

public enum MySingleton { 
    INSTANCE; 
    // add methods & stuff here 
} 

// Usage: 
MySingleton.INSTANCE.doSomething(); 

Die „singletonicity“ von der JVM ist garantiert - nur eine Instanz sein wird.

Verwandte Themen