所以最近我一直在使用Javassist,但遇到了一个我找不到答案的问题。CtMethod的insertAt方法允许您在特定的行号处插入代码,但是它会覆盖该行还是保留该行,我该如何使其与默认行相反?我有一个应用程序,可以在运行时使用Javassist修改源,该源基于XML文件中的“挂钩”。我要使它可以覆盖一条线,或者可以将一条线放置在该线的上方而不是覆盖它。显然,有很多方法可以做到这一点,但是我宁愿使用一种正确的方法。
CtMethod对象中存在的方法insertAt(int lineNumber,String
src)
允许在给定行中的代码
之前* 注入以 src 编写的代码。 *
例如,使用以下(简单)示例程序:
public class TestSubject {
public static void main(String[] args) {
TestSubject testSubject = new TestSubject();
testSubject.print();
}
private void print() {
System.out.println("One"); // line 9
System.out.println("Two"); // line 10
System.out.println("Three"); // line 11
}
}
通过简单的编码(请记住,方法变量必须是 打印 方法的CtMethod表示形式):
// notice that I said line 10, which is where the sysout of "two" is
method.insertAt(10, true, "System.out.println(\"one and an half\");");
将在类中插入新的sysout指令。新类的输出将是:
one
one and an half
two
three
Javassist没有提供简单的方法来删除一行代码,因此,如果您真的想替换它,那么除了破解之外,别无选择。
怎么做?好吧,让我向您介绍您的新朋友(如果您还不知道)CodeAttribute对象。
CodeAttribute对象负责保存表示方法流的字节码,该代码属性还具有另一个名为LineNumberAttribute的属性,该属性可帮助您将行号映射到字节码数组中。因此,总结该对象即可满足您的所有需求!
以下示例中的想法非常简单。将字节码数组中的字节与应删除的行相关联,并用无操作码替换字节。
再一次,method是方法 print 的CtMethod表示形式 __
// let's erase the sysout "Two"
int lineNumberToReplace = 10;
// Access the code attribute
CodeAttribute codeAttribute = method.getMethodInfo().getCodeAttribute();
// Access the LineNumberAttribute
LineNumberAttribute lineNumberAttribute = (LineNumberAttribute) codeAttribute.getAttribute(LineNumberAttribute.tag);
// Index in bytecode array where the instruction starts
int startPc = lineNumberAttribute.toStartPc(lineNumberToReplace);
// Index in the bytecode array where the following instruction starts
int endPc = lineNumberAttribute.toStartPc(lineNumberToReplace+1);
System.out.println("Modifying from " + startPc + " to " + endPc);
// Let's now get the bytecode array
byte[] code = codeAttribute.getCode();
for (int i = startPc; i < endPc; i++) {
// change byte to a no operation code
code[i] = CodeAttribute.NOP;
}
在 原始 TestSubject类中运行此修改,将导致注入的类具有以下输出:
one
three
当你有需要添加一条线,仍保持现有的一个,你只需要使用给出的例子 比较容易的部分 ,如果你想更换线路,您必须先删除使用中给出的例子既有线 的硬部分
,然后使用第一个示例注入新行。
还请记住,在示例中,我假设您已经对javassist的基础知识感到满意,只显示了多汁的部分,而不是全部内容。这就是为什么,例如,在示例中没有ctClass.writeFile
…您仍然需要这样做,我只是省略了它,因为我希望您应该知道您必须这样做。
如果您在代码示例中需要任何其他帮助,请询问。我很乐意提供帮助。
问题内容: 我有一些人已经解决过的问题,但问题是我不了解我的实现中缺少什么。 我的hibernate代码的一部分如下: 问题是我想通过更改hibernate.connection.url属性中的“数据库”一词来选择要在运行时中使用的数据库。 在javaswing中,我正在实现此功能: } 然后,我用按钮检查所做的更改,从组合框中选择所需的数据库: 现在,debug1的输出正在更改,因此我在此打印中
Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京技术学院的数学和计算机科学系的 Shigeru Chiba 所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使用Javassist对字节码操作为JBoss实现动态AOP框架。 Javassist(JAVA 编程ASSISTant)使Java字节码操作变得简单。 它是一个用Java编辑字节码的类库; 它使Jav
我在Spring框架中使用ehcache。我正在使用ehcache.xml初始化ehcache。然而,我想在运行时添加某些属性,如terracottaconfig。为此,我覆盖了类EhCacheManagerFactoryBean。目前,我正在覆盖这个类的方法getObject()(我不知道这是否是一个正确的覆盖,因为在使用ehcache.xml文件初始化类之前,调用了其他方法setResourc
修改矩形和圆角矩形 您可以调整矩形的大小和位置。在 Photoshop 中,您也可以在绘制圆角矩形形状后,对这些形状的角半径进行修改。可单独调整每个圆角,并可以同时对多个图层上的矩形进行调整。 注意:如果您选择多个矩形,则最上面矩形的值将显示在“属性”面板中。您键入的值将应用于所有选择的矩形。 使用“路径选择工具”可选择一个或多个矩形或圆角矩形。 要更改矩形的尺寸,请在“属性”面板或选项栏中的 W
接口说明 如果已创建了飞行路径,而想修改飞行路径的相关信息,Wish3DEarth团队新增了修改飞行路线的接口,开发者可以通过该接口,来修改飞行路径的相关信息(名称、视点等)。 注意:vpIds如果不传,默认会将原有的视点置空 如需调用,请访问 开发者文档 来查看详细的接口使用说明 该接口仅开放给已获取SDK的开发者 API地址 POST /api/flyline/1.0.0/update 是否需
问题内容: 我正在尝试制作一个包含名称的列表。该列表应该是可修改的(添加,删除,排序等)。但是,每当我尝试更改ArrayAdapter中的项目时,程序都会崩溃,并显示错误。这是我的代码: 我尝试插入,删除和清除方法,但没有一个起作用。有人可以告诉我我做错了什么吗? 问题答案: 我自己尝试了一下…发现它没有用。所以我检查了ArrayAdapter的源代码并发现了问题。由数组初始化后,将其转换为不能修