J'ai été inspiré par l'article ci-dessous.
Je veux afficher true même en Java avec a == 1 && a == 2 && a == 3 --Qiita Je veux afficher true en Java avec a == 1 && a == 2 && a == 3 (édition PowerMockito) --Qiita Je veux afficher true même en Java avec a == 1 && a == 2 && a == 3 (Black Magic) --Qiita Je veux afficher true même en Java avec a == 1 && a == 2 && a == 3 (édition noire) --Qiita
Puisqu'il a été réalisé par Proxy de la bibliothèque standard Java, il est nécessaire d'implémenter l'interface.
Point d'accès
public static void main(String... args) throws Exception {
	{
		System.out.println("Tout d'abord, si vous l'exécutez normalement ...");
		Judge judge = new JudgeImpl();
		test(judge);
	}
	{
		System.out.println("Si vous mordez le 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) );
}
Logique du jugement
public class JudgeImpl implements Judge{
    public boolean judge(int a) {
        if (a == 1 && a == 2 && a == 3) {
            return true;
        } else {
            return false;
        }
    }
}
L'interface cible pour réécrire le résultat du traitement
public interface Judge {
    public boolean judge(int a);
}
Classe proxy qui réécrit le résultat du traitement
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
/**Dans l'interface spécifiée par la méthode addInterface
La valeur de retour est(B|b)S'il existe une méthode booléenne, le résultat sera vrai*/
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("Vraiment`"+normalValue+"`J'ai entendu que tu voulais revenir`true`Je reviendrai!");
				return true;
			}
			return normalValue;
		}
	}
}
Tout d'abord, si vous l'exécutez normalement ...
false
false
false
Si vous mordez le proxy ...
Vraiment`false`J'ai entendu que tu voulais revenir`true`Je reviendrai!
true
Vraiment`false`J'ai entendu que tu voulais revenir`true`Je reviendrai!
true
Vraiment`false`J'ai entendu que tu voulais revenir`true`Je reviendrai!
true
        Recommended Posts