Coisas que odeio em Java

Nem tudo é perfeito, o Java infelizmente não foge a essa regra. Segue abaixo a minha lista de coisas que não gosto na linguagem. Você tem também suas “mágoas”? Dê sua opinião!

  1. O comando wait(0) espera para sempre, ao invés de não esperar. Isso torna códigos que façam wait baseados em algum cálculo um inferno, já que sempre temos que testar se o resultado é zero;

  2. O wait está sujeito a spurious wakeups;

  3. Quando interagindo com aplicações C++, realmente faz falta os tipos unsigned. Pelo menos, em cases de stream de sockets e na classe ByteBuffer (onde assume-se que você vai trabalhar com alguém externo) deveriam haver métodos nativos para trabalhar com unsigned, nem que fosse fazendo conversões só para a rede;

  4. Existem coisas extremamente complexas que são fáceis de fazer (como esperar uma conexão ou sincronizar threads). Por outro lado, coisas triviais em outras linguagens (limpar o console, pegar o diretório que a aplicação roda) são praticamente impossíveis de se fazer em java;

  5. O método read de um socket bloqueante lê n bytes ou menos, e não especificamente os n bytes, como seria em qualquer outra implementação socket padrão;

  6. A linguagem java deveria ter removido o break do switch. Já que fall through é muito sujeito a erros. O mesmo vale para ifs envolvendo atribuições e outros mandraquismos “C”;

  7. Não está no contrato do close() do OutputStream a necessidade de um flush() antes de fechar a conexão;

  8. Existem coisas que simplesmente deveriam estar no Swing e não estão. Por exemplo, setLength() no JTextField, a classe JTreeTable, etc. Ok, o Swing é bem feito e isso é implementável, mas coisas tão úteis assim deveriam vir na biblioteca padrão. A utilidade dessas coisas é comprovada até por artigos da própria Sun, que ensinam a implementar tais funcionalidades;

  9. A API está começando a ficar “gorda”, já que em nome da compatibilidade classes muito antigas não são eliminadas. Infelizmente, não creio que haja uma solução para esse problema, a não ser talvez criar duas distribuições java (uma com as classes do passado, outra sem, para ser usada em projetos novos).

[EDIT] 10. O Swing é muito poderoso, mas também é muito pesado.

  1. Não deveria ser permitido uma subclasse ter um atributo com o mesmo nome de um atributo visível na superclasse.

  2. Deveria haver o escopo de subpacote e um encapsulamento que envolvesse herança, mas não visibilidade entre membros de um mesmo pacote. Mas dá para entender o porque de não fazer isso, ter centenas de tipos de visibilidade podem trazer mais mal do que bem…

PS: O título do Java foi só para chamar a atenção. Muita coisa eu realmente não odeio, só desgosto ou me incomoda um pouco.

Olá,

Acho que uma das coisas que mais enche a paciencia é mexer com data (sem user JODA).

[]´s

[quote=ViniGodoy]Nem tudo é perfeito, o Java infelizmente não foge a essa regra. Segue abaixo a minha lista de coisas que não gosto na linguagem. Você tem também suas “mágoas”? Dê sua opinião!

  1. O comando wait(0) espera para sempre, ao invés de não esperar. Isso torna códigos que façam wait baseados em algum cálculo um inferno, já que sempre temos que testar se o resultado é zero;
    [/quote]

Concordo, todos SOs definem que esperar por zero retorna imediatamente, ou faz pooling no caso de aquisição de recursos.

Ainda bem, caso contrario seria uma primitiva inutil. Todos SOs definem que toda espera está sujeita a cancelamento, isso é um mecanismo muito importante para construir sistemas confiaveis. Mas que é um saco, isto é.

Assim tipos escalares definidos pelo usuário.

Java não tem suporte a algo como o curses, logo qualquer coisa envolvendo console é um parto - pior que limpar é descobrir a dimensão.

Hmm, pelo contrário, em todos sistemas unix, esse é o comportamento se você usar recv() ou read() em um socket. http://www.opengroup.org/onlinepubs/007908799/xns/recv.html. Com windows é a mesma coisa, ou seja, retornar a quantidade lida não só é o comportamento normal, como também a forma correta de operar.

Java não deveria ter switch, deveria ter pattern matching.

Ainda bem, imagine quando se precisar fechar um stream sem escrever o conteúdo do buffer dele?

[quote=ViniGodoy]
8. Existem coisas que simplesmente deveriam estar no Swing e não estão. Por exemplo, setLength() no JTextField, a classe JTreeTable, etc. Ok, o Swing é bem feito e isso é implementável, mas coisas tão úteis assim deveriam vir na biblioteca padrão. A utilidade dessas coisas é comprovada até por artigos da própria Sun, que ensinam a implementar tais funcionalidades;

  1. A API está começando a ficar “gorda”, já que em nome da compatibilidade classes muito antigas não são eliminadas. Infelizmente, não creio que haja uma solução para esse problema, a não ser talvez criar duas distribuições java (uma com as classes do passado, outra sem, para ser usada em projetos novos).[/quote]

