Quels sont les avantages principaux (...) fournir sur l'aide d'un initialiseur statique comme un pseudo point d'entrée?
-
18-09-2019 - |
Question
Le point d'entrée dans un programme en Java est généralement quelque chose comme ceci
// MyMain.java
public class MyMain{
//whatever
public static void main(String args[]){
System.out.println("balderdash");
}
}
Cependant, comme il n'y a que celui SOP dans le principal, la classe ci-dessus peut être comme celui-ci à la place
// MyMain.java
public class MyMain{
//whatever
static {
System.out.println("balderdash");
}
}
Un avantage évident à l'utilisation principale (...) est que les arguments peuvent être passés dans le programme. Une autre (je devine ici) peut avoir à faire avec les objets traitement des déchets créés collecter dans un bloc statique différemment.
Quels sont les autres avantages découlant de l'utilisation du point d'entrée de langue défini -. Public void main (String statiques args []) au lieu d'utiliser un initialiseur statique
p.s. Les extraits ci-dessus sont données à titre indicatif, et ne peuvent être compilable
La solution
- Vous pouvez tester ou appeler d'autres applications.
- Il est ce que les autres attendront.
- Si vous exécutez votre application entière dans le contexte d'un initialiseur statique, I suspect vous efficacement tiendrez un verrou sur ce type pour tout le temps. Si un autre thread essaie d'appeler une méthode statique dans la même classe, il va bloquer. Voilà le genre de problème que vous obtenez lorsque vous essayez d'utiliser un concept d'une manière inattendue - il est juste sur le plan conceptuel « mal ». Initialisation la classe est tout simplement pas la même chose que l'exécution d'une application.
EDIT: Voici un exemple de ce problème:
class SampleTask implements Runnable
{
public void run()
{
System.out.println("Calling someStaticMethod");
Test.someStaticMethod();
System.out.println("someStaticMethod returned");
}
}
public class Test
{
static
{
System.out.println("Starting new thread...");
new Thread(new SampleTask()).start();
System.out.println("Thread started. Sleeping");
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
System.out.println("Interrupted!");
}
System.out.println("Finished sleeping");
}
public static void someStaticMethod()
{
System.out.println("In someStaticMethod");
}
public static void main(String[] args)
{
System.out.println("In main. Sleeping again.");
try
{
Thread.sleep(5000);
}
catch (InterruptedException e)
{
System.out.println("Interrupted!");
}
}
}
Sortie:
Starting new thread...
Thread started. Sleeping
Calling someStaticMethod
Finished sleeping
In someStaticMethod
someStaticMethod returned
In main. Sleeping again.
Notez comment l'appel à someStaticMethod
du nouveau thread doit attendre jusqu'à ce que l'initialiseur statique terminée avant qu'il arrive à courir.
Autres conseils
Vous pouvez appeler main()
pour d'autres objets de partout ailleurs dans votre code autant de fois que vous le souhaitez. Un initialiseur statique ne va jamais fonctionner une fois. En outre, vous pouvez passer des paramètres de la ligne de commande en main()
.
Deux grands points positifs pour main()
dans mon livre.
La principale raison pour laquelle il est préférable d'utiliser main()
est que vous pouvez avoir plusieurs méthodes principales dans votre application (dans les différentes classes). Si vous chargez une classe, main()
n'est pas exécuté automatiquement lors static
blocs de code sont toujours exécutées exactement une fois à la première fois une classe est chargée et il n'y a aucun moyen d'empêcher cela.
OK, je dois admettre que je ne l'ai pas essayé avec une classe statique initialisé, mais ne tapant
java StaticInitializedClass
sur la ligne de commande imprimer
Exception in thread "main" java.lang.NoSuchMethodError: main
car il ne dispose pas d'une méthode main(String[])
?
Il ne faut pas oublier maintenabilité. Quand quelqu'un d'autre va changer votre code qu'ils vont toujours chercher une méthode main () pour démarrer le programme. À moins d'une raison quelconque, vous ne pouvez pas vous déplacer (et je suppose qu'il n'y a pas) alors je voudrais simplement utiliser la méthode principale.
Si vous n'avez pas de point d'entrée, vous ne pouvez pas exécuter quoi que ce soit. Si vous avez beaucoup de points d'entrée (plusieurs méthodes principales), utilisateur qui lance vos contrôles d'application qui seront exécutés par la ligne de commande.
Sur les autres blocs d'initialisation statique main sont exécutées lorsque la classe est chargée. Contrôle des classe est chargée et l'ordre de chargement de classe (et de l'exécution de leurs blocs d'initialisation statique) est beaucoup plus difficile à contrôler. C'est une raison suffisante de ne pas mettre à beaucoup de logique à des blocs d'initialisation statiques. Vous faites quelque chose de plus difficile à lire et à comprendre et en récompense que vous recevez quelque chose de plus difficile à utiliser.