Pergunta

A assinatura do método de Java main () método é:

public static void main(String[] args){
    ...
}

Existe uma razão para que este método ser estático?

Foi útil?

Solução

O método é estático, porque caso contrário não haveria ambigüidade: construtor que deve ser chamado? Especialmente se a sua aparência de classe como este:

public class JavaClass{
  protected JavaClass(int x){}
  public void main(String[] args){
  }
}

Caso o new JavaClass(int) chamada JVM? O que ele deve passar por x?

Se não, deve o JavaClass instanciar JVM sem correr qualquer método construtor? Eu acho que não deveria, porque isso vai especial caso toda a sua classe - às vezes você tem uma instância que não foi inicializado, e você tem que verificar isso em cada método que poderia ser chamado

.

Existem demasiados casos de ponta e ambiguidades para que façam sentido para o JVM ter que instanciar uma classe antes de o ponto de entrada é chamado. É por isso que main é estático.

Eu não tenho idéia por que main é sempre marcada public embora.

Outras dicas

Esta é apenas uma convenção. Na verdade, até mesmo o nome main (), e os argumentos passados ??são puramente convenção.

Quando você executar java.exe (ou javaw.exe no Windows), o que realmente está acontecendo é um par de Java Native Interface (JNI) chamadas. Estas chamadas carregar a DLL que é realmente a JVM (isso mesmo - java.exe não é o JVM). JNI é a ferramenta que usamos quando temos de colmatar o mundo máquina virtual, eo mundo de C, C ++, etc ... O inverso também é verdadeiro - não é possível (pelo menos que eu saiba) para realmente obter uma JVM em execução sem usar JNI.

Basicamente, java.exe é um aplicativo super simples C que analisa a linha de comando, cria uma nova matriz de String na JVM de manter estes argumentos, analisa-o nome da classe que você especificou como contendo main (), usa chamadas JNI para encontrar o método main () em si, em seguida, chama o método main (), passando a matriz de cadeia recém-criado como um parâmetro. Isto é muito, muito parecido com o que você faz quando você usar a reflexão de Java -. Ele só usa confusamente nomeados chamadas de funções nativas em vez

Seria perfeitamente legal para você escrever sua própria versão do java.exe (a fonte é distribuído com o JDK) e tê-lo fazer algo completamente diferente. Na verdade, isso é exatamente o que fazemos com todos os nossos aplicativos baseados em Java.

Cada um dos nossos aplicativos Java tem seu próprio lançador. Nós principalmente fazer isso assim que nós começamos nosso próprio ícone e processo de nome, mas veio a calhar em outras situações em que queremos fazer algo além da chamada normal main () para começar as coisas (Por exemplo, em um caso que estamos fazendo COM interoperabilidade, e nós realmente passar um identificador COM em main () em vez de uma matriz de cadeia).

Assim, de longo e curto: a razão é estática é b / c que é conveniente. A razão é chamado de 'main' é que ele tinha que ser alguma coisa, e main () é o que eles fizeram nos velhos tempos de C (e naqueles dias, o nome da função foi importante) . Suponho que java.exe poderia ter permitido que você especificar apenas um nome principal método totalmente qualificado, em vez de apenas a classe (java com.mycompany.Foo.someSpecialMain) - mas isso só torna mais difícil em IDEs para detectar automaticamente o ' 'classes launchable em um projeto.

O método main() em C++, C# e Java are estática Porque eles podem, então, ser invocado pelo mecanismo de tempo de execução sem ter que instanciar todos os objetos, em seguida, o código no corpo de main() fará o resto.

Por public static void main (String [] args)?

Isto é como linguagem Java é projetado e Java Virtual Machine é projetado e escrito.

o Oracle Java Specification Language

Confira Capítulo 12 Execução - Seção 12.1.4 Invoke Test.main :

Finalmente, após conclusão da inicialização de classe de teste (durante o qual outros carregamento consequente, ligando, e inicializando pode ter ocorrido), o principal método de teste é chamado.