Quanto ao Swing, não posso comentar, não uso. Quanto a remover todo junk, bom, isso seria perfeitamente possivel se os arquivos .class carregassem informação de dependencia junto.

Para esperar indefinidamente, o valor deveria ser -1 em vez de 0. Realmente foi mal escolhido.

Acho que foi uma decisão de implementação porque eles não conseguiram um "wait" que funcionasse direito em todos os sistemas operacionais suportados.

É por isso que o C# tem tipos signed e unsigned. Uma coisa que me enche o saco é o tipo "byte" ser signed e o tipo "char" ser unsigned, em Java - ambos deveriam ser unsigned. O operador "&gt&gt&gt" é uma forma patética de remendar essa deficiência. Até em Modula-3 (uma linguagem criada pelo Niklaus Wirth, criador do Pascal, AKA Delphi) existe o tipo "CARDINAL" que é o nosso velho e conhecido unsigned.

Isso é herança acadêmica - veja a descrição da classe java.util.Date; ela não tem as coisas mais elementares que são necessárias com datas.

Isso, como foi dito acima, é comum para todas as linguagens que têm suporte a sockets.

O C# fez isso, mesmo sacrificando um pouco a compatibilidade (ao nível de "bugs"?) com o C/C++.
Ainda acho que a atribuição deveria ser ":=" e a comparação "=", tal como no Pascal (mas sem repetir os erros dele, como a precedência de operadores que é esquisita).

Hum…

De fato o Swing é um pouco esquizofrênico - muitas coisas úteis não existem, ou não funcionam direito.

[quote]
9. A API está começando a ficar "gorda", já que em nome da compatibilidade classes muito antigas não são eliminadas. Infelizmente, não creio que haja uma solução para esse problema, a não ser talvez criar duas distribuições java (uma com as classes do passado, outra sem, para ser usada em projetos novos).[/quote]
API gorda? Compare com as APIs do Windows. Isso sim é que é API gorda.

[quote=ViniGodoy]
9. A API está começando a ficar “gorda”, já que em nome da compatibilidade classes muito antigas não são eliminadas. Infelizmente, não creio que haja uma solução para esse problema, a não ser talvez criar duas distribuições java (uma com as classes do passado, outra sem, para ser usada em projetos novos).[/quote]

Acho que uma possível solução para isso seria manter a compatibilidade com 2 ou no máximo 3 versões anteriores, passando disse seria removido! Mas o impacto que isso traria não sei dizer!

ASOBrasil

Tem muito software aqui feito em Java 1.3, se por exemplo ficássemos atrelados a compatibilidade de 2 ou 3 versões, apartir do Java6, teríamos que migrar toneladas de código.

A proposta de uma versão que continue compatível com as mais antigas e uma compatível com o somente a versão atual seria legal.

Até!

Concordo plenamente!!

Uma coisa que existe em Pascal, Ada e mais algumas linguagens é o tipo “range”. Por exemplo, você pode ter algo como:

type Card : 1..52;

e isso já faz um “bounds checking” em tempo de compilação e execução. Ele é complementar aos “enums”.
Isso poderia existir em Java, até para definir arrays de forma mais decente. Acho horrível essa herança do C++. Por que é que não posso ter algo como:

type Card = 1..52;
boolean[Card] naipe  = new boolean [Card];

e os elementos vão de naipe[1] a naipe[52], sem desperdiçar elementos (o offset é inserido pelo compilador, em vez de sê-lo pelo programador. )

Thingol,

Concordo que a API do Windows é obesa… mas isso não tira o mérito do que eu falei, pois a API do Java está começando a engordar.

Se eles não fizerem uma limpa nunca, cedo ou tarde o java também ficará cheio de lixo.

[quote=ViniGodoy]Nem tudo é perfeito, o Java infelizmente não foge a essa regra. Segue abaixo a minha lista de coisas que não gosto na linguagem. Você tem também suas “mágoas”? Dê sua opinião!

  1. O comando wait(0) espera para sempre, ao invés de não esperar. Isso torna códigos que façam wait baseados em algum cálculo um inferno, já que sempre temos que testar se o resultado é zero;

  2. O wait está sujeito a spurious wakeups;

[/quote]

Porque raios vc faz um wait baseado num calculo ??

use char. char é unsigned

limpar o console !? vejo que vc faz muits programas de console…
nesse caso melhor usar swing e mandar escreve num component e depois apagá-lo. Afinal qual é a diferença entre o console um textarea ?

para saber onde roda File startupFolder = new File("."); em standalone
application.getRalPath("/"); em web

é que podem não existir n bytes para ler…

Vc não quer fall through ? use if/else if
Depois de remover o break, removam também os genérics … afinal podemos codificar tão bem ou melhor sem isso.

Aqui eu concordo. Acontece que JTreeTable é um caso particular que mostra o poder do Swing. Esse acoplamento não é possível em nenhum outra tecnologia

