I was inspired by the article below.
I want to output true in Java with a == 1 && a == 2 && a == 3 --Qiita I want to output true in Java with a == 1 && a == 2 && a == 3 (PowerMockito edition) --Qiita I want to output true in Java with a == 1 && a == 2 && a == 3 (black magic edition) --Qiita I want to output true in Java with a == 1 && a == 2 && a == 3 (black edition) --Qiita
Since it was realized by Proxy of Java standard library, it is necessary to implement the interface.
Entry point
public static void main(String... args) throws Exception {
{
System.out.println("First of all, if you execute it normally ...");
Judge judge = new JudgeImpl();
test(judge);
}
{
System.out.println("If you bite the 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) );
}
Judgment logic
public class JudgeImpl implements Judge{
public boolean judge(int a) {
if (a == 1 && a == 2 && a == 3) {
return true;
} else {
return false;
}
}
}
Interface for which the processing result is rewritten
public interface Judge {
public boolean judge(int a);
}
Proxy class that rewrites the processing result
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;
/**In the interface specified by the addInterface method
The return value is(B|b)If there is a boolean method, the result will be 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("Really`"+normalValue+"`I heard you want to return`true`I'll return!");
return true;
}
return normalValue;
}
}
}
First of all, if you execute it normally ...
false
false
false
If you bite the Proxy ...
Really`false`I heard you want to return`true`I'll return!
true
Really`false`I heard you want to return`true`I'll return!
true
Really`false`I heard you want to return`true`I'll return!
true
Recommended Posts