Por que o método MAIN não possui implicitações?

Estava observando um artigo por aí. Quando me bateu esta dúvida. Tendo em vista, diversas outras coisas em java, que não obrigam o programador a por na assinatura, ficando de forma opcional (assim como nas interfaces e alguns extends), etc. bateu a dúvida. Por que aquele monstro do método main, também não tem implicitações em sua assinatura, sendo que SEMPRE vai ser estático, publico, void… ?

Para quem estaria iniciando, seria muito mais simples e amigável, escrever o main, como no C.

void main(String args[]) {
//comandos
}

Em C/C++ são válidos:

int main (int argc, char*argv[])
int main (int argc, char*argv[], char*envp[])

Não sei se pelo padrão ANSI é aceito “void main”. Que eu saiba, main em C tem de retornar pelo menos 0. E eu não acho nem um pouco amigável o “main” do C/C++, embora seja programador C/C++ há mais de 20 anos.
É que você está acostumado com ele.

Na verdade, como você deve saber, nem o main no Java é obrigatório - se você escrever uma applet, ela não tem “main”.
Tudo depende de quem vai instanciar a classe Java.
Se for o Java.exe, ele requer o tal do main; isso é uma convenção do java.exe, não da linguagem em si. Se ele não achar um método “public static void main” ele não consegue rodar seu programa. Se você instanciar a classe de outra forma (por exemplo, usando um outro programa como o JavaService), a convenção pode ser outra.

[quote=thingol]Em C/C++ são válidos:

int main (int argc, char*argv[])
int main (int argc, char*argv[], char*envp[])

Não sei se pelo padrão ANSI é aceito “void main”. Que eu saiba, main em C tem de retornar pelo menos 0. E eu não acho nem um pouco amigável o “main” do C/C++, embora seja programador C/C++ há mais de 20 anos.
É que você está acostumado com ele.

Na verdade, como você deve saber, nem o main no Java é obrigatório - se você escrever uma applet, ela não tem “main”.
Tudo depende de quem vai instanciar a classe Java.
Se for o Java.exe, ele requer o tal do main; isso é uma convenção do java.exe, não da linguagem em si. Se ele não achar um método “public static void main” ele não consegue rodar seu programa. Se você instanciar a classe de outra forma (por exemplo, usando um outro programa como o JavaService), a convenção pode ser outra.
[/quote]

Levei em consideração o C somente pela simplicidade. Ja vi alguns compiladores aceitarem ‘void main(void)’ por exemplo.

Sei, que não é obrigatório o uso do método main nas classes, caso o interesse não seja torna-las executáveis.

Mas minha dúvida, é porquê invés de ter que escrever, todo o public static void main, a sun não adaptou este método, com os modificadores implícitos também? Bem na idéia de interfaces.

Na minha idéia, funcionaria como main:

public void main
static void main
void main
public static void main

Tendo como opcional o public e o static, (dependendo da visão, até o void… mas ai acho que quebraria alguns paradigmas) uma vez sabendo que eles estariam ali de qualquer forma.

É essa dúvida, com a sun! :stuck_out_tongue:

Acho que o java.exe requer que seja um “public static void main(String[] args)” exatamente para seguir a MESMA semântica (significado) do C/C++, já que você falou nisso.

Se você tirasse o “static” a semântica seria diferente (porque exigiria que a classe tivesse um construtor público e sem parâmetros, para poder ser instanciada antes de você poder chamar o “main”); se você tirasse o “public” o java.exe não poderia nem instanciar a tal classe porque ela não é pública. E ele requer o (String[] args) porque copia exatamente a idéia do “(int argc, char* argv[])”.

Sinta-se à vontade para modificar os fontes do java.exe e relaxar essas imposições… É mais simples que parece; basta baixar os fontes da Sun (e ter o MS Visual Studio 2003 Enterprise instalado na sua máquina) , modificar o programa em C que chama o main, e recompilar o java.exe.

[quote=thingol]Acho que o java.exe requer que seja um “public static void main(String[] args)” exatamente para seguir a MESMA semântica (significado) do C/C++, já que você falou nisso.

Se você tirasse o “static” a semântica seria diferente (porque exigiria que a classe tivesse um construtor público e sem parâmetros, para poder ser instanciada antes de você poder chamar o “main”); se você tirasse o “public” o java.exe não poderia nem instanciar a tal classe porque ela não é pública. E ele requer o (String[] args) porque copia exatamente a idéia do “(int argc, char* argv[])”.

Sinta-se à vontade para modificar os fontes do java.exe e relaxar essas imposições… É mais simples que parece; basta baixar os fontes da Sun (e ter o MS Visual Studio 2003 Enterprise instalado na sua máquina) , modificar o programa em C que chama o main, e recompilar o java.exe.
[/quote]

Certo, thingol. Mas você entendeu que eu me refiro, em questões de que, a pessoa não “tiraria” na verdade, pois, assim como interfaces, se eu colocasse o ‘public’ la por exemplo, beleza! mas se eu não colocasse, o compilador iria enxergar mesmo assim, uma vez, sendo implícito.

eu escreveria: public void main
e o compilador enxergaria: public static void main

Não é uma necessidade, oras. É apenas uma dúvida, de porquê a sun não fez isso. Sabendo que ela fez, em outros casos parecidos.

Como interfaces, que novamente, cito:

interface a { int a(); }

o compilador sabe que o método a(), é public abstract static final …

:roll:

Desvirtuando um pouquinho o sentido do tópico, fiquei interessado nesse negócio :

Bem que você poderia criar um artigo sobre isso, que tal Thingol? :smiley:

abração

Uma coisa boa do Java é que “vale o que está escrito” (lembra do jogo do bicho?) Não há coisas misteriosas como em um programa em C++ (onde para saber o que o compilador entendeu do seu programa às vezes é necessário obter uma listagem assembly). E as regras valem para todos, não são diferentes só porque o método se chama “main”.

O compilador sabe que o método a é public, mas não é static final (static final só para constantes definidas na interface, uma coisa que acho muito estranha em Java).
Mas isso está escrito na definição da linguagem.

Então alguma coisa está errado no livro da khaty Sierra ou eu estou me confundindo. Quando chegar em casa, levanto esse assunto novamente.

Quando você faz int a(); em uma interface, implicitamente este método é public e abstract e não public static final.

Opa é verdade. Isso acontece exatamente pela variança da utilização.

Agora, e quanto ao public e abstract. A idéia continua se baseando nisso. São coisas que sempre farão parte da interface, colocando ou não.

no main, public static são coisas que sempre farão parte também!

Como vc (leia-se a JVM) destingue isso de public void main(String args[]) que não é uma sintaxe válida para o método main ?

Realmente…

Os modificadores public e static poderiam ser implícitos.

Abraços.

O java.exe faz o seguinte, em termos resumidos:

  • Lê os parâmetros passados na linha de comando
  • Carrega a jvm.dll
  • Prepara a classpath a partir do parâmetro -classpath e da variável de ambiente CLASSPATH
  • Tenta carregar a classe indicada na linha de comando (como se fosse Class.forName), sem instanciá-la.
  • Procura na classe um método público e estático com o nome main, e com um único parâmetro do tipo java.lang.String[]. Se for encontrado, tenta chamá-lo. Note que a classe mesmo assim não é instanciada - apenas o método estático main é chamado. Se quiser instanciar a classe, isso deve ser feito (por exemplo) pelo main.

Você pode reescrever um pedaço do java.exe para fazer algo diferente, desde que você carregue a jvm.dll. Não é difícil, só um pouco trabalhoso.

[quote=sergiotaborda][quote=peerless]
Para quem estaria iniciando, seria muito mais simples e amigável, escrever o main, como no C.

void main(String args[]) {
//comandos
}

[/quote]

Como vc (leia-se a JVM) destingue isso de public void main(String args[]) que não é uma sintaxe válida para o método main ?[/quote]

Que se eles abordassem a idéia de main implícito, seria válido. pois você veria public void main, mas o compilador: public STATIC void main…

Como eu disse: o fonte do javac e do java.exe está disponível para você mexer e fazer as alterações que você quiser.
Se quiser que o “main” tenha regras especiais, esteja à vontade para mexer no fonte do javac.
(Ele usa “recursive descent” em vez de usar um parser gerado automaticamente por um “compiler-compiler” como o yacc, portanto deve ser mais fácil de mexer para quem não conhece muita teoria de construção compiladores).
Existe até um projeto chamado “KSL” (Kitchen Sink Language), no Java.net, para você entrar se você quiser.
Mas é o que eu digo: o legal do Java é que “vale o que está escrito”, e “as regras são iguais para todos”.
Se quiser sugerir a alteração para a Sun, vá para bugs.sun.com e encaminhe seu pedido.

[quote=thingol]Como eu disse: o fonte do javac e do java.exe está disponível para você mexer e fazer as alterações que você quiser.
Se quiser que o “main” tenha regras especiais, esteja à vontade para mexer no fonte do javac.
(Ele usa “recursive descent” em vez de usar um parser gerado automaticamente por um “compiler-compiler” como o yacc, portanto deve ser mais fácil de mexer para quem não conhece muita teoria de construção compiladores).
Existe até um projeto chamado “KSL” (Kitchen Sink Language), no Java.net, para você entrar se você quiser.
Mas é o que eu digo: o legal do Java é que “vale o que está escrito”, e “as regras são iguais para todos”.
Se quiser sugerir a alteração para a Sun, vá para bugs.sun.com e encaminhe seu pedido. [/quote]

Legal as dicas, valeu Thingol. Mas este ‘vale o que está escrito’, não é seguido ‘bem’ ao pé da letra. um construtor por exemplo, não precisa ter o ‘public’, casts implicitos, extends implicitos…
abraço

[quote=peerless]Legal as dicas, valeu Thingol. Mas este ‘vale o que está escrito’, não é seguido ‘bem’ ao pé da letra. um construtor por exemplo, não precisa ter o ‘public’…
abraço[/quote]

Cuidado com o que você fala :stuck_out_tongue:

No Java, “vale o que está escrito”, e se você compilar um código e estiver em desacordo com a Java Language Specification, poste um bug no bugs.sun.com porque um dos dois está errado (o Javac ou a JLS).

Se você omitir o “public” o construtor será “package-private”, ou seja, só poderá ser chamado em classes do mesmo pacote.

[quote=lgi2020]Realmente…

Os modificadores public e static poderiam ser implícitos.

Abraços.[/quote]

Do meu ponto de vista neste caso não poderiam, pois sem eles descritos de forma explicita não seria possível o compilador entender que o metodo “main” em questão se trataria do metodo principal, mesmo que o compilador levasse em consideração o nome do metodo e sua assinatura. Embora veja como incorreto a pessoa poderia ter uma classe que não fosse a principal e mesmo assim pretender colocar um metodo com o nome de “main”, e possuindo um “array” de “String” como parametro, e o programador não quer que seja o principal chamado pela aplicação.

OK. enviei a dica lá.
Se obtiver alguma resposta, vou pôr aqui.

valeu…

[quote=javapaulomg][quote=lgi2020]Realmente…

Os modificadores public e static poderiam ser implícitos.

Abraços.[/quote]

Do meu ponto de vista neste caso não poderiam, pois sem eles descritos de forma explicita não seria possível o compilador entender que o metodo “main” em questão se trataria do metodo principal, mesmo que o compilador levasse em consideração o nome do metodo e sua assinatura. Embora veja como incorreto a pessoa poderia ter uma classe que não fosse a principal e mesmo assim pretender colocar um metodo com o nome de “main”, e possuindo um “array” de “String” como parametro, e o programador não quer que seja o principal chamado pela aplicação. [/quote]

E se isso for uma especificação? Ai segue-se regras.