¿Qué beneficios ofrece main(...) sobre el uso de un inicializador estático como pseudopunto de entrada?

StackOverflow https://stackoverflow.com/questions/1298342

Pregunta

El punto de entrada a un programa en Java suele ser algo como esto


    // MyMain.java
    public class MyMain{  
      //whatever 
        public static void main(String args[]){ 
        System.out.println("balderdash");
        }
    }

Sin embargo, dado que solo existe un SOP en main, la clase anterior puede ser así


    // MyMain.java
    public class MyMain{
        //whatever
        static {    
        System.out.println("balderdash");
        }
    }

Una ventaja obvia de usar main(...) es que se pueden pasar argumentos al programa.Otro (supongo que aquí) puede tener que ver con que el recolector de basura trate los objetos creados dentro de un bloque estático de manera diferente.

¿Qué otros beneficios se obtienen al usar el punto de entrada definido por el lenguaje: public static void main( String args[] ) en lugar de usar un inicializador estático?

PD.Los fragmentos anteriores son solo para ilustración y es posible que no sean compilables.

¿Fue útil?

Solución

  • Puede probarlo o llamar desde otras aplicaciones.
  • Es lo que los demás esperan.
  • Si se ejecuta toda su aplicación en el contexto de un inicializador estático, I sospechoso usted efectivamente a cabo un bloqueo en ese tipo durante todo el tiempo. Si cualquier otro hilo intenta llamar a un método estático en la misma clase, bloqueará. Ese es el tipo de problema que se obtiene cuando se intenta utilizar un concepto de una manera inesperada - es sólo conceptualmente "equivocado". La inicialización de la clase simplemente no es lo mismo que ejecutar una aplicación.

EDIT: He aquí un ejemplo de ese problema:

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!");
        }
    }
}

Salida:

Starting new thread...
Thread started. Sleeping
Calling someStaticMethod
Finished sleeping
In someStaticMethod
someStaticMethod returned
In main. Sleeping again.

Tenga en cuenta la forma en la llamada a someStaticMethod del nuevo hilo tiene que esperar hasta que el inicializador estático ha terminado antes de que llegue a funcionar.

Otros consejos

Puede llamar main() para otros objetos de cualquier otro lugar en el código tantas veces como desee. Un inicializador estático sólo se va a ejecutar ni una sola vez. Además, se puede pasar parámetros desde la línea de comandos en main().

Dos grandes puntos positivos para main() en mi libro.

La razón principal por la que es mejor utilizar main() es que usted puede tener varios métodos principales en su aplicación (en diferentes clases). Si se carga una clase, main() no se ejecuta automáticamente, mientras que los bloques de código static siempre se ejecutan exactamente una vez en la primera vez que se carga una clase y no hay manera de evitarlo.

OK, voy a admitir que no he probado con una clase estática inicializado, pero no volvería a escribir

java StaticInitializedClass

en la línea de comandos imprimir

Exception in thread "main" java.lang.NoSuchMethodError: main

ya que no tiene un método main(String[])?

No olvidemos sobre el mantenimiento. Cuando alguien va a cambiar su código que siempre van a buscar un método main () para iniciar el programa. A menos que haya alguna razón no se puede conseguir alrededor (y supongo que no lo es) entonces yo sólo tiene que utilizar el método principal.

Si usted no tiene ningún punto de entrada, no se puede ejecutar cualquier cosa. Si usted tiene muchos puntos de entrada (muchos métodos principales), usuario que inicia sus controles de las aplicaciones que se ejecutan por la línea de comandos.
Por otro lado bloques de inicialización estática se ejecutan cuando se carga la clase. Controlar qué clase se carga y el orden de carga de clases (y de la ejecución de sus bloques de inicialización estática) es mucho más difícil de controlar. Esa es una razón suficiente para no poner a mucha lógica a los bloques de inicialización estática. Haces algo más difícil de leer y entender y en la recompensa que recibe algo más difícil de usar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top