D'après ma compréhension du langage Java, les variables statiques peuvent être initialisées dans static initialization block
.
Cependant, lorsque j'essaie d'implémenter cela dans la pratique (les variables static
qui sont aussi final
), j'obtiens l'erreur indiquée dans la capture d'écran ci-dessous:
Oui, bien sûr: les variables static final
peuvent être initialisées dans un bloc statique mais .... vous avez des GOTO implicites dans cet exemple (try/catch
est essentiellement un 'Capture GOTO si quelque chose de mauvais arrive' ).
Si une exception est levée, vos variables final
ne seront pas initialisées.
Notez que l'utilisation de constructions statiques va à l'encontre du dogme orienté objet. Cela peut compliquer vos tests et rendre le débogage plus difficile.
Vous pouvez le faire, mais vous devez quitter le bloc statique en lançant une exception. Vous pouvez rediffuser l'exception qui a été interceptée ou une nouvelle. Généralement, cette exception doit être une RuntimeException
. Vous ne devriez vraiment pas attraper une Exception
générique, mais des exceptions plus spécifiques qui pourraient être levées depuis votre bloc try
. Enfin, si un initialiseur statique lève une exception, il rendra la classe inutilisable pendant cette exécution spécifique, car la machine virtuelle Java ne tentera d'initialiser votre classe qu'une seule fois. Toute tentative ultérieure d'utilisation de cette classe entraînera une autre exception, telle que NoClassDefFoundError
.
Donc, pour que ça fonctionne, votre initialiseur devrait lire quelque chose comme ceci:
static {
try {
...
} catch (Exception e) {
e.PrintStackTrace();
throw new InitializationFailedException("Could not init class.", e);
}
}
En supposant que InitializationFailedException
est une RuntimeException
personnalisée, mais vous pouvez en utiliser une existante.
public class MyClass
{
private static final SomeClass myVar;
static
{
Object obj = null; // You could use SomeClass, but I like Object so you can reuse it
try
{
obj = new SomeClass(...);
}
catch(WhateverException err)
{
// Possibly nested try-catches here if the first exception is recoverable...
// Print an error, log the error, do something with the error
throw new ExceptionInInitializerError(err);
}
finally
{
myVar = (SomeClass) obj;
}
}
}
En supposant qu'aucun endroit en amont ne soit en mesure d'attraper un ExceptionInInitializationError ou un Exception général, le programme ne doit jamais essayer d'utiliser myVar . Si toutefois ceux-ci sont interceptés et que le programme ne se termine pas, vous devez alors coder pour surveiller et gérer myVar étant null (ou contentez-vous de NullPointerExceptions
sortir partout).
Je ne suis pas sûr qu'il existe un bon moyen de gérer cela.
Pouvez-vous mettre la déclaration dans le bloc finally?
try {
//load file
} catch(IOException e) {
// horay
} finally {
Host=config.get......
}