forçar implementação de equals e hashcode

11 respostas
rodrigo.bossini

Object fornece uma implementação padrão para equals e hashcode.

Estava eu aqui pensando com meus botões se existiria uma maneira de obrigar uma classe a fornecer uma implementação específica para ambos os métodos.

Não tem, né?

11 Respostas

E

Não, porque os métodos não são abstratos em Object. E você também não pode torná-los abstratos em uma subclasse de Object.

rodrigo.bossini

Seria interessante se, por exemplo, a gente criasse uma interface, colocasse as assinaturas destes métodos na interface e, a partir daí, a implementação fosse obrigatória, né?

E

Você está se referindo ao C#, onde você pode indicar que um determinado método implementa EXPLICITAMENTE uma interface?

public interface IDisposable 
{
    void Dispose();
}
...
class MyClass : IDisposable 
{
    /// <summary>Implementação EXPLÍCITA de IDisposable</summary>
    public void IDisposable.Dispose () 
    {
    }
}
rodrigo.bossini

Não. Estou falando de java.

Foi exatamente isso que eu disse com a frase:

Com isso aí eu quis dizer que poderia ser possível criar uma interface, colocar as assinaturas dos métodos nela, e a partir daí, cada classe que implementasse esta interface seria obrigada a fornecer uma nova implementação para os métodos. O que não é possível. Obrigado.

sergiotaborda

rod.attack:
Object fornece uma implementação padrão para equals e hashcode.

Estava eu aqui pensando com meus botões se existiria uma maneira de obrigar uma classe a fornecer uma implementação específica para ambos os métodos.

Não tem, né?

Claro que tem.

A opção mais trivial é criar uma Classe super pai de todos que herda de object e da qual todas as suas classes herdam. Não todas.Apenas as que precisam de equals e hashCode implementados. Um HashableObject , por exemplo. Esta classe simplesmente define esses métodos como abstratos forçando assim a sua implementação.

Mas como usar herança é algo que só se pode fazer uma vez fica complicado controlar classes netas de HashableObject.
A opção então é usar anotações e o APT. Neste esquema o APT testa a existencia da anotação @InheritHashAndEquals que signifcia que a classe usa
as implementações da classe pai.
Sem a presença da anotação o APT procura por implementações dos métodos na classe espeficada. Se encontrar otimo, se não, lança um erro.

O APT pode ser intregado ao processo de compilação não deixando o codigo compilar se não tiver as implementações devidas.

Ferramentas menos sofisticadas não forçam a implementação, mas podem avisar quando detectarem inconsistencias, com o CheckStyle

P.S. A APT foi adicionada no java 5 mas foi depois padronizada e inserida no java 6 http://www.javabeat.net/articles/14-java-60-features-part-2-pluggable-annotation-proce-1.html

rodrigo.bossini

Tenho uma classe que gostaria de obrigar a implementar equals e hashcode. Se ela não fizer isso, quero que seja gerado um erro de compilação.

Tem um exemplo aí usando o APT de como isso seria feito?

sergiotaborda

rod.attack:
Tenho uma classe que gostaria de obrigar a implementar equals e hashcode. Se ela não fizer isso, quero que seja gerado um erro de compilação.

Tem um exemplo aí usando o APT de como isso seria feito?

Não. Terá que pesquisar…

gomesrod

Se for só uma parte das classes do sistema (por exemplo: apenas as entidades) dá para utilizar a idéia do Sérgio e criar uma classe mãe que obrigue essa implementação. Mas como ele disse, se for em todas fica complicado.

E para que a classe mãe obrigue a implementação pode ser mais ou menos assim:

abstract class Entity {
  // Sobrescreve equals
  public boolean equals(Object o) {
     // Chama o método que deve ser obrigatoriamente implementado pelas filhas
     return isEqual(o);
  }
  
  // Método de implementação obrigatória nas classes filhas
  public abstract boolean isEqual(Object o);

  /* Faz o mesmo para o hashcode */
}
rodrigo.bossini

sergiotaborda:
rod.attack:
Tenho uma classe que gostaria de obrigar a implementar equals e hashcode. Se ela não fizer isso, quero que seja gerado um erro de compilação.

Tem um exemplo aí usando o APT de como isso seria feito?

Não. Terá que pesquisar…

Valeu. Já deu pelo menos uma ideia.

E

Na prática, o melhor é você usar algum plugin para a sua IDE, como o CheckStyle ou o PMD, e forçar essa regra apenas em classes de alguns subpacotes que você determinar no seu projeto. Por exemplo, classes que devam ser inseridas em hashmaps você pode deixá-las em um determinado subpacote, e então você determina uma regra para o CheckStyle verificar se hashCode e equals estão implementadas nessas classes.

dyorgio

vc pode verificar em runtime tb com reflection…
pode ser rapido se bem implementado (HashSet com as classes ja verificadas).

Criado 18 de fevereiro de 2010
Ultima resposta 18 de fev. de 2010
Respostas 11
Participantes 5