gpt4 book ai didi

java - 编辑方法返回的内容 java

转载 作者:行者123 更新时间:2023-11-29 05:46:58 25 4
gpt4 key购买 nike

我在修改游戏时遇到了问题。我需要在不编辑方法本身的情况下修改方法返回的内容。我试着用 power-mock 来做这件事但没有成功。有谁知道如何使用 power-mock 或任何其他字节码操作库,甚至任何标准库来做到这一点?我愿意使用任何库,只要许可证允许它用于我的目的。

我希望能够编辑静态方法的返回值,以及所有对象的非静态方法的返回值。

这是我用 power-mock 尝试过的

import org.powermock.api.easymock.PowerMock;

import static org.easymock.EasyMock.expect;

public class BeanTest
{
public static void main(String[] args) throws Exception
{
Bean beanMock = PowerMock.createMock(Bean.class);
expect(beanMock.convert("world")).andReturn("WORLD");
System.out.println(beanMock.convert("world"));
}
}

public class Bean
{
protected String convert(String name)
{
throw new UnsupportedOperationException("not implemented yet");
}
}

最佳答案

在 Java 中,返回类型不是方法签名的一部分,因此您可以随心所欲地使用它。

有两种方法可以透明地实现这一点:

  1. 如果您可以控制要从中调用方法的对象的注入(inject),则使用 Java 动态代理。
  2. 使用带有环绕建议的 AspectJ 方面,您可以操作不受您控制的代码(第三方库)。通过编译时编织或加载时编织使用 AspectJ

编辑:

使用 java 动态代理(用于接口(interface))或 CGlib(用于类),您可以使用一个接口(interface)指向一个代理,您可以从中与调用相交,对其进行处理,然后将其委托(delegate)给真正的实现。为此,您必须控制依赖注入(inject)。 Here is a nice explanation .

示例:

SomeInterface t = (SomeInterface) Proxy.newProxyInstance(SomeInterface.class.getClassLoader(),
new Class<?>[] {SomeInterface.class},
new TestInvocationHandler(new TestImpl()));

它的作用:TestInvocationHandler 扩展了 InvocationHandler 接口(interface)。 TestImpl 是一个实现 SomeInterface 的类。当您从 SomeInterface 调用一个方法时,它将在 TestInvocationHandler 中结束。 InvocationHandler 有一个调用方法,如下所示:

public Object invoke(Object proxy, Method method, Object[] args);
  • 代理 - 对对象的引用

  • method - 被调用的方法

  • args - 方法的参数

例如,使用 AspectJ,您可以使用切入点指定应该包装在环绕建议中的内容。 AspectJ 的优点是无需任何显式编程即可操作已编译的代码或您自己的代码。

例子:

@Aspect
public class MyAspect {

@Around("execution(* org.example.yourMethod(..))")
public Object doNothing(ProceedingJoinPoint pjp) {

// You can call the method or ignore the call and do your logic
return pjp.proceed();
}

}

http://www.hubberspot.com/2012/12/how-to-implement-around-advice-using_12.html是一个很好的例子,说明如何将 AspectJ 与 spring 一起使用。也许它可以帮助您作为起点。

用 CGlib 解释它要困难得多,所以我用 Java 动态代理来解释它。针对您的情况

 // I suppose Bean implements IBean interface
IBean beanMock = (IBean) Proxy.newProxyInstance (
IBean.getClass().getClassLoader(),
new Class[] { IBean.class },
new InvocationHandler() {
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
if(method.getName().equals("convert")) {
if(args[0].toString().equals("world")) {
return "WORLD"
}
} else {
// Implement default case
}
}
});

System.out.println(beanMock.convert("world"));

关于java - 编辑方法返回的内容 java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15511664/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com