You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用LexicalPreservingPrinter时新方法体丢失,代码是否存在问题?

JavaParser LexicalPreservingPrinter添加方法丢失方法体问题

问题描述

我希望向现有类中添加新方法,同时保留原有代码的格式。使用com.github.javaparser:javaparser-core:3.25.5版本,但在使用LexicalPreservingPrinter时,新添加的方法没有方法体。参考代码如下:

final CompilationUnit cu = StaticJavaParser.parse(Paths.get("path-of-an-existing-class.java"));

LexicalPreservingPrinter.setup(cu);

final ClassOrInterfaceDeclaration type = cu.addClass("GeneratedClass");
final MethodDeclaration method = type.addMethod("main", Keyword.PUBLIC, Keyword.STATIC);
final BlockStmt block = new BlockStmt();
method.setBody(block);
final NameExpr clazz = new NameExpr("System");
final FieldAccessExpr field = new FieldAccessExpr(clazz, "out");
final MethodCallExpr call = new MethodCallExpr(field, "println");
call.addArgument(new StringLiteralExpr("Hello World!"));
block.addStatement(call);

// 注释掉LexicalPreservingPrinter.setup(...)时,两次打印的"Hello"数量相等
// 启用该代码时,数量不同
System.out.println(StringUtils.countMatches(new DefaultPrettyPrinter().print(cu), "Hello"));
System.out.println(StringUtils.countMatches(LexicalPreservingPrinter.print(cu), "Hello"));

问题原因

你的代码存在关键疏漏:LexicalPreservingPrinter.setup(cu)只会初始化解析阶段生成的原有AST节点的词法保留信息,而你手动创建的新节点(比如GeneratedClass类、main方法、方法体等)并没有被纳入词法保留的处理范围。当LexicalPreservingPrinter打印时,无法识别这些新节点的内容,导致新方法的方法体被忽略,两次打印的"Hello"数量出现差异。

解决方法

为每个手动创建的新节点单独调用LexicalPreservingPrinter.setup(),让它们被纳入词法保留机制的处理。修改后的代码如下:

final CompilationUnit cu = StaticJavaParser.parse(Paths.get("path-of-an-existing-class.java"));

LexicalPreservingPrinter.setup(cu);

final ClassOrInterfaceDeclaration type = cu.addClass("GeneratedClass");
// 为新创建的类启用词法保留
LexicalPreservingPrinter.setup(type);

final MethodDeclaration method = type.addMethod("main", Keyword.PUBLIC, Keyword.STATIC);
// 为新创建的方法启用词法保留
LexicalPreservingPrinter.setup(method);

final BlockStmt block = new BlockStmt();
method.setBody(block);
// 为方法体启用词法保留
LexicalPreservingPrinter.setup(block);

final NameExpr clazz = new NameExpr("System");
final FieldAccessExpr field = new FieldAccessExpr(clazz, "out");
final MethodCallExpr call = new MethodCallExpr(field, "println");
call.addArgument(new StringLiteralExpr("Hello World!"));
block.addStatement(call);

System.out.println(StringUtils.countMatches(new DefaultPrettyPrinter().print(cu), "Hello"));
System.out.println(StringUtils.countMatches(LexicalPreservingPrinter.print(cu), "Hello"));

这样修改后,LexicalPreservingPrinter就能正确识别并打印新添加的方法体内容,两次输出的"Hello"数量会保持一致。

内容的提问来源于stack exchange,提问作者Shear Plane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 05:05:26