Quais os benefícios que principal (...) fornecer mais usando um estático-initializer como um ponto de entrada pseudo?

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

Pergunta

O ponto de entrada em um programa em java é tipicamente algo como isto


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

No entanto, uma vez que não é apenas o SOP no principal, a classe acima pode ser assim em vez


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

Uma vantagem óbvia de usar principal (...) é que os argumentos podem ser passados ??para o programa. Outro (eu estou supondo aqui) pode ter a ver com o collecter lixo tratar objetos criados dentro de um bloco estático diferente.

Que outros benefícios vêm de usar o ponto de entrada definido pelo idioma -. Public static void main (args String []) em vez de usar um inicializador estático

P.S. Os trechos acima são apenas para ilustração e não pode ser compilable

Foi útil?

Solução

  • Você pode testá-lo ou chamá-lo de outras aplicações.
  • É o que as outras pessoas vão esperar.
  • Se você executar sua aplicação inteira no contexto de um inicializador estático, eu suspeito você vai efetivamente ser mantendo um bloqueio nesse tipo durante todo o tempo. Se qualquer outro segmento tenta chamar um método estático na mesma classe, ele irá bloquear. Esse é o tipo de problema que você começa quando você tentar usar um conceito de uma forma inesperada - é apenas conceitualmente "errado". Inicializar a classe simplesmente não é a mesma que executar um aplicativo.

EDIT: Aqui está um exemplo desse 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!");
        }
    }
}

Output:

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

Observe como a chamada para someStaticMethod do novo segmento tem que esperar até a estática initializer terminou antes que ele chegue a ser executado.

Outras dicas

Você pode chamar main() para outros objetos de qualquer outro lugar no seu código tantas vezes quanto quiser. A estática initializer só vai sempre correr uma vez. Além disso, você pode passar parâmetros de linha de comando em main().

Dois grandes pontos positivos para main() no meu livro.

A principal razão pela qual é melhor usar main() é que você pode ter vários métodos principais em seu aplicativo (em diferentes classes). Se você carregar uma classe, main() não é executado automaticamente quando blocos de código static são sempre executadas exatamente uma vez na primeira vez que uma classe é carregada e não há maneira de evitar isso.

OK, eu admito que eu não tentei com uma classe estática inicializada, mas não iria escrever

java StaticInitializedClass

na linha de comando imprimir

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

, uma vez que não tem um método main(String[])?

Não vamos esquecer sobre manutenção. Quando alguém vai para alterar o código eles estão sempre vai procurar um método main () para iniciar o programa. A menos que haja algum motivo você não pode se locomover (e eu estou supondo que não existe), então eu iria usar apenas o método principal.

Se você não tem qualquer ponto de entrada, você não pode executar qualquer coisa. Se você tem muitos pontos de entrada (muitos principais métodos), usuário que inicia seus controles de aplicativos que serão executados pela linha de comando.
Por outro lado estática blocos de inicialização são executados quando a classe é carregada. Controlando qual classe é carregado e a ordem de carregamento de classe (e de execução dos seus blocos de inicialização estática) é muito mais difícil de controlar. Isso é motivo suficiente para não colocar a muita lógica para blocos de inicialização estáticos. Você faz algo difícil de ler e compreender e na recompensa que você receber alguma coisa mais difícil de usar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top