2010-07-02 4 views
1

Je me demandais si le code suivant est sûr.Une variable statique essayant d'accéder à une autre variable statique

public class GUIBundle { 

    // The technique known as the initialization on demand holder idiom, 
    // is as lazy as possible. 
    // http://en.wikipedia.org/wiki/Initialization_on_demand_holder_idiom 
    //private static class BundleHolder { 
    // private static final ResourceBundle bundle = ResourceBundle.getBundle("org.yccheok.jstock.data.gui"); 
    //} 
    private static final ResourceBundle bundle = ResourceBundle.getBundle("org.yccheok.jstock.data.gui"); 

    private GUIBundle() { 
    } 

    public static String getString(String key) { 
     // return BundleHolder.bundle.getString(key); 
     return bundle.getString(key); 
    } 
} 

public class SellPortfolioChartJDialog extends javax.swing.JDialog { 

    private static final String[] cNames = new String[] { 
     GUIBundle.getString("BuyPortfolioTreeTableModel_NetGainValue") 
    }; 
} 

Depuis CNAMES est dans la portée statique, est-il sûr pour qu'il puisse accéder à faisceau statique? Cela rend-il différent si j'utilise une technique d'initialisation paresseuse? Je me souviens que je suis tombé sur un article (j'ai quand même perdu l'article) sur l'ordre d'initialisation non déterministe des variables statiques. Je ne suis pas sûr si le non déterministe de l'ordre d'initialisation des variables statiques, appliqué au cas ci-dessus?

+0

Votre API retourne 'CHAINE' et vous essayez d'obtenir' String [] '- ce ne sera pas compiler de toute façon. Je pense que je comprends le thème, et je pense que cela fonctionnera (en toute sécurité) si vous corrigez votre code. –

+0

@ring il construit un String [] avec 1 String dedans. – corsiKa

+0

la méthode getString devrait avoir "return bundle.getString (key)" et un ';' pour cNames est manquant, ... et il compile, je suppose une faute de frappe à cause du code commenté :) – naikus

Répondre

4

je crois que l'ordre d'initialisation des variables statiques non déterministes (dans les différentes unités de compilation) est un C/C++ « fonction ». En Java, les variables statiques sont initialisées lorsque leur classe est chargée, et au sein d'une même classe dans leur ordre de déclaration. L'ordre est donc déterministe (au moins dans un environnement à un seul thread).

Cela garantit que ce que vous avez l'intention de faire devrait fonctionner: lorsque GUIBundle est d'abord référencé, le chargeur de classe le charge et initialise également bundle. L'appel à GUIBundle.getString() se produit uniquement après l'initialisation de la classe.

+0

Non, il est possible que l'ordre d'initialisation soit indéterminé. Joshua Bloch a plus d'informations. – DJClayworth

+0

@DJClayworth, pourriez-vous fournir une référence plus spécifique? Je n'ai pas trouvé de détails à ce sujet dans Java efficace. –

+0

Je ne peux pas trouver non plus. Pouvez-vous s'il vous plaît fournir une référence? –

0

Pour moi, c'est sans danger.

bundle est initialisé juste après GUIBuilder est chargé et par conséquent avant getString est appelé pour la première fois.

1

Cela fonctionne très bien. Je l'ai eu pour compiler en gardant le même principe mais en utilisant des classes différentes (je ne voulais pas prendre la peine de prendre vos pots ... :-).

Évidemment, il y a quelques petits problèmes, comme la façon dont vous déclarez vos String [] a besoin d'être

private static final String[] cNames = new String[] { 
     GUIBundle.getString("BuyPortfolioTreeTableModel_NetGainValue") 
    }; 
} 

Autre que cela, cela fonctionne très bien. La clé de l'utilisation de la statique dans d'autres statiques est l'ordre dans lequel ils sont déclarés. Vous ne pouvez pas faire

static Foo b = a; 
static Foo a = new Foo(); 
1

Je pense que parfaitement sûr, vous voyez parce que le quand

GUIBundle.getString 

est utilisé dans votre sous-classe JDialog, la machine virtuelle Java sera complètement initialiser (voir le chargement de spécification du langage Java, la liaison et l'initialisation) la GUIBundle de classe avant d'appeler la méthode getString, qui va initialiser tous les initialiseurs de classe (statiques) dans la classe GUIBundle.

Edit: En savoir plus à ce sujet dans spec VM: http://java.sun.com/docs/books/jvms/second_edition/html/Concepts.doc.html#16491

Questions connexes