Ich stamme aus C und C ++ und fand die vernünftige Verwendung von typedef
unglaublich hilfreich. Kennen Sie eine Möglichkeit, ähnliche Funktionen in Java zu erreichen, sei es ein Java-Mechanismus, ein Java-Muster oder eine andere effektive Methode, die Sie verwendet haben?
244
public interface ScopeFactory { <Scope extends Map<String, Object>> Scope create(...) throws Exception; }
Antworten:
Java hat primitive Typen, Objekte und Arrays und das war's. Keine typedefs.
quelle
typedef
neu zu definieren ,boolean
zubool
.typedef int PlayerID
die folgende hinzuzufügen: Dadurch kann der Compiler sicherstellen, dass PlayerIDs nicht austauschbar mit anderen Ints verwendet werden, und Code ist für Menschen viel lesbarer . Im Grunde ist es wie eine Aufzählung, aber ohne einen begrenzten Satz von Werten.typedef MegaLongTemplateClass<With, Many, Params> IsShorten;
.typedef
aktiviert so etwas nicht. Es gibt nur einen anderen Namen für einen Typ.int
und diese ändern müssenlong
, müssen Sie sie an jeder Stelle im Code ändern, an der Sie mit der ID arbeiten. Wenn Sie diestypedef
getan hätten , müssten Sie es nur an einer Stelle ändern.Wenn Sie dies meinen, können Sie einfach die Klasse erweitern, die Sie eingeben möchten, z. B.:
quelle
typedef
hat keines der Probleme, die der Artikel für diese gefälschten Klassen beschreibt (und sie sind sehr real).final
Klassen verwenden können.In Java gibt es ab 1.6 kein typedef. Sie können lediglich eine Wrapper-Klasse für das erstellen, was Sie möchten, da Sie keine endgültigen Klassen (Integer, Double usw.) unterordnen können.
quelle
Wie andere bereits erwähnt haben,
gibt es in Java keinen typedef-Mechanismus.
Ich unterstütze auch keine "gefälschten Klassen" im Allgemeinen, aber es sollte hier keine allgemeine strenge Faustregel geben:
Wenn Ihr Code zum Beispiel immer und immer wieder einen "generischen Typ" verwendet, zum Beispiel:
Sie sollten auf jeden Fall in Betracht ziehen, eine Unterklasse für diesen Zweck zu haben.
Ein anderer Ansatz, den man in Betracht ziehen kann, besteht beispielsweise darin, eine Verzögerung in Ihrem Code zu haben, wie:
Verwenden Sie dann in Ihrem Code NameToNumbers und haben Sie eine Pre-Compiler-Aufgabe (ANT / Gradle / Maven), um relevanten Java-Code zu verarbeiten und zu generieren.
Ich weiß, dass dies für einige Leser dieser Antwort seltsam klingen mag, aber so viele Frameworks haben "Anmerkungen" vor JDK 5 implementiert, genau das macht das Projekt lombok und andere Frameworks.
quelle
Wirklich, die einzige Verwendung von typedef, die auf Javaland übertragen wird, ist Aliasing - das heißt, der gleichen Klasse werden mehrere Namen gegeben. Das heißt, Sie haben eine Klasse "A" und möchten, dass sich "B" auf dasselbe bezieht. In C ++ würden Sie "typedef BA" ausführen.
Leider unterstützen sie es einfach nicht. Wenn Sie jedoch alle beteiligten Typen steuern, KÖNNEN Sie auf Bibliotheksebene einen bösen Hack ausführen - Sie erweitern entweder B von A oder lassen B A implementieren.
quelle
typedef
wäre auch nützlich, Aliase für Aufrufe generischer Typen zu erstellen. Zum Beispiel:typedef A<Long,String> B;
(Dies mag ein Sonderfall dessen sein, was Sie beschrieben haben, aber es zeigt den Reiz der Idee etwas deutlicher).real_t
fürdouble
undbool
fürboolean
.Vielleicht könnte dies ein weiterer möglicher Ersatz sein:
quelle
myMap
Instanz des Typs definierenMyMap
, können Sie die tatsächliche HashMap nur durch EingabemyMapInstance.value.SomeOperation()
anstelle von bearbeitenmyMapInstance.SomeOperation()
. Das ist ärgerlich, nicht wahr?Wie in anderen Antworten erwähnt, sollten Sie das Pseudo-Typedef-Antimuster vermeiden . Typedefs sind jedoch immer noch nützlich, auch wenn dies nicht der Weg ist, um sie zu erreichen. Sie möchten zwischen verschiedenen abstrakten Typen mit derselben Java-Darstellung unterscheiden. Sie möchten Zeichenfolgen, bei denen es sich um Kennwörter handelt, nicht mit Zeichenfolgen verwechseln, die Straßenadressen sind, oder Ganzzahlen, die einen Versatz darstellen, mit Zeichenfolgen, die einen absoluten Wert darstellen.
Mit dem Checker Framework können Sie ein typedef abwärtskompatibel definieren. Ich arbeite sogar für primitive Klassen wie
int
und Abschlussklassen wieString
. Es hat keinen Laufzeitaufwand und unterbricht keine Gleichheitstests.Abschnitt Typaliasnamen und Typedefs im Checker Framework-Handbuch beschreiben verschiedene Möglichkeiten zum Erstellen von Typedefs, abhängig von Ihren Anforderungen.
quelle
Kotlin unterstützt Typ-Aliase https://kotlinlang.org/docs/reference/type-aliases.html . Sie können Typen und Funktionstypen umbenennen.
quelle
In einigen Fällen kann eine verbindliche Anmerkung genau das sein, wonach Sie suchen:
https://github.com/google/guice/wiki/BindingAnnotations
Wenn Sie sich nicht auf Guice verlassen möchten, ist möglicherweise nur eine regelmäßige Anmerkung ausreichend.
quelle
Sie können eine Aufzählung verwenden, obwohl dies semantisch etwas anders ist als eine typedef, da nur eine eingeschränkte Menge von Werten zulässig ist. Eine andere mögliche Lösung ist eine benannte Wrapper-Klasse, z
Dies scheint jedoch viel klobiger zu sein, insbesondere angesichts der Tatsache, dass aus dem Code nicht hervorgeht, dass die Klasse keine andere Funktion als einen Alias hat.
quelle
Mit Typedef können Elemente implizit Typen zugewiesen werden, die sie nicht sind. Einige Leute versuchen, dies mit Erweiterungen zu umgehen. Lesen Sie hier bei IBM, um zu erklären, warum dies eine schlechte Idee ist.
Bearbeiten: Während starke Typinferenz eine nützliche Sache ist, denke ich nicht (und hoffe wir werden nicht), dass
typedef
es hässlichen Kopf in verwalteten Sprachen aufzieht (jemals?).Bearbeiten 2: In C # können Sie eine using-Anweisung wie diese oben in einer Quelldatei verwenden. Es wird verwendet, damit Sie den zweiten angezeigten Punkt nicht ausführen müssen. Die Namensänderung wird nur angezeigt, wenn ein Bereich eine Namenskollision zwischen zwei Typen einführt. Das Umbenennen ist auf eine Datei beschränkt, außerhalb derer jeder verwendete Variable- / Parametertyp unter seinem vollständigen Namen bekannt ist.
quelle
In Java ist typedef nicht erforderlich. Alles ist ein Objekt außer den Grundelementen. Es gibt keine Zeiger, nur Referenzen. Die Szenarien, in denen Sie normalerweise typedefs verwenden würden, sind Instanzen, in denen Sie stattdessen Objekte erstellen.
quelle
UnmodifiableDirectedGraph<IncrediblyFancyEdgeType, IncrediblyFancyAbstractNode.EvenFancierConcreteNode>
oderIncrediblyFancyGraph
? Ich kann mich immer auf die Definition beziehen, um herauszufinden, worum es eigentlich geht. Auf diese Weise kann ich auch sicher sein, dass ichUnmodifiableDirectedGraph<IncrediblyFancyEdge,IncredilyFancyAbstractNode.SlightlyLessFancyConcreteNode>
aus purer Langeweile nichts verpassen werde .Enterprise
.