370 Stimmen

Wie lassen sich Konstanten am besten in Java implementieren?

Ich habe solche Beispiele gesehen:

public class MaxSeconds {
   public static final int MAX_SECONDS = 25;
}

und nahm an, dass ich eine Klasse Constants haben könnte, um Konstanten darin zu verpacken und sie als static final zu deklarieren. Ich weiß praktisch kein Java überhaupt und frage mich, ob dies der beste Weg, um Konstanten zu erstellen ist.

5voto

Rob Dickerson Punkte 1439

Ich stimme zu, dass die Verwendung einer Schnittstelle nicht der richtige Weg ist. Das Vermeiden dieses Musters hat sogar einen eigenen Punkt (#18) in Blochs Leistungsfähiges Java .

Ein Argument, das Bloch gegen das Konstanten-Schnittstellenmuster vorbringt, ist, dass die Verwendung von Konstanten ein Implementierungsdetail ist, aber die Implementierung einer Schnittstelle zu ihrer Verwendung dieses Implementierungsdetail in Ihrer exportierten API offenlegt.

En public|private static final TYPE NAME = VALUE; Muster ist eine gute Möglichkeit, eine Konstante zu deklarieren. Persönlich denke ich, dass es besser ist, eine separate Klasse zu vermeiden, um alle Konstanten unterzubringen, aber ich habe noch nie einen Grund gesehen, dies nicht zu tun, abgesehen von persönlichen Vorlieben und Stil.

Wenn Ihre Konstanten gut als Aufzählung modelliert werden können, sollten Sie die enum Struktur in 1.5 oder höher verfügbar.

Wenn Sie eine frühere Version als 1.5 verwenden, können Sie immer noch typsichere Aufzählungen mit normalen Java-Klassen erstellen. (Siehe diese Seite für mehr darüber).

5voto

Ich ziehe es vor, Getter statt Konstanten zu verwenden. Diese Getter können konstante Werte zurückgeben, z. B. public int getMaxConnections() {return 10;} aber alles, was die Konstante benötigt, wird über einen Getter laufen.

Ein Vorteil ist, dass Sie, wenn Ihr Programm über die Konstante hinauswächst - wenn Sie feststellen, dass sie konfigurierbar sein muss - einfach ändern können, wie der Getter die Konstante zurückgibt.

Ein weiterer Vorteil ist, dass man nicht alles, was die Konstante verwendet, neu kompilieren muss, um sie zu ändern. Wenn Sie auf ein statisches endgültiges Feld verweisen, wird der Wert dieser Konstante in jeden Bytecode kompiliert, der auf sie verweist.

4voto

Lorand Bendig Punkte 10540

Basierend auf den obigen Kommentaren denke ich, dass dies ein guter Ansatz ist, um die altmodische globale Konstantenklasse (mit öffentlichen statischen finalen Variablen) in ihr enum-ähnliches Äquivalent zu ändern:

public class Constants {

    private Constants() {
        throw new AssertionError();
    }

    public interface ConstantType {}

    public enum StringConstant implements ConstantType {
        DB_HOST("localhost");
        // other String constants come here

        private String value;
        private StringConstant(String value) {
            this.value = value;
        }
        public String value() {
            return value;
        }
    }

    public enum IntConstant implements ConstantType {
        DB_PORT(3128), 
        MAX_PAGE_SIZE(100);
        // other int constants come here

        private int value;
        private IntConstant(int value) {
            this.value = value;
        }
        public int value() {
            return value;
        }
    }

    public enum SimpleConstant implements ConstantType {
        STATE_INIT,
        STATE_START,
        STATE_END;
    }

}

Dann kann ich sie an wie verweisen:

Constants.StringConstant.DB_HOST

3voto

Bradley Harris Punkte 922

Ein guter objektorientierter Entwurf sollte nicht viele öffentlich verfügbare Konstanten benötigen. Die meisten Konstanten sollten in der Klasse gekapselt sein, die sie für ihre Arbeit benötigt.

2voto

djangofan Punkte 26852

Zu dieser Frage gibt es eine Reihe von Meinungen. Zunächst einmal werden Konstanten in Java im Allgemeinen als öffentlich, statisch und endgültig deklariert. Im Folgenden werden die Gründe dafür genannt:

public, so that they are accessible from everywhere
static, so that they can be accessed without any instance. Since they are constants it
  makes little sense to duplicate them for every object.
final, since they should not be allowed to change

Ich würde niemals eine Schnittstelle für einen CONSTANTS-Zugriff bzw. ein CONSTANTS-Objekt verwenden, einfach weil von Schnittstellen im Allgemeinen erwartet wird, dass sie implementiert werden. Würde das nicht komisch aussehen?

String myConstant = IMyInterface.CONSTANTX;

Stattdessen würde ich zwischen verschiedenen Möglichkeiten wählen, die auf einigen kleinen Kompromissen beruhen, und so hängt es davon ab, was Sie brauchen:

1.  Use a regular enum with a default/private constructor. Most people would define 
     constants this way, IMHO.
  - drawback: cannot effectively Javadoc each constant member
  - advantage: var members are implicitly public, static, and final
  - advantage: type-safe
  - provides "a limited constructor" in a special way that only takes args which match
     predefined 'public static final' keys, thus limiting what you can pass to the
     constructor

2.  Use a altered enum WITHOUT a constructor, having all variables defined with 
     prefixed 'public static final' .
  - looks funny just having a floating semi-colon in the code
  - advantage: you can JavaDoc each variable with an explanation
  - drawback: you still have to put explicit 'public static final' before each variable
  - drawback: not type-safe
  - no 'limited constructor'

3.  Use a Class with a private constructor:
  - advantage: you can JavaDoc each variable with an explanation
  - drawback: you have to put explicit 'public static final' before each variable
  - you have the option of having a constructor to create an instance
     of the class if you want to provide additional functions related
     to your constants 
     (or just keep the constructor private)
  - drawback: not type-safe

4. Using interface:
  - advantage: you can JavaDoc each variable with an explanation
  - advantage: var members are implicitly 'public static final'
  - you are able to define default interface methods if you want to provide additional
     functions related to your constants (only if you implement the interface)
  - drawback: not type-safe

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