Venant d'un milieu C et C ++, j'ai trouvé que l'utilisation judicieuse de typedef
était incroyablement utile. Connaissez-vous un moyen d'obtenir des fonctionnalités similaires en Java, que ce soit un mécanisme, un modèle Java ou tout autre moyen efficace que vous avez utilisé?
244
public interface ScopeFactory { <Scope extends Map<String, Object>> Scope create(...) throws Exception; }
Réponses:
Java a des types, des objets et des tableaux primitifs et c'est tout. Pas de typedefs.
la source
typedef
redéfinirboolean
àbool
.typedef int PlayerID
ce qui permet au compilateur de s'assurer que les PlayerID ne sont pas utilisés de manière interchangeable avec d'autres entrées, et cela rend également le code beaucoup plus lisible pour les humains . Fondamentalement, c'est comme une énumération mais sans un ensemble limité de valeurs.typedef MegaLongTemplateClass<With, Many, Params> IsShorten;
.typedef
ne permet rien de tel. Il donne juste un autre nom pour un type.int
et que vous devez le changerlong
, vous devez le changer à chaque endroit du code où vous travaillez avec l'ID. Si vous l'aviez faittypedef
, vous n'auriez qu'à le changer à un seul endroit.Si c'est ce que vous voulez dire, vous pouvez simplement étendre la classe que vous souhaitez taper, par exemple:
la source
typedef
n'a aucun des problèmes que l'article décrit pour ces fausses classes (et ils sont très réels).final
classes.Il n'y a pas de typedef en java à partir de 1.6, ce que vous pouvez faire est de créer une classe wrapper pour ce que vous voulez car vous ne pouvez pas sous-classer les classes finales (Integer, Double, etc.)
la source
Comme d'autres l'ont déjà mentionné,
il n'y a pas de mécanisme typedef en Java.
Je ne supporte pas non plus les "fausses classes" en général, mais il ne devrait pas y avoir de règle générale stricte ici:
si votre code, par exemple, utilise encore et encore et encore un "type générique" par exemple:
Vous devriez certainement envisager d'avoir une sous-classe à cet effet.
Une autre approche que l'on peut envisager, est par exemple d'avoir dans votre code une décélération comme:
Ensuite, utilisez dans votre code NameToNumbers et disposez d'une tâche de précompilation (ANT / Gradle / Maven) pour traiter et générer le code java pertinent.
Je sais que pour certains des lecteurs de cette réponse, cela peut sembler étrange, mais c'est le nombre de frameworks qui ont implémenté des "annotations" avant JDK 5, c'est ce que fait le projet lombok et d'autres frameworks.
la source
Vraiment, la seule utilisation de typedef qui se répercute sur Javaland est l'aliasing, c'est-à-dire donner à la même classe plusieurs noms. Autrement dit, vous avez une classe "A" et vous voulez que "B" se réfère à la même chose. En C ++, vous feriez "typedef BA;"
Malheureusement, ils ne le soutiennent tout simplement pas. Cependant, si vous contrôlez tous les types impliqués, vous POUVEZ tirer un méchant hack au niveau de la bibliothèque - vous étendez B à partir de A ou B implémentez A.
la source
typedef
serait également utile pour créer des alias pour les appels de types génériques. Par exemple:typedef A<Long,String> B;
(cela peut être un cas particulier de ce que vous avez décrit, mais cela montre un peu plus clairement l'attrait de l'idée).real_t
pourdouble
etbool
pourboolean
.Cela pourrait peut-être être un autre remplacement possible:
la source
myMap
instance de typeMyMap
, vous ne pouvez opérer sur HashMap réel qu'en tapant à lamyMapInstance.value.SomeOperation()
place demyMapInstance.SomeOperation()
. C'est ennuyeux, non?Comme indiqué dans d'autres réponses, vous devez éviter l' anti-motif pseudo-typedef . Cependant, les typedefs sont toujours utiles même si ce n'est pas le moyen de les atteindre. Vous souhaitez faire la distinction entre différents types abstraits qui ont la même représentation Java. Vous ne voulez pas mélanger les chaînes qui sont des mots de passe avec celles qui sont des adresses de rue, ou des entiers qui représentent un décalage avec ceux avec ceux qui représentent une valeur absolue.
Le Checker Framework vous permet de définir un typedef d'une manière rétrocompatible. Je travaille même pour les classes primitives telles que
int
et les classes finales telles queString
. Il n'a pas de temps d'exécution et ne rompt pas les tests d'égalité.La section Alias de type et typedefs du manuel Checker Framework décrit plusieurs façons de créer des typedefs, selon vos besoins.
la source
Kotlin prend en charge les alias de type https://kotlinlang.org/docs/reference/type-aliases.html . Vous pouvez renommer des types et des types de fonction.
la source
Dans certains cas, une annotation de liaison peut être exactement ce que vous recherchez:
https://github.com/google/guice/wiki/BindingAnnotations
Ou si vous ne voulez pas dépendre de Guice, une annotation régulière peut suffire.
la source
Vous pouvez utiliser un Enum, bien que ce soit sémantiquement un peu différent d'un typedef en ce qu'il n'autorise qu'un ensemble restreint de valeurs. Une autre solution possible est une classe wrapper nommée, par exemple
mais cela semble beaucoup plus maladroit, d'autant plus qu'il n'est pas clair d'après le code que la classe n'a pas d'autre fonction que d'alias.
la source
Typedef permet aux éléments d'être implicitement affectés aux types qu'ils ne sont pas. Certaines personnes essaient de contourner ce problème avec des extensions; lisez ici chez IBM pour une explication de pourquoi c'est une mauvaise idée.
Edit: Bien que l'inférence de type forte soit une chose utile, je ne pense pas (et j'espère que nous ne le verrons pas) voir
typedef
élever sa tête laide dans les langages gérés (jamais?).Edit 2: En C #, vous pouvez utiliser une instruction using comme celle-ci en haut d'un fichier source. Il est utilisé pour que vous n'ayez pas à faire le deuxième élément affiché. La seule fois où vous voyez le changement de nom, c'est quand une portée introduit une collision de noms entre deux types. Le changement de nom est limité à un fichier, en dehors duquel chaque type de variable / paramètre qui l'a utilisé est connu sous son nom complet.
la source
Il n'y a pas besoin de typedef en Java. Tout est un objet sauf les primitives. Il n'y a pas de pointeurs, seulement des références. Les scénarios dans lesquels vous utiliseriez normalement des typedefs sont des instances dans lesquelles vous créez des objets à la place.
la source
UnmodifiableDirectedGraph<IncrediblyFancyEdgeType, IncrediblyFancyAbstractNode.EvenFancierConcreteNode>
ouIncrediblyFancyGraph
? Je peux toujours me référer à la définition pour savoir de quoi il s'agit réellement. De cette façon, je peux également être sûr de ne pas manquerUnmodifiableDirectedGraph<IncrediblyFancyEdge,IncredilyFancyAbstractNode.SlightlyLessFancyConcreteNode>
l'ennui.Enterprise
.