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

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

[Java でもa == 1 && a == 2 && a == 3でtrueって出力させたい - Qiita](https://qiita.com/opengl-8080/items/a9e53d38c18a473e85b1)
[Java でもa == 1 && a == 2 && a == 3でtrueって出力させたい（PowerMockito編） - Qiita](https://qiita.com/ngsw_taro/items/594f14dd22afd1660091#_reference-5a780999deb3e546adee)
[Java でもa == 1 && a == 2 && a == 3でtrueって出力させたい（黒魔術編） - Qiita](https://qiita.com/deaf_tadashi/items/f145bc4645127b88281b)
[Java でもa == 1 && a == 2 && a == 3でtrueって出力させたい(真っ黒編) - Qiita](https://qiita.com/Wreulicke/items/425601e0d2b754e1251a)

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

```java:エントリポイント
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) );
}
```

```java:判定ロジック
public class JudgeImpl implements Judge{
    public boolean judge(int a) {
        if (a == 1 && a == 2 && a == 3) {
            return true;
        } else {
            return false;
        }
    }
}
```

```java:処理結果を書き換える対象とするインターフェイス
public interface Judge {
    public boolean judge(int a);
}
```

```java:処理結果を書き換えるプロキシクラス
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
```