45 votes

Java - Les variables finales peuvent-elles être initialisées dans un bloc d'initialisation statique?

Basé sur ma connaissance du langage Java, les variables peuvent être initialisées en static initialization block.

Cependant, lorsque j'essaie de mettre en pratique (static variables final également), je reçois le message d'erreur indiqué dans la capture d'écran ci-dessous.

Capture d'écran vous pouvez accéder directement à http://i49.tinypic.com/5vxfn4.jpg (dans le cas de l'image ci-dessous est unreadably petit).

5vxfn4.jpg

39voto

SyntaxT3rr0r Points 10771

Oui bien sûr: static final variables peuvent être initialisées dans un bloc statique mais .... vous avez des GOTO implicites dans cet exemple ( try/catch est essentiellement une "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.

20voto

Kevin Brock Points 4695

Vous pouvez faire cela, mais vous devez quitter le bloc statique par la levée d'une exception - vous pouvez renvoyer l'exception qui a été pris ou un nouveau. En général, cette exception doit être un RuntimeException. Vous devriez vraiment ne pas attraper un générique Exception mais plus exception spécifique(s) qui pourrait être levée à partir de l'intérieur de votre try bloc. Enfin, si un initialiseur statique déclenche une exception alors il rendra la classe inutilisable au cours de cette manche particulière parce que la JVM ne tentera d'initialiser votre classe à la fois. Les tentatives ultérieures de l'utilisation de cette classe entraînera dans une autre exception, comme NoClassDefFoundError.

Donc, pour le travail, 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 l' InitializationFailedException est une coutume RuntimeException, mais vous pouvez en utiliser un existant.

9voto

Matt Vang Points 1
 public class MyClass
{
    private statics final SomeClass myVar;

    static
    {
        Object obj = null;  // You could use SomeClass, but I like Object so you can reuse it
        try
        {
            object = 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 emplacement en amont ne soit en mesure d'attraper une exception ExceptionInInitializationError ou une exception générale, 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 le fait que myVar soit null (ou être heureux si NullPointerExceptions apparaît de partout).

Je ne suis pas sûr qu'il existe un bon moyen de gérer cela.

0voto

Stephen Points 1

Pouvez-vous mettre la déclaration dans le bloc finally?

 try {
    //load file
} catch(IOException e) {
    // horay
} finally {
    HOST=config.get......
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X