Les problèmes de l'initialisation d'une variable finale en Java
Je continuer à courir dans de légères variations d'un problème en Java et il commence à faire de moi, et je ne peux pas vraiment penser à un bon moyen de les contourner.
J'ai une propriété de l'objet, qui est définitive, mais dynamique. C'est, je veux la valeur de la constante une fois affecté, mais la valeur peut être différente à chaque exécution. Donc, je déclare la classe de niveau variable au début de la classe - dire private final FILE_NAME;
. Ensuite, dans le constructeur, je lui assigner une valeur - dire FILE_NAME = buildFileName();
Le problème commence quand j'ai le code dans le buildFileName()
méthode lève une exception. J'ai donc essayer quelque chose comme cela dans le constructeur:
try{
FILE_NAME = buildFileName();
}
catch(Exception e){
...
System.exit(1);
}
Maintenant, j'ai une erreur "Le vide final le champ nom de fichier peut ne pas avoir été initialisé." C'est là que je commence à être un peu agacé à Java strict du compilateur. Je sais que ce ne sera pas un problème parce que si il arrive à l'attraper le programme va fermer... Mais le compilateur ne sait pas qui et donc ne pas permettre à ce code. Si j'essaie d'ajouter un mannequin affectation à la pêche, je get - "Le dernier champ FILE_NAME peut-être déjà été assigné." J'ai clairement ne peut pas affecter une valeur par défaut avant le try-catch parce que je ne peut l'attribuer à la fois.
Des idées...?
- Tu veux dire
private static final FILE_NAME;
? - Hawtin - pas. Pourquoi devrait-il être statique?
- Je suis d'accord avec Ryan réponse (et voté de façon appropriée). Une chose que je vais dire est... voulez-vous vraiment le Système.quitter si vous ne pouvez pas initialiser? Peut-être la meilleure idée est de les laisser à l'exception obtenir jeté de toute façon si elle n'est pas traitée, vous aurez encore sortie, mais si il y a un mécanisme de gestion en place, il peut être pris en charge correctement.
- parce que
ALL_CAPS
indique constantes (un.k.un.static final
): java.sun.com/docs/codeconv/html/CodeConventions.doc8.html#367 - Sauer - c'est une constante, mais c'est un objet de niveau constant... chaque objet peut avoir son propre nom de fichier, mais une fois mis, il ne peut pas être changé.
- exactement. Et au moins le soleil convention de nommage dit que "les variables déclarées des constantes de classe" doit être nommé avec
ALL_CAPS
. D'autres domaines, même sifinal
, devrait êtrecamelCase
avec un bas de cas du caractère de départ.
Vous devez vous connecter pour publier un commentaire.
Comment sur
Soit
Ou certains préfèrent:
Mais en l'appelant
System.exit
statique initialiser est probablement une mauvaise idée. Il va mess des tests unitaires jusqu'.final
champs d'instance il y a sournois façons de regarder la variable non initialisée avant ou après).throw new Error()
ligne ne sera jamais atteint et qui est juste là pour apaiser le compilateur. Je ne vois pas l'avantage de cette réponse par rapport à celui que j'ai posté et Ryan Elkin est - laissez-moi savoir si vous pensez qu'il y a quelque chose qui m'échappeÀ la réflexion, je crois que je viens de trouvé une solution! - utiliser une variable intermédiaire.
Ne sais pas pourquoi il m'a fallu tellement de temps pour penser à cela...
= ""
.null
soit. IL NE DEVRAIT PAS ÊTRE AFFECTÉ.fileName
à quelque chose. Si vous n'en avez pas, vous obtiendrezThe local variable fileName may not have been initialized
erreur de compilation.null
est certainement un bon choix.fileName()
de la fonctionthrow Error( )
aprèsSystem.exit( 1)
. Pour le compilateurSystem.exit
est juste une autre fonction et il a besoin d'un terminator spécial dans le bloc. Certes, vous pourriez mettrefileName = null;
aprèsSystem.exit
au lieu de l'initialisation à la déclaration en ligne. BTW, je pense que votre solution est plus propre.Je serais personnellement il suffit de jeter une Erreur -- si votre flux d'erreur est bien conçu, le Système.exit() devrait être redondante. Votre programme, vraisemblablement, n'a pas la charrue dans le désert si une Erreur est levée...?
Dans le même sens que l'OP problème, je devais être capable de trouver un moyen pour affecter des valeurs à la finale de champs à être lue dans une .fichier de propriétés sur le système de fichiers, de sorte que les valeurs ne pouvait pas être connu par mon application jusqu'à ce qui s'est passé. À l'aide de la généralisation de l'appel de méthode pour affecter la valeur après la lecture du contenu de l' .les propriétés de fichier dans les Propriétés de l'objet sur l'application de démarrage a été un Hail Mary pass qui, heureusement, a fonctionné. Il limite également le pas. de fois que le fichier doit être lu à la fois par l'application devient chargé dans la mémoire tout simplement par le code de vérification pour voir si les Propriétés de l'objet est ou n'est pas null. Mais bien sûr, une fois attribué, le final de la valeur du champ ne peut pas être modifié, sauf en modifiant son "final" de l'état, par manuipulating le domaine de la modification de la définition au moment de l'exécution (comme discuté dans d'autres lieux ici DONC, comme https://stackoverflow.com/a/3301720/1216686 - sournois, mais je l'adore!). Exemple de Code, avec typique erreur d'exécution de la vérification comme pour les Npe omis par souci de concision:
Cela vous permet d'externaliser les propriétés de lire dans l'application et marque encore les champs utilisés pour tenir leurs valeurs en "finale". Il permet également de vous garantir une valeur retournée par la dernière valeur de champ depuis getProperty() dans la classe de Propriétés permet à la méthode d'appel du code pour passer à une valeur par défaut à utiliser dans le cas où la propriété de la paire clé-valeur n'a pas été trouvé dans la externe .fichier de propriétés.