2017-12-04 18 views
1

かなりのクラスのプロジェクトがあり、Debugと実行すると、IntellijのRunと比べると、さまざまな答えが出ます。正解ですが、どちらの場合も異なります。hashCodeを実装していないクラスを見つけよう

私は、違いの原因であるhashCodeを実装していないクラスが1つ以上あると思われます。私たちはいくつかの場所でハッシュベースのコレクションを使用します。

hashCodeを実装していないクラスは、手作業で手を通すことなく簡単に見つけることができますか?

+0

「hashCode()」をオーバーライドするクラスを見つける方が簡単かもしれません。 – shmosel

+2

"正解ですが、どちらの場合も異なります。"それが正しいなら、何が問題なのですか? .NETのいくつかのバージョンが、デバッグモードで実行されているかどうかに基づいて故意に変更された文字列ハッシュコードアルゴリズムを知っています - 同じことをやっているJavaについてはわかりませんが、そうするのが有効です。複数の実行で安定しているハッシュコードに頼っているのであれば、それはバグです。 –

+0

HashMapなどで使用されるすべてのクラスが 'hashCode()'を実装する必要はありません。代わりに、すべてのクラスを2つのカテゴリのいずれかに属するものと考えてください。最初の値ベースのクラスには、StringとIntegerが含まれます。 2つの整数値1234の両方は、異なるオブジェクトであるかどうかにかかわらず同じとみなされます。一方、IDベースのクラスオブジェクトは、同じ値を持っていても互いに区別されます。もしあなたと私が両方ともフレッドと名付けられれば、それは私たちを同じ人にしません。アイデンティティクラスは 'equals()'と 'hashCode()'をオーバーライドする必要はありません。 – DodgyCodeException

答えて

1

カスタムクラスローダーでhashCodeをオーバーライドしないプリントクラスを実行してみることもできます。 -Djava.system.class.loader=my.package.HashFindingLoader

package my.package; 
import java.lang.reflect.Method; 

public class HashFindingLoader extends ClassLoader { 

    public HashFindingLoader(ClassLoader parent) { 
     super(parent); 
    } 

    @Override 
    public Class<?> loadClass(String name) throws ClassNotFoundException { 
     Class<?> c = super.loadClass(name); 

     //filters out librry classes, adjust as necessary 
     if(!c.getPackage().getName().matches("^(java|sun).*")){   
      Method hashCode; 
      try { 
       hashCode = c.getMethod("hashCode"); 
      } catch (NoSuchMethodException|SecurityException ex) { 
       throw new RuntimeException(ex); 
      } 
      if (hashCode.getDeclaringClass().equals(Object.class)){ 
       System.out.printf("%s does not override hashCode%n", c); 
      } 
     } 
     return c; 
    } 

} 
関連する問題