O principal método deve ser declarado public, static e vazia. Ele deve aceitar um único argumento que é uma matriz de strings. Este método pode ser declarado como qualquer

public static void main(String[] args)

ou

public static void main(String... args)

o Oracle Java Virtual Machine Specification

Confira Capítulo 2 Java conceitos de programação de idioma - Seção 2.17 execução :

A máquina virtual Java inicia a execução invocando o principal método de alguma classe específica e passá-lo um único argumento, que é uma matriz de strings. Isto faz com que a classe especificada para ser carregado (§2.17.2), ligado (§2.17.3) para outros tipos de que ele utiliza, e inicializado (§2.17.4). O principal método deve ser declarado public, static e vazia.

a Oracle OpenJDK Fonte

Faça o download e extrair o frasco fonte e ver como JVM está escrito, veja ../launcher/java.c, que contém código nativo C por trás java [-options] class [args...] comando:

/*
 * Get the application's main class.
 * ... ...
 */
if (jarfile != 0) {
    mainClassName = GetMainClassName(env, jarfile);

... ...

    mainClass = LoadClass(env, classname);
    if(mainClass == NULL) { /* exception occured */

... ...

/* Get the application's main method */
mainID = (*env)->GetStaticMethodID(env, mainClass, "main",
                                   "([Ljava/lang/String;)V");

... ...

{    /* Make sure the main method is public */
    jint mods;
    jmethodID mid;
    jobject obj = (*env)->ToReflectedMethod(env, mainClass,
                                            mainID, JNI_TRUE);

... ...

/* Build argument array */
mainArgs = NewPlatformStringArray(env, argv, argc);
if (mainArgs == NULL) {
    ReportExceptionDescription(env);
    goto leave;
}

/* Invoke main method. */
(*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs);

... ...

Deixe-nos simplesmente fingir, que static não seria necessária como o ponto de entrada do aplicativo.

Uma classe de aplicativo, então, parecido com este:

class MyApplication {
    public MyApplication(){
        // Some init code here
    }
    public void main(String[] args){
        // real application code here
    }
}

A distinção entre o código construtor e método main é necessário porque, em OO falar um construtor só deve certificar-se de que uma instância é inicializado corretamente. Após a inicialização, a instância pode ser usado para o "serviço" pretendido. Colocando o código da aplicação completa para o construtor iria estragar isso.

Assim, esta abordagem forçaria três diferentes contratos sobre o aplicativo:

  • Não deve ser um construtor padrão. Caso contrário, a JVM não saberia qual construtor chamar e deve ser fornecida What parâmetros.
  • Não deve ser um método main 1 . Ok, isso não é surpreendente.
  • A classe não deve ser abstract. Caso contrário, a JVM não poderia instanciar-lo.

A abordagem static por outro lado, requer apenas um contrato:

  • Deve haver um método main 1 .

Aqui, nem abstract nem vários construtores assuntos.

Uma vez que Java foi projetado para ser uma linguagem simples para o usuário não é de estranhar que também o ponto de entrada do aplicativo foi concebido de uma forma simples usando um contrato e não de uma forma complexa usando três independentes e quebradiços contratos.

Por favor nota: Esse argumento é não sobre a simplicidade dentro da JVM ou dentro do JRE. Este argumento é sobre a simplicidade para o user .


1 Aqui as contagens de assinatura completas como um único contrato.

Se não fosse, que o construtor deve ser usado se houver mais do que um?

Não há mais informações sobre a inicialização e execução de programas Java disponível no Java Specification Language .

Antes do principal método é chamado, nenhum objeto é instanciado. Tendo os meios de palavra-chave estática do método pode ser chamado sem criar quaisquer objetos em primeiro lugar.

Porque de outra forma, seria necessário uma instância do objeto a ser executado. Mas deve ser chamado a partir do zero, sem construir o objeto em primeiro lugar, uma vez que é geralmente a tarefa da função main () (inicialização), para analisar os argumentos e construir o objeto, geralmente usando esses argumentos parâmetros / programa.

O que é o significado de public static void main(String args[])?

  1. public é um especificador de acesso significa acesso qualquer um pode / invocá-lo como JVM (Java Virtual Machine.
  2. static permite main() a ser chamado antes de um objeto da classe foi criada. Esta é neccesary porque main() é chamado pelo JVM antes de quaisquer objetos são feitos. Uma vez que é estático, ele pode ser chamado diretamente através da classe.

    class demo {    
        private int length;
        private static int breadth;
        void output(){
            length=5;
            System.out.println(length);
        }
    
        static void staticOutput(){
            breadth=10; 
            System.out.println(breadth);
        }
    
        public static  void main(String args[]){
            demo d1=new demo();
            d1.output(); // Note here output() function is not static so here
            // we need to create object
            staticOutput(); // Note here staticOutput() function is  static so here
            // we needn't to create object Similar is the case with main
            /* Although:
            demo.staticOutput();  Works fine
            d1.staticOutput();  Works fine */
        }
    }
    

    Da mesma forma, nós usamos algum estática para métodos definidos pelo usuário de modo que não temos necessidade de fazer objetos.

  3. void indica que o método main() ser declarado não retorna um valor.

  4. especifica String[] args o único parâmetro no método main().

    args -. Um parâmetro que contém uma matriz de objetos do tipo classe String

Deixe-me explicar essas coisas de uma maneira muito mais simples:

public static void main(String args[])

Todas as aplicações Java, exceto applets, começar sua execução a partir main().

O public palavra-chave é um modificador de acesso que permite que o membro a ser chamado de fora da classe.

static é utilizado porque permite main() a ser chamado sem ter que instanciar uma instância específica da classe.

void indica que main() não retorna qualquer valor.

Applets, MIDlets, Servlets e feijão de vários tipos são construídos e depois ter métodos de ciclo de vida chamado sobre eles. Invocando principal é tudo o que é sempre feito para a classe principal, por isso não há necessidade de um estado a ser realizada em um objeto que é chamado várias vezes. É perfeitamente normal para o pino principal em uma outra classe (embora não seja uma grande idéia), que iria ficar no caminho do uso da classe para criar o objeto principal.

É apenas uma convenção, mas provavelmente mais conveniente do que a alternativa. Com um principal estático, tudo o que você precisa saber para invocar um programa Java é o nome ea localização de uma classe. Se não fosse estático, você também tem que saber como criar uma instância dessa classe, ou exigir que a classe tem um construtor vazio.

Se o método principal não seria estático, você precisa criar um objeto de sua classe principal de fora do programa. Como você quer fazer isso?

Quando você executar o Java Virtual Machine (JVM) com o comando java,

java ClassName argument1 argument2 ...

Ao executar o aplicativo, você especifica seu nome de classe como um argumento para o comando java, como acima

as tentativas de JVM para invocar o método principal da classe você especificar

-Neste momento, nenhum objeto da classe foram criadas.

Declarando main como allows estática a JVM invoke principal Criando without um instance da classe.

volta Vamos para o comando

ClassName é um command-line argument à JVM que lhe diz qual classe para executar. Após o ClassName, você também pode especificar um list of Strings (separados por espaços) como argumentos de linha de comando que a JVM vai passar para a sua aplicação. argumentos -como pode ser usado para especificar opções (por exemplo, um nome de arquivo) para executar o aplicação- é por isso que há um parâmetro chamado String[] args no principal

Referências: Java ™ como o programa Para (objetos early ), Décima Edição

Eu acho que a palavra-chave 'estática' torna o principal método um método de classe e métodos de classe têm apenas uma cópia do mesmo e pode ser compartilhado por todos, e também, ele não requer um objeto de referência. Assim, quando a classe de driver é compilado o principal método pode ser invocado. (Eu sou apenas em nível alfabeto de java, desculpe se eu estiver errado)

main () é estático porque; em que ponto do ciclo de vida do aplicativo, a pilha de aplicação é de natureza processual, devido a não haver objetos ainda instanciado.

É uma ardósia limpa. Sua aplicação está em execução neste momento, mesmo sem quaisquer objetos sendo declarado (lembre-se, há processual e padrões OO codificação). Você, como o desenvolvedor, transformar o aplicativo em uma solução orientada a objetos criando instâncias de seus objetos e, dependendo do código compilado dentro.

orientada a objetos é grande para milhões de razões óbvias. No entanto, longe vão os dias em que a maioria dos desenvolvedores VB palavras-chave usadas regularmente como "goto" em seu código. "Goto" é um comando processual em VB que é substituído pelo seu homólogo OO:. Método de invocação

Você também pode olhar para o ponto de entrada estático (principal) como pura liberdade. Teve Java sido suficiente diferente para instanciar um objeto e presente apenas essa instância para você no prazo, você não teria nenhuma escolha a não ser escrever um aplicativo processual. Tão inimaginável que possa parecer para Java, é possível que haja muitos cenários que exigem abordagens processuais.

Esta é provavelmente uma resposta muito obscura. Lembre-se, "classe" é apenas uma coleção de código inter-relacionado. "Instância" é um isolado, vivendo e respirando geração autônoma dessa classe.

O public static void main(String[]) protoype é uma convenção definido na JLS :

O principal método deve ser declarado public, static e vazia. Ele deve especificar um parâmetro formal (§8.4.1), cujo tipo declarado é matriz de cadeia.

Na JVM especificação 5.2. Virtual Machine Start-up podemos ler:

A máquina virtual Java inicia-se através da criação de uma classe inicial, que é especificado em uma maneira dependente da aplicação, utilizando o carregador de classe de bootstrap (§5.3.1). A máquina virtual Java, em seguida, liga a classe inicial, inicializa, e invoca o método da classe public void main (String []) . A invocação deste método impulsiona toda a posterior execução. A execução das instruções de Máquina Virtual Java que constituem o principal método pode causar ligando (e, por conseguinte, a criação) de classes adicionais e interfaces, bem como invocação de métodos adicionais.

O engraçado, na especificação JVM é não mencionar que o método principal tem de ser estático. Mas a especificação também diz que a máquina virtual Java executar 2 passos antes:

inicialização de uma classe ou interface consiste em executar o seu método de classe ou de inicialização de interface.

Na 2.9. Métodos especiais :

A classe ou interface método de inicialização é definida:

Uma classe ou interface tem, no máximo, uma classe ou interface método de inicialização e é inicializada (§5.5) invocando esse método. O método de inicialização de uma classe ou interface tem o <clinit> nome especial, não tem argumentos, e é nula.

E classe ou interface método de inicialização é diferente de um método de inicialização exemplo definidos como segue:

Ao nível da máquina virtual Java, cada construtor escrito na linguagem de programação Java (JLS §8.8) aparece como um método de inicialização de instância que tem a <init> nome especial.

Assim, a JVM inicializar um classe ou interface método de inicialização e não um método de inicialização instância que é realmente um construtor. Assim, eles não precisam de mencionar que o método principal tem de ser estático na especificação JVM porque está implícito no fato de que nenhuma instância são criados antes de chamar o método principal.

Recentemente, pergunta semelhante foi afixado em Programmers.SE

  • Por um método estático main em Java e C #, em vez de um construtor?

    À procura de uma resposta definitiva de uma fonte primária ou secundária de por que (nomeadamente) Java e C # decidir ter um método estático como seu ponto de entrada - em vez de representar uma instância do aplicativo por uma instância de uma classe Application, com o ponto de entrada de ser um construtor apropriado?

TL; DR parte da resposta aceita é,

Em Java, a razão de public static void main(String[] args) é que

  1. Gosling queria
  2. o código escrito por alguém com experiência em C (não em Java)
  3. para ser executado por alguém acostumado a correr PostScript em Notícias

http://i.stack.imgur.com/qcmzP.png


Para C #, o raciocínio é transitively semelhante , por assim dizer. projetistas da linguagem manteve a sintaxe familiar para programadores provenientes de Java. Como C # arquiteto Anders Hejlsberg coloca ,

... nossa abordagem com C # tem sido simplesmente oferecer uma alternativa ... para programadores Java ...

...

É apenas uma convenção. O JVM certamente poderia lidar com métodos principais não-estáticos, se isso teria sido a convenção. Afinal, você pode definir uma estática initializer em sua classe, e instanciar um zilhão de objetos antes mesmo de chegar ao seu método main ().

A palavra-chave public é um modificador de acesso, o que permite que o programador controle a visibilidade de membros da classe. Quando um membro da classe é precedida por public, então isso membro pode ser acessado pelo código fora da classe em que ela é declarada.

O oposto de public é private, que impede que um membro de ser usado por código definido pelo lado de fora da sua classe.

Neste caso, main() deve ser declarado como public, uma vez que deve ser chamado por fora código da sua classe quando o programa é iniciado.

O static palavra-chave permite main() a ser chamado, sem ter de instanciar uma instância específica da classe. Isto é necessário pois main() é chamado pelo interpretador Java antes de quaisquer objetos são feitos.

O void chave simplesmente diz ao compilador que main() não retorna um valor.

O verdadeiro ponto de entrada para qualquer aplicação é um método estático. Se a linguagem Java suportado um método de instância como o "ponto de entrada", o tempo de execução seria necessário implementá-lo internamente como um método estático que construiu uma instância do objeto seguido, chamando o método de instância.

Com isso fora do caminho, vou examinar as razões para a escolha de um específico das três opções seguintes:

  1. A static void main() como o vemos hoje.
  2. Um exemplo void main() método chamado de um objecto recém-calculado.
  3. Usando o construtor de um tipo como o ponto de entrada (por exemplo, se a classe de entrada foi chamado Program, em seguida, a execução seria efetivamente consistem em new Program()).

Breakdown:

static void main()

  1. Chama o construtor estático da classe de fechamento.
  2. Chama o método main() estático.

void main()

  1. Chama o construtor estático da classe de fechamento.
  2. Constrói uma instância da classe delimitador chamando efetivamente new ClassName().
  3. Chama o main() método de instância.

new ClassName()

  1. Chama o construtor estático da classe de fechamento.
  2. Constrói uma instância da classe (então não faz nada com ele e simplesmente retorna).

Justificação:

Eu vou na ordem inversa para este.

Tenha em mente que um dos objetivos do projeto de Java era enfatizar (requer quando possível) objeto bom orientada práticas de programação. Neste contexto, o construtor de um objeto inicializa o objeto, mas não deve ser responsável pelo comportamento do objeto. Portanto, uma especificação que deu um ponto de entrada de new ClassName() iria confundir a situação para novos desenvolvedores Java, forçando uma exceção para o desenho de um construtor "ideal" em cada aplicação.

Ao fazer main() um método de instância, o problema acima é certamente resolvido. No entanto, ele cria complexidade, exigindo a especificação para listar a assinatura do construtor da classe de entrada, bem como a assinatura do método main().

Em resumo, especificando um static void main() cria uma especificação com o mínimo de complexidade embora respeitando o princípio de colocar comportamento em métodos . Considerando o quão simples é implementar um método main() que se constrói uma instância de uma classe e chama um método de instância, não há nenhuma vantagem real para especificar main() como um método de instância.

estático -. Quando a JVM faz uma chamada para o método main não há nenhum objeto que existe para a classe que está sendo chamado, portanto, ele tem que ter método estático para permitir invocação da classe

Eu não sei se o JVM chama o método principal antes que os objetos são instanciados ... Mas há uma razão muito mais poderosa por isso que o método main () é estático ... Quando JVM chama o método principal do classe (digamos, Pessoa). invoca-lo por " Person.main () ". Você vê, a JVM invoca pelo nome da classe. É por isso que o método main () é suposto ser estático e tão pública que pode ser acessado pelo JVM.

Hope ajudou. Se o fizesse, deixe-me saber por comentar.

métodos

estáticos não necessitam de qualquer objeto. Ele é executado diretamente de modo principal é executado diretamente.

A palavra-chave estática no método principal é usado porque não há qualquer instanciação que ocorrem no método principal. Mas objeto é construído, em vez de invocação, como resultado, use a palavra-chave estática no método principal. Em JVM memória contexto é criado quando as cargas de classe em it.And todos os membros estáticos estão presentes em que a memória. se fizermos a estática principal agora será em memória e pode ser acessível a JVM (class.main (..)) para que possamos chamar o método principal com a necessidade de necessidade, mesmo para montão foi criado.

É apenas uma convenção, como podemos ver aqui:

O método pública devem ser declarados e estática , não deve retornar qualquer valor e deve aceitar uma matriz de String como um parâmetro. Por padrão, o primeiro argumento não-opção é o nome da classe a ser invocado. Um nome de classe totalmente qualificado deve ser usado. Se a opção -jar é especificada, o primeiro argumento não-opção é o nome de um arquivo JAR contendo arquivos de classe e recurso para o aplicativo, com o classe de inicialização indicada pelo cabeçalho do manifesto Main-Class.

http://docs.oracle. com / JavaSE / 1.4.2 / docs / tooldocs / windows / java.html # descrição

As palavras-chave public static void significa que a máquina virtual Java (JVM) intérprete pode chamar o método principal do programa para iniciar o programa (público) sem criar uma instância da classe (estática), e o programa não retorna dados para o intérprete Java VM (void) quando termina.

Fonte: Essentials, Parte 1, Lição 2: Construindo Aplicações

Basicamente fazemos essas funções membros de dados e membro como estático que não estão realizando qualquer tarefa relacionada a um objeto. E no caso do método principal, estamos fazendo isso como um STATIC porque não é nada a ver com o objeto, como o principal método execute sempre se estamos criando um objeto ou não.

Qualquer método declarado como estático em Java pertence à própria classe. método novamente estático de uma classe particular pode ser acessado apenas por fazer referência à classe como Class_name.method_name();

Assim, uma necessidade classe não deve ser instanciado antes de acessar um método estático.

Assim, o método main () é declarada como static para que ele possa ser acessado sem criar um objeto dessa classe.

Uma vez que salvar o programa com o nome da classe, onde o principal método está presente (ou de onde o programa deve começar sua execução, aplicáveis ??para as classes sem um método main() () (Nível avançado)). Então, pelo acima mencionado maneira:

Class_name.method_name();

o principal método pode ser acessado.

Em breve, quando o programa é compilado ele procura o método main() com argumentos String como: main(String args[]) na classe mencionada (ie pelo nome do programa), e uma vez que no início, não tem escopo para instanciar essa classe , então o método main () é declarada como estática.

A partir java.sun.com (há mais informações no site):

O principal método é estático para dar o Java VM intérprete uma maneira de começar a classe sem criar uma instância da classe de controle primeiro. As instâncias da classe de controle são criados no método principal depois que o programa é iniciado.

O meu entendimento sempre foi simplesmente que o método principal, como qualquer método estático, pode ser chamado sem criar uma instância da classe associada, permitindo que ele seja executado antes de qualquer outra coisa no programa. Se não fosse estática, você teria que instanciar um objeto antes de chamar ele-- que cria um problema 'galinha e do ovo', já que o principal método é geralmente o que você usa para objetos instanciar no início do programa.

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