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

30 respostas
peerless

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

}

30 Respostas

T

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.

peerless

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.

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:

T

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.

peerless

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.

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:

peerless

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

T

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.

peerless

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

R

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

peerless

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!

sergiotaborda

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 ?

lgi2020

Realmente…

Os modificadores public e static poderiam ser implícitos.

Abraços.

T

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.

peerless

sergiotaborda:
peerless:

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

void main(String args[]) {

//comandos

}

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 ?

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…

T

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.

peerless

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.

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

T

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

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.

javapaulomg

lgi2020:
Realmente…

Os modificadores public e static poderiam ser implícitos.

Abraços.

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.

peerless

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

valeu…

peerless

javapaulomg:
lgi2020:
Realmente…

Os modificadores public e static poderiam ser implícitos.

Abraços.

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.

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

javapaulomg

peerless:
javapaulomg:
lgi2020:
Realmente…

Os modificadores public e static poderiam ser implícitos.

Abraços.

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.

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

Sim creio eu que seja uma especificação, porém neste caso em particular o metodo “main” e aberto a possibilidade do programdor decidir se o mesmo sera utilizado como principal por sua aplicação ou será apenas um metodo com o nome “main” sem ser o principal.
Porem em certos pontos a linguagem adota trechos implicitos, isso ao meu ver porque não poderia ser implementado de forma diferente, logo seria retundante informar o que so pode ser aquilo mesmo, um exemplo e uma “suposta” varíavel de instância em uma interface, sendo que a mesma se trata de uma constante, já que uma interface não pode conter varíaveis de instância.
Sendo assim pressumo que a Sun, adorte somente trechos implicitos quando o mesmo não possuir meios diferentes de ser declado.

ViniGodoy

Eu também acho que o método main está bom do jeito que está.

E também concordo com o Thigol, o método main do C e do C++ são realmente estranhos de se entender, muito piores que os do Java. Sou programador C++ a 10 anos.

E no java, vale mesmo o que está escrito. As regras de omissão costumam a ser bastante claras. Por exemplo, no caso de interfaces, a regra imposta é que todos os métodos são publicos, então, permite-se a omissão.

No caso do main, a JVM também permite que você tenha outros métodos, que não o principal, chamados main. Não creio que isso seja elegante, mas é possível e certamente alguém por aí reclamaria se a regra fosse alterada. Basta não declarado como static ou public.

Mas eu concordo com você em um aspecto. Poderiam ter criado uma sintaxe mais simples para o main, lá no começo do Java. Pena q agora talvez seja um pouco tarde…

PS: Thingol, essa história de pedir para o cara baixar os fontes me cheirou ao argumento do pessoal do Linux. Acho que a maior parte dos mortais evitará ao máximo baixar o código de um compilador ou de um SO se puder. Além disso, creio que nosso colega quisesse algo padrão, que servisse para comunidade, e não só para o compilador dele. Até pq, do contrário, ele nem precisa alterar o java.exe. Bastaria ele fazer um script que fizesse a leitura do arquivo com o main e o alterasse para a sintaxe normal, antes de compilar… (tal como várias mágicas sintáticas feitas pelo compilador do C ou do C++ antes de efetivamente compilar o código)

Claro, de qualquer forma, deve ser bastante interessante alterar o java.exe, como uma experiência… :wink:

T

Bom, de qualquer maneira, a última referência é a JLS - Java Language Specification.
Você pode sugerir alterações à linguagem úteis ou não tão úteis; bugs.sun.com recebe suas sugestões, assim como os fóruns de java.net.

T

ViniGodoy:

PS: Thingol, essa história de pedir para o cara baixar os fontes me cheirou ao argumento do pessoal do Linux. Acho que a maior parte dos mortais evitará ao máximo baixar o código de um compilador ou de um SO se puder. Além disso, creio que nosso colega quisesse algo padrão, que servisse para comunidade, e não só para o compilador dele. Até pq, do contrário, ele nem precisa alterar o java.exe. Bastaria ele fazer um script que fizesse a leitura do arquivo com o main e o alterasse para a sintaxe normal, antes de compilar… (tal como várias mágicas sintáticas feitas pelo compilador do C ou do C++ antes de efetivamente compilar o código)

Claro, de qualquer forma, deve ser bastante interessante alterar o java.exe, como uma experiência… ;)

O pessoal de Java e o pessoal de Linux (e o de Open-Source, ou FOSS) têm muitos pontos em comum, incluindo alguma “religiosidade” e fanatismo que pode ser encontrado em ambos. (Sou velho demais para acreditar nessas coisas - declaro-me agnóstico). Você não percebeu? :stuck_out_tongue:
De qualquer maneira, existem os canais adequados para a solicitação de novos recursos (bugs.sun.com, JCP, java.net etc.), e é possível fazer as experiências.
Que tal acrescentar “operator overloading” ao Java, por exemplo? Eu sei que em Java “vale o que está escrito” (se bem que o “foreach” não é bem assim…), e com “operator overloading” isso começará a não valer mais, mas isso pode ser tentado como uma experiência.

ViniGodoy

Ótimo, poderíamos adotar a sugestão dos mains parecidos com os do C++, acrescentar recursos de templates, constness, operator overloading, aritmética de ponteiros, suporte a funções estruturadas e sem classes e uma fase de substituição sintática (com macros e defines) e chamar a nova linguagem de Java++.

Esqueci de alguma coisa? heheheheeh. :slight_smile:

T

Não se esqueceu de “closures” e suporte a XML e SQL diretamente no código Java? É o que o pessoal queria pôr no Java 7, mas não vai dar tempo…

peerless

XML e SQL dentro do código já não são mascarados com anotações?

nbluis

Não vejo problemas quanto a isso…

Pelo menos da maneira como é hoje, é extremamente simples entender seu funcionamento.

Lembrando que o nome do método main não é nada mais que convenção.

Posso ter métodos main até sobrecarregados dentro da minha classe sem problemas.

por exemplo

public static void main(String... args);
public void main(int i);
private void main(char c);
T

XML e SQL dentro do código já não são mascarados com anotações?

Não é bem isso. É algo parecido com o LINQ, que vai aparecer no Visual Studio 2008.

Por exemplo, você pode fazer parse de XML com o LINQ em C# e VB.NET sem ter de usar DOM ou SAX ou coisa parecida - simplesmente especifique um fragmento do XML que você quer ler, com as variáveis onde os valores devem ser carregados.

nbluis

ViniGodoy:
Ótimo, poderíamos adotar a sugestão dos mains parecidos com os do C++, acrescentar recursos de templates, constness, operator overloading, aritmética de ponteiros, suporte a funções estruturadas e sem classes e uma fase de substituição sintática (com macros e defines) e chamar a nova linguagem de Java++.

Esqueci de alguma coisa? heheheheeh. :)

]

Dai eu viro pintor.

peczenyj

Medo do que vai ser o Java 8…

Criado 10 de outubro de 2007
Ultima resposta 10 de out. de 2007
Respostas 30
Participantes 9