Alguém sabe dizer por que o método main não funciona sem array de String como argumento? Se você excluir o array do método ela compila, mas a JVM passa a não reconhecer mais aquele método como o ?main?. Engraçado é que se pode por qualquer nome neste array que ela não encrenca, mas excluir nem pensar…
Querendo entender um detalhe do main
6 Respostas
claro… mudando o nome, você não muda a assinatura do método
você ainda vai ter um
“public static void main(Array de java.lang.String){}”
e sem o argumento “array de String” ele não funciona, pois o método main padrão é um public static void main(String[] args) e um “public static void main()” é apenas um método qualquer =]
Alguém sabe dizer por que o método main não funciona sem array de String como argumento?
O método vai continuar ‘funcionando’, entretanto quando vc executa uma classe java, o primeiro e unico metodo chamado é o main cuja assinatura é um array de strings.
É uma convenção adotada. Em C, C++ e D vc pode ter um main(void), no java optaram por ter apenas um. Acredito que seja por que se vc tiver mais um um ‘main’ – sobrecarrando o método, vc pode confundir a maquina virtual. Afinal não ha nada q vá impedir vc de ter mais de um ‘public static void main’. Se alguem souber mais, poste ai!
Além de tudo que o pessoal acima falou, é necessário um array pois o Java pega cada “palavra” passada por parâmetro e bota num índice diferente!
se vc mudar a assinatura e/ou a lista de parametros, vc vai ter um método que (como a kathy diz no livro) ocasionalmente tem o mesmo nome DO método main que a JVM procura…
[…]Acredito que seja por que se vc tiver mais um um ‘main’ – sobrecarrando o método, vc pode confundir a maquina virtual. Afinal não ha nada q vá impedir vc de ter mais de um ‘public static void main’. Se alguem souber mais, poste ai!
Se eu entendi direito, o que o peczenyj disse é que não dá pra sobrecarregar o método main. Se for isso, não é verdade.
Caro xandinhocavalcante.
O que identifica de forma única um método dentro de uma classe é, como o pessoal todo já disse, a assinatura do método. A assinatura de um método é formada pelo nome e pelo tipo dos seu parâmetros.
Como assim “pelo tipo dos seus parâmetros”? Simples: Suponha o seguinte método
public String repetir(String texto, int vezes, String separador){
StringBuilder sb = new StringBuilder();
for(int i = 0; i < vezes; i++){
sb.append(texto);
if(i < vezes - 1)
sb.append(separador);
}
return sb.toString();
}
a assinatura deste método é “repetir(String, int, String)”. O nome dos parâmetros não importam para a identificação unívoca do método dentro de uma classe, pois os parâmetros só são utilizados dentro do método.
Quando você tenta invocar o método acima, por exemplo, para imprimir na tela 7 linhas dizendo “Java é massa!”
System.out.println(
repetir("Java é massa!", 7, "\n")
);
Qual a informação que a JVM vai ter a respeito dessa invocação?
:thumbup: O nome do método
:thumbup: Que o método tem 3 parâmetros de tipos String, int e String, exatamente nesta ordem
E qual a informação a JVM não tem (E nunca terá)?
:thumbdown: O nome dos respectivos parâmetros
Perceba que não há a necessidade de a JVM saber o nome dos parâmetros do método repetir. Se os nomes forem como descrito acima, teremos apenas que:
:arrow: texto = “Java é massa!”
:arrow: vezes = 7
:arrow: separador = “\n”
Se o método tivesse sido declarado assim:
public String repetir(String batatinha, int abobrinha, String goiabinha){
...
}
Em nada mudaria a invocação deste método, e também em nada mudaria o comportamento da JVM para obedecer a tal invocação. E teriamos novamente que
:arrow: batatinha = “Java é massa!”
:arrow: abobrinha = 7
:arrow: goiabinha = “\n”
Em suma, não vem ao caso o nome do parâmetro. O que define a assinatura do método é o nome do método e os tipos dos parâmetros em uma determinada ordem. E é a assinatura quem identifica de forma única o método dentro da classe.
Quando temos métodos com mesmo nome e assinaturas diferentes, temos o que se chama de sobrecarga de método. Se, por exemplo, quisessemos fornecer uma versão do método repetir, a qual pedisse somente o texto a ser repetido e a quantidade de repetições, assumindo como separadaor a “pulada de linha”, teriamos o seguinte:
public String repetir(String texto, int vezes){
return repetir(texto, vezes, "\n");
}
public String repetir(String texto, int vezes, String separador){
...
}
Se vc invocar
System.out.println(repetir("Java rlz!", 3, ", "));
System.out.println(repetir("=========", 3, "**"));
System.out.println(repetir("Java rlz!", 3));
System.out.println("E ponto final!!!");
Você verá em seu consele o seguinte:
Java rlz!, Java rlz!, Java rlz!
=========**=========**=========
Java rlz!
Java rlz!
Java rlz!
E ponto final!!!
Perceba que quando a JVM “lê” as invocações ao método repetir, ela sabe qual dos dois deve invocar, e sabe isso pela assinatura do método. Na primeira invocação ao método repetir, estamos passando um String, um int e um String. A JVM vai na classe e busca algum método com a assinatura “repetir(String, int, String)”. No segundo, passamos um String e int apenas. A JVM então busca na classe um método com a assinatura “repetir(String, int)”.
Assim, a assinatura é que faz com que a JVM não se “confunda” se houver sobrecarga do método main. A JVM é programada de tal forma, que quando você tentar executar uma classe, ela irá buscar nesta classe que você indicou um método com a assinatura “main(String[])” e que tenha retorno do tipo void. Se a JVM não localizar na classe ûm método com essas características, vc ganhara “na cara” um infame
[color=darkred]
java.lang.NoSuchMethodError: main
Exception in thread "main"
[/color]
Espero ter ajudado. Qualquer dúvida, pergunte!
Se eu entendi direito, o que o peczenyj disse é que não dá pra sobrecarregar o método main. Se for isso, não é verdade.
Acho que eu compliquei demais. Eu quis dizer que justamente pelo método main poder ser carregado em diversas assinaturas que uma assinatura em específico foi determinada como padrão para executar uma classe, provavelmente esse método deve ser chamado via reflection, sendo invocado ou algo assim.