Ela está ficando gorda porque os programadores não usam as classes que deveriam, não mudam o código quando algo fica deprecated. E é por causa deles que API é gorda.

Difícil pegar o diretório corrente da aplicação?? Apenas use assim:

String sDir = System.getProperty(“user.dir”);

Não testei mais pelo que me lembro das variáveis properties do sistema é assim.

Não vejo nada de errado com o break

Concordo no sentido de que o core do Java está ficando inutilmente gordo, mas não sei se seria a solução criar distribuições diferentes, talvez sim, ou não.

Vero! Mas talvez com o SwingFramework que será lançado na versão 7, fique o swing algo mais prático.

Uma coisa que acho chata de se trabalhar no Java como rodrigo gomes mesmo disse, é trabalhar com Java, para que há tantas classes para se trabalhar com datas? Acho ruim de fato. Existem até frameworks 0.o disso para java.

String sDir = System.getProperty(“user.dir”);

Isso não retorna o diretório da aplicação. Isso retorna o diretório corrente em que o usuário se encontra.

O que quero dizer é, em C++ é muito fácil pegar o diretório onde o .exe está gravado. Independente de qual caminho você esteja rodando o código, ou de qual seja o caminho da pasta “my docs” de seu usuário. Ok, ok, a desculpa oficial do java é: “Mas o .jar pode estar em qualquer lugar, até em um BD, ou num applet…” Mas a falta desse recurso torna aplicações com plugins gravados no diretório da aplicação (tais como o Eclipse) só resolvíveis com algum tipo de xunxo (será que é para isso que o Eclipse tem um .exe?).

Outra coisa, o problema não está no break do switch, mas no fato do switch fazer fall through. Ou seja, se você esquecer o break, ele cairá na próxima condição do switch, como se a avaliação da condição fosse verdadeira.

E isso certamente é comprovadamente propenso a erros.

No caso dos breaks eu também concordo, porém ja estou acostumado a acrescentar em cada case: um break;

case 1:
// cmds
break;

case 2:
// cmds
break;

Fazer o que né? :cry: :cry: :cry:

Rapaz, o caso do break eu tenho que discordar, depois que eu comecei a usar switches com enumns já tive vários casos de fallthrough.

O que ia resolver mesmo o problema é um switch com pattern matching, esse sim não precisaria de fallthrought.

Olá

Além da falta de inteiros de 64 bits, o que sempre senti falta no Java foi facilidade de acessar dispositivo periféricos. Não fosse por isto, Java teria sido realmente VB killer.

Pensando a posteriori, teria sido muito melhor que a Sun tivesse investido em facilidade de uso de periféricos TODO o tempo que gastou com J2EE (menos servlets e JMS).

[]s
Luca

[quote=Luca]Olá

Além da falta de inteiros de 64 bits, o que sempre senti falta no Java foi facilidade de acessar dispositivo periféricos. Não fosse por isto, Java teria sido realmente VB killer.
[/quote]

O que vc está chamando de periférico ali ?
Com qual periférico vc não consegue comunicar usando java ?

[quote=Luca]Olá

Além da falta de inteiros de 64 bits, o que sempre senti falta no Java foi facilidade de acessar dispositivo periféricos. Não fosse por isto, Java teria sido realmente VB killer.

Pensando a posteriori, teria sido muito melhor que a Sun tivesse investido em facilidade de uso de periféricos TODO o tempo que gastou com J2EE (menos servlets e JMS).

[]s
Luca[/quote]
Talvez eu esteja falando besteira, bem provável aliás, mas se eu não me engano, o long, que é um tipo inteiro, tem 64 bits.

[quote=elomarns][quote=Luca]Olá

Além da falta de inteiros de 64 bits, o que sempre senti falta no Java foi facilidade de acessar dispositivo periféricos. Não fosse por isto, Java teria sido realmente VB killer.

Pensando a posteriori, teria sido muito melhor que a Sun tivesse investido em facilidade de uso de periféricos TODO o tempo que gastou com J2EE (menos servlets e JMS).

[]s
Luca[/quote]
Talvez eu esteja falando besteira, bem provável aliás, mas se eu não me engano, o long, que é um tipo inteiro, tem 64 bits.[/quote]

Exactamente.
byte = 8 bits
short = 16 bits
int = 32 bits
long = 64 bits

Eu também concordo com a criação de uma máquina virtual mais limpa, sem nenhuma classe/método depreciado (nem é só pela performance, mas também pela limpeza e padronização).

A questão dos periféricos é interessante. Realmente, joysticks e alguns tipos de hardware não tem suporte em java puro. Até mesmo o uso pino-a-pino das portas serial e paralela não tem uma solução satisfatória em java puro.

Sempre tem que recair no JNI, ou para a biblioteca de alguém que usou o JNI para você. E isso sempre gera o stress de ter alguma dll anexada, ou monstrinhos para gravar no java/bin…

Também já sofri com isso.