如何使用java assist替换fluent api中的精确方法调用?

如何使用java assist替换fluent api中的精确方法调用?,java,bytecode,instrumentation,javassist,Java,Bytecode,Instrumentation,Javassist,我需要替换java方法中的方法调用 考虑一个场景: public void enterCatle(){ if(PaltformRuntime.returnSuggestion()){ System.out.println("entered into the castle"); } } 我需要用其他方法调用替换returnSuggestion()。我可以通过覆盖 java assist的表达式编辑器 但有一种情况如下 public void enterCatl

我需要替换java方法中的方法调用

考虑一个场景:

public void enterCatle(){

    if(PaltformRuntime.returnSuggestion()){

        System.out.println("entered into the castle");
    }
}
我需要用其他方法调用替换
returnSuggestion()
。我可以通过覆盖 java assist的表达式编辑器

但有一种情况如下

public void enterCatle(){   
    if(PaltformRuntime.returnSuggestion() && ElementRegistry.returnSuggestion()){

        System.out.println("entered into the castle");
    }
}
在if语句的
entercatale()
中,有两个
returnSuggestion()
来自不同的类。我需要的是单独替换第一个
returnSuggestion()

我试图确定要替换的确切方法调用,例如
m.getLineNumber()
m.where().getName()
,通过这些东西,我可以缩小到特定的方法和确切的行号。现在的问题是,如果在同一行中使用相同的方法两次,两种方法都会被替换

如何确定要替换的确切方法?有没有办法获得方法调用的上下文,比如方法调用的位置,这样我就可以通过java assist进行映射。
或者对于这个场景还有其他方法吗?

您用标签标记了您的问题,因此您不应该处理作为源代码工件的表达式,更不用说行号了。除此之外,如果您认为一个方法调用是正确的,而另一个是错误的,那么您应该能够区分其中一个方法调用与另一个方法调用相比是正确的。如果您不能将其表示为一个明确的条件,那么任务描述本身就是有缺陷的,并且不能固定在代码大小上。因此这两种方法在接收方类型和返回类型上有所不同。在这种情况下,如果您使用处理字节码指令而不是源代码的API处理该类,则很容易区分这些方法,因为每个调用指令都与已解析的目标方法关联,并且这些方法被认为是完全不同的,正好有相同的名字。@Holger谢谢你的回复。我已经根据我需要的确切场景编辑了我的问题。这里,returnSuggestion()都返回布尔值。我需要替换对returnSuggestion()的唯一第一个调用。有什么办法可以实现吗?原则上,应该是可能的;如上所述,接收器类型是与调用指令相关联的信息的一部分。不幸的是,我没有使用Javassist,所以我不能详细介绍这个特定的库,但我认为,它接收旧方法作为
CtMethod
instance,它知道它的声明类,这可能是一种方法。你用标签标记了你的问题,因此你不应该处理源代码工件的表达式,更不用说行号了。除此之外,如果您认为一个方法调用是正确的,而另一个是错误的,那么您应该能够区分其中一个方法调用与另一个方法调用相比是正确的。如果您不能将其表示为一个明确的条件,那么任务描述本身就是有缺陷的,并且不能固定在代码大小上。因此这两种方法在接收方类型和返回类型上有所不同。在这种情况下,如果您使用处理字节码指令而不是源代码的API处理该类,则很容易区分这些方法,因为每个调用指令都与已解析的目标方法关联,并且这些方法被认为是完全不同的,正好有相同的名字。@Holger谢谢你的回复。我已经根据我需要的确切场景编辑了我的问题。这里,returnSuggestion()都返回布尔值。我需要替换对returnSuggestion()的唯一第一个调用。有什么办法可以实现吗?原则上,应该是可能的;如上所述,接收器类型是与调用指令相关联的信息的一部分。不幸的是,我没有使用Javassist,所以我无法详细介绍这个特定的库,但我认为,将旧方法作为
CtMethod
instance接收,它知道它的声明类,这可能是一种方法。