Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

sekkuar

Códigos Mentirosos

Recommended Posts

Já faz um tempo, eu dou uma olhada nos códigos do JDK, e percebo algumas coisas bem mentirosas, que as vezes me deixam confuso ou indignado.

 

Não que o código seja mentira, mas pelo menos a documentação é

 

vou postar alguns exemplos, e vocês me dizem o que acham

 

java.awt.event.KeyEvent

/**
    * This constant is obsolete, and is included only for backwards
    * compatibility.
    * @see #VK_SEPARATOR
    */
   public static final int VK_SEPARATER      = 0x6C;

   /**
    * Constant for the Numpad Separator key.
    * @since 1.4
    */
   public static final int VK_SEPARATOR      = VK_SEPARATER;

 

Porque o primeiro é obsoleto se ele é igual ao segundo??

 

 

java.awt.Component

/**
    * Transfers the focus to the next component, as though this Component were
    * the focus owner.
    * @see       #requestFocus()
    * @since     JDK1.1
    */
   public void transferFocus() {
       nextFocus();
   }

   /**
    * @deprecated As of JDK version 1.1,
    * replaced by transferFocus().
    */
   @Deprecated
   public void nextFocus() {
       transferFocus(false);
   }

 

nextFocus() é obsoleto, deve ser substituido por transferFocus().

Mas, transferFocus simplesmente chama nextFocus!!!!

 

porque eu não devo usar, se ele mesmo usa?

 

java.awt.Component (de novo!)

   /**
    * Shows or hides this component depending on the value of parameter
    * <code>b</code>.
    * <p>
    * This method changes layout-related information, and therefore,
    * invalidates the component hierarchy.
    *
    * @param b  if <code>true</code>, shows this component;
    * otherwise, hides this component
    * @see #isVisible
    * @see #invalidate
    * @since JDK1.1
    */
   public void setVisible(boolean B) {
       show(B);
   }

/**
    * @deprecated As of JDK version 1.1,
    * replaced by <code>setVisible(boolean)</code>.
    */
   @Deprecated
   public void show() {
     //[...]
   }

/**
    * @deprecated As of JDK version 1.1,
    * replaced by <code>setVisible(boolean)</code>.
    */
   @Deprecated
   public void show(boolean B) {
       if (B) {
           show();
       } else {
           hide();
       }
   }

/**
    * @deprecated As of JDK version 1.1,
    * replaced by <code>setVisible(boolean)</code>.
    */
   @Deprecated
   public void hide() {
      //[...]
   }

 

Todo mundo sabe que não se deve usar o show() ou hide(), ou show(boolean), se usa o setVisible(boolean) no lugar.

 

Por que mesmo??????

 

 

 

java.lang.Thread

Essa foi a primeira que me deixou indignado

/**
    * Causes the currently executing thread to sleep (temporarily cease
    * execution) for the specified number of milliseconds, subject to
    * the precision and accuracy of system timers and schedulers. The thread
    * does not lose ownership of any monitors.
    *
    * @param  millis
    *         the length of time to sleep in milliseconds
    *
    * @throws  IllegalArgumentException
    *          if the value of {@code millis} is negative
    *
    * @throws  InterruptedException
    *          if any thread has interrupted the current thread. The
    *          <i>interrupted status</i> of the current thread is
    *          cleared when this exception is thrown.
    */
   public static native void sleep(long millis) throws InterruptedException;

   /**
    * Causes the currently executing thread to sleep (temporarily cease
    * execution) for the specified number of milliseconds plus the specified
    * number of nanoseconds, subject to the precision and accuracy of system
    * timers and schedulers. The thread does not lose ownership of any
    * monitors.
    *
    * @param  millis
    *         the length of time to sleep in milliseconds
    *
    * @param  nanos
    *         {@code 0-999999} additional nanoseconds to sleep
    *
    * @throws  IllegalArgumentException
    *          if the value of {@code millis} is negative, or the value of
    *          {@code nanos} is not in the range {@code 0-999999}
    *
    * @throws  InterruptedException
    *          if any thread has interrupted the current thread. The
    *          <i>interrupted status</i> of the current thread is
    *          cleared when this exception is thrown.
    */
   public static void sleep(long millis, int nanos)
   throws InterruptedException {
       if (millis < 0) {
           throw new IllegalArgumentException("timeout value is negative");
       }

       if (nanos < 0 || nanos > 999999) {
           throw new IllegalArgumentException(
                               "nanosecond timeout value out of range");
       }

       if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
           millis++;
       }

       sleep(millis);
   }

 

sleep(long millis, int nanos), diz que interrompe por milissegundos mais nanosegundos, mas na verdade, ele só faz uma verificação muito inteligente, e depois incrementa (ou não) um milisegundo a mais.

E ainda quer botar a culpa no sistema, dizendo

 

subject to the precision and accuracy of system

timers and schedulers.

 

 

esse me deixou muito indignado.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Todas, exceto a última, são apenas refatoração de código. Queriam renomear os métodos. Viram que os nomes não ficaram adequados e acharam nomes melhores. Mas por deixar a JDK portável, eles depreciaram aqueles métodos e criaram outros. Imagina que você tem um programa desenvolvido com java 5 e no java 6 não existisse mais o método. Pra você poder usar o java 6 teria que fazer uma série de mudanças. Já a última opção visa evitar problemas com contadores de tempo de diferentes sistemas operacionais e máquinas virtuais java.

Compartilhar este post


Link para o post
Compartilhar em outros sites

Bom, tem algumas coisas ali que na primeira olhada dão um sentimento de "WTF" ou "Mother of God". Acho que já encontrei um passatempo extra.

 

No caso do KeyEvent, a única justificativa plausível p/ mim p/ terem feito aquilo seria um erro na grafia da constante. Isso acontece direto na tradução do Opensuse (mesmo no string freeze os desenvolvedores alteram as mensagens porque os tradutores abrem bug report de palavras com grafia incorreta em inglês). Mas acho que o intervalo de tempo entre o JDK 1.1 e o 1.4 invalidariam essa possibilidade (será que temos que incluir corretores ortográficos antes do release do codigo?)

 

No segundo exemplo existe uma sutileza no código: existem dois métodos transferFocus diferentes pois possuem assinaturas diferentes. Repare que um deles não tem parâmetro Boolean (o marcado com @deprecated), mas o novo nextFocus utiliza um outro método transferFocus. Como venho de Python e C, onde não dá p/ ter métodos/funções com nomes iguais e assinaturas diferentes, nem sei como funciona o lance de argumento default em Java, acredito que os javeiros mais sérios podem explicar mais isso.

 

Quanto à retrocompatibilidade, tenho uma opinião dividida. Sei que seria um horror todo mundo ter que reescrever o código só porque a Sun/Oracle mudou uma letrinha no fonte, mas também não gosto da idéia de acumular código obsoleto de trocentos anos atrás, podendo piorar muito a manutenção da linguagem. Ppor isso eu gostei da iniciativa do pessoal do Python e do Perl de quebrar compatibilidade com as versões anteriores. Sei que o PHP também passou por isso e já ouvi gente dizendo que a implementação de namespaces no PHP 5.3 foi uma espécie de gato, mas não vou entrar em detalhes porque não conheço a linguagem.

 

 

 

 

Vergil:

 

Em relação à refatoração nesses pedaços da JDK eu tenho minhas dúvidas depois de ver o código com o show/hide/setVisible. No meu conceito o correto seria o código antigo usar o código novo e não o contrário. Como estou recomeçando pela "bolhonésima" vez a estudar Java SE (sempre larguei na parte de loops por perder o interesse) seria bom se você explicasse melhor qual seria a idéia dos devs do JDK.

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Isis,

 

A refatoração do mecanismo para se exibir ou esconder um componente trata-se apenas de uma padronização. No Java existe um padrão para encapsular um atributo de classe. O encapsulamento visa tornar o atributo private/protected e fornecer métodos de leitura e escrita (getters e setters).

private boolean visible;
public boolean isVisible() {
  return visible;
}

public void setVisible(boolean B) {
  this.visible(B);
}

Nesse caso você usa apenas um método para alterar o estado de um componente através do seu método de escrita. Para exibi-lo ou escondê-lo basta chamar o método setVisible passando true para exibir e false para esconder.

 

Resumindo, é só uma padronização. O nosso colega não postou o código do método show(), que é onde a "mágica" acontece. É o método show que altera o valor da variável visible (É feio! Mas é o que eles estavam tentando corrigir).

Se tiver interesse, podes dar uma bisbilhotada no código da classe java.awt.Component.

 

Eu entendo bem o por quê de você ter começado a estudar Java e desistir várias vezes. Pra quem já conhece uma linguagem de script como Python e Ruby fica difícil mexer com Java. O Java é muito burocrático e te obriga a escrever muito mais do que em Python e Ruby. Eu já tive experiências bem furtivas com Python e Ruby quando precisei montar scripts pra funcionar como uma espécie de shell script no Linux (Sou mil vezes implementar um código em Python do que em ShellScript). Nessa curta experiência eu pude verificar que você escreve bem menos. A linguagem é bem mais flexível. Por isso é muito mais fácil alguém do Java aprender essas linguagens do que o contrário, porque você não desanima. :rolleyes:

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.