Java
黒魔術

Java でもa == 1 && a == 2 && a == 3でtrueって出力させたい(黒魔術ってほどでもないグレーな魔術編)

以下記事に感化されて書きました。

Java でもa == 1 && a == 2 && a == 3でtrueって出力させたい - Qiita
Java でもa == 1 && a == 2 && a == 3でtrueって出力させたい(PowerMockito編) - Qiita
Java でもa == 1 && a == 2 && a == 3でtrueって出力させたい(黒魔術編) - Qiita
Java でもa == 1 && a == 2 && a == 3でtrueって出力させたい(真っ黒編) - Qiita

Java標準ライブラリのProxyで実現しましたので、インターフェイスの実装が必要となります。

エントリポイント
public static void main(String... args) throws Exception {
    {
        System.out.println("まずは普通に実行すると・・・");
        Judge judge = new JudgeImpl();
        test(judge);
    }
    {
        System.out.println("Proxyをかましてやると・・・");
        Judge judge = new AlwaysTrue.Builder()
                .addInterface(Judge.class)
                .build(JudgeImpl.class);
        test(judge);
    }
}

private static void test(Judge judge){
    System.out.println( judge.judge(1) );
    System.out.println( judge.judge(2) );
    System.out.println( judge.judge(3) );
}
判定ロジック
public class JudgeImpl implements Judge{
    public boolean judge(int a) {
        if (a == 1 && a == 2 && a == 3) {
            return true;
        } else {
            return false;
        }
    }
}
処理結果を書き換える対象とするインターフェイス
public interface Judge {
    public boolean judge(int a);
}
処理結果を書き換えるプロキシクラス
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

/** addInterfaceメソッドで指定したインターフェイスの中で
戻り値が(B|b)ooleanのメソッドがあれば、その結果がtrueになるよ */
public class AlwaysTrue{

    public static class Builder{
        List<Class<?>> interfaces = new ArrayList<>();
        public Builder addInterface(Class<?> interfaze) {
            interfaces.add(interfaze);
            return this;
        }
        private Class<?>[] getInterfacesArray(){
            Class<?>[] clazzArr = new Class[interfaces.size()];
            for( int i =0;i<interfaces.size();i++) {
                clazzArr[i] = interfaces.get(i);
            }
            return clazzArr;
        }

        public <E> E build(Class<?> clazz) throws Exception {
            Object normalInstance = clazz.newInstance();
            Object prankInstance = Proxy.newProxyInstance(
                    clazz.getClassLoader(),
                    getInterfacesArray(),
                    new AlwaysTrueHandler(normalInstance));
            @SuppressWarnings("unchecked")
            E o = (E)prankInstance;
            return o;
        }
    }

    private static class AlwaysTrueHandler implements InvocationHandler {
        private Object normalInstance;
        public AlwaysTrueHandler( Object normalInstance){
            this.normalInstance = normalInstance;
        }
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object normalValue =  method.invoke(normalInstance, args);
            if( method.getReturnType() == Boolean.class
                    || method.getReturnType() == boolean.class ){
                System.out.println("ほんとうは`"+normalValue+"`を返したいらしいけど、`true`を返すぜ!");
                return true;
            }
            return normalValue;
        }
    }
}

実行結果

まずは普通に実行すると・・・
false
false
false
Proxyをかましてやると・・・
ほんとうは`false`を返したいらしいけど、`true`を返すぜ!
true
ほんとうは`false`を返したいらしいけど、`true`を返すぜ!
true
ほんとうは`false`を返したいらしいけど、`true`を返すぜ!
true