Javaで、equalsとhashCodeをオーバーライドするのが面倒くさい

※本質を逃していたので色々変えました。201201101948

Javaで、構造体のように使うクラスでは、通常equalsやhashCodeをオーバーライドするが、これが毎回同じようなコードを書かされて面倒くさい。

リフレクション(java.lang.reflect)APIを調べてみたら、これを継承で済ませられることが判明したので作った。

「同じようなコード」は、以下のブログ記事を参考にしています。
http://d.hatena.ne.jp/daira1004/20080501/1209652634

DataObject.java
import java.lang.reflect.*;

public class DataObject {

    public boolean equals(Object o){

        Class classX = this.getClass();
        Class classY = o.getClass();

        if(classX != classY)
            return false;

        Field[] fields = classX.getFields();

        try {
            for(Field f : fields){
                if(!f.get(this).equals(f.get(o)))
                    return false;
            }
        }
        catch(IllegalAccessException e){            
            e.printStackTrace();
            throw new Error();
        }

        return true;
    }

    public int hashCode(){
        final int m = 37;

        int ans = 17;

        for(Field f : this.getClass().getFields()){
            Class t = f.getType();
            int plus = 0;

            try {
            
                if(t == boolean.class)
                    plus = f.getBoolean(this) ? 0 : 1;
                else if(t == byte.class)
                    plus = (int)f.getByte(this);
                else if(t == char.class)
                    plus = (int)f.getChar(this);
                else if(t == short.class)
                    plus = (int)f.getShort(this); 
                else if(t == int.class)
                    plus = f.getInt(this);
                else if(t == long.class) {
                    long tmp = f.getLong(this);
                    plus = (int)(tmp ^ (tmp >>> 32));
                }
                else if(t == float.class)
                    plus = Float.floatToIntBits(f.getFloat(this));
                else if(t == double.class){
                    long tmp = Double.doubleToLongBits(f.getDouble(this));
                    plus = (int)(tmp ^ (tmp >>> 32));
                }
                else 
                    plus = f.get(this).hashCode();

            }
            catch(IllegalAccessException e){
                e.printStackTrace();
                throw new Error();
            }

            ans = m * ans + plus;
        }

        return ans;
    }

}

使用側サンプル

Test.java
import java.lang.reflect.*;

public class Test {

    public static void main(String[] args) {
        Hoge hoge = new Hoge(1,2);
        Hoge hoge2 = new Hoge(1,2);
        System.out.println(hoge.equals(hoge2)); //true
    }

    public static class Hoge extends DataObject {
        public final int a;
        public final int b;

        public Hoge(int a, int b) {
            this.a = a;
            this.b = b;
        }
    }

}