2009-03-25 6 views
5

Une fois qu'une classe est chargée, est-il possible d'invoquer à nouveau des initialiseurs statiques?Appel de l'initialiseur statique à nouveau

public class Foo { 

    static { 
     System.out.println("bar"); 
    } 

} 

Edit:

J'ai besoin d'invoquer l'initialiseur statique parce que je n'ai pas écrit la classe d'origine et la logique que je dois appeler est mis en œuvre dans le initialiseur statique.

Répondre

4

une circonstance dans laquelle la logique serait exécuté plusieurs fois est si la classe est chargée plusieurs fois par différents classloaders. Notez que dans ce cas, ils sont essentiellement des classes différentes.

Généralement, cependant, ce sont des offres one-shot. Si vous voulez être capable d'invoquer la logique plusieurs fois, faites ce que les autres ont suggéré et mettez-le dans une méthode statique.

+0

J'essayais de trouver une référence sur les chargeurs de classe, mais je n'en trouvais pas de bonne. Avez-vous une? –

+0

Hélas, non. Mes connaissances sont bricolées à partir des spécifications de la VM, du javadoc, des manuels du serveur et de diverses sources Internet. Vous pourriez faire pire que Googling "developerWorks" et "ClassLoader". – McDowell

10

Placez le code d'initialisation dans une méthode statique publique séparée, de sorte que vous puissiez l'appeler à partir de l'initialiseur statique et d'ailleurs?

+0

Je ne peux pas modifier le code. C'est dans une bibliothèque tierce et je n'ai pas l'intention de créer ma propre distribution avec le code dans une méthode statique régulière. :) La solution que j'ai utilisée était de copier et coller le code dans une autre classe afin qu'il puisse être dans une méthode statique régulière. Mais je n'ai pas aimé ça.DRY – Kalecser

+0

Hm ... alors ma prochaine question est, pourquoi cette classe 3ème partie a-t-elle de la logique dans un initialiseur statique que vous pourriez vouloir réinventer ?! –

+0

Il va charger et traiter un fichier de configuration XML sur l'initialiseur statique, je veux recharger le fichier XML. – Kalecser

4

Je suis d'accord avec la réponse d'Earwicker. Juste extraire l'initialisation statique à une méthode statique séparée.

public class Foo { 

    static { 
     Foo.initialize(); 
    } 

    public static void initialize() { 
     System.out.println("bar"); 
    } 

} 
+0

Pourquoi la downvote? La personne qui m'a rabaissé peut-elle expliquer pourquoi? –

0

Vous pouvez essayer d'étendre la classe qui contient le code statique, puis placer votre propre initialiseur statique. Pas tout à fait sûr si cela fonctionne, mais:

public class OldBadLibraryClass { 
    static { 
     System.out.println("oldBadLibrary static init"); 
    } 
} 

//next file 

public class MyBetterClass extends OldBadLibraryClass { 
    static { 
     System.out.println("MyBetterClass init"); 
    } 
} 


public class Test { 
    public static void main(String[] args) { 
     new MyBetterClass(); 
    } 
} 

voir si les impressions ci-dessus dans l'ordre que vous attendez. Sur ma machine, ça a marché.

Bien que ce soit totalement un hack, et est assez fragile. Il serait vraiment préférable de modifier l'ancienne classe pour avoir une méthode init() qui peut être surchargée.

0

Si vous voulez vraiment la réponse exacte à votre question, la réponse est non. Il n'est pas possible d'invoquer un initialiseur statique ou un instanceInitializer via une réflexion.

Les docs dit clairement:

pour getDeclaredMethod(String name):

Si le nom est "<initialisation>" ou "<clinit>" un NoSuchMethodException est élevé.

pour getDeclaredMethods():

La méthode d'initialisation des classes ne sont pas inclus dans le tableau retourné.

Donc non, il n'est pas possible de l'invoquer, même par réflexion.

Questions connexes