如何使用JavaParser统计Java类中的标识符数量
How to Count Identifiers in a Java Class with JavaParser
Great question! Since JavaParser doesn’t provide a direct getIdentifiers() method, you’ll need to traverse the Abstract Syntax Tree (AST) using its Visitor pattern to collect and count all identifier nodes. Here’s a practical, step-by-step solution:
1. Understand What Counts as an Identifier
In JavaParser, an Identifier node represents user-defined names like:
- Class/interface names
- Method names
- Field names
- Local variable names
- Parameter names
- Enum constants, etc.
2. Create a Custom Visitor to Count Identifiers
JavaParser’s VoidVisitorAdapter lets you traverse the AST and react to specific node types. We’ll extend this to count every Identifier we encounter (with optional filtering for specific identifier types).
import com.github.javaparser.ast.Node; import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; import com.github.javaparser.ast.body.FieldDeclaration; import com.github.javaparser.ast.body.MethodDeclaration; import com.github.javaparser.ast.expr.Identifier; import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import com.github.javaparser.ast.body.VariableDeclarator; public class IdentifierCounterVisitor extends VoidVisitorAdapter<Void> { private int identifierCount = 0; @Override public void visit(Identifier identifier, Void arg) { // Optional: Add filters to count only specific types of identifiers Node parent = identifier.getParentNode().orElse(null); if (parent != null) { // Example: Count only class names, method names, fields, and variables if (parent instanceof ClassOrInterfaceDeclaration || parent instanceof MethodDeclaration || parent instanceof FieldDeclaration || parent instanceof VariableDeclarator) { identifierCount++; } } // Always call super.visit to continue traversing child nodes in the AST super.visit(identifier, arg); } public int getIdentifierCount() { return identifierCount; } }
3. Use the Visitor to Parse and Count
Once you have your visitor, use it to traverse the AST of your target Java class:
import com.github.javaparser.JavaParser; import com.github.javaparser.ParseResult; import com.github.javaparser.ast.CompilationUnit; import java.io.File; import java.io.IOException; public class IdentifierCounter { public static void main(String[] args) throws IOException { // Replace with your Java file path File targetFile = new File("src/main/java/YourTargetClass.java"); // Parse the file into a CompilationUnit (root node of the AST) ParseResult<CompilationUnit> parseResult = JavaParser.parse(targetFile); if (parseResult.isSuccessful()) { CompilationUnit compilationUnit = parseResult.getResult().get(); // Count identifiers across the entire file IdentifierCounterVisitor globalVisitor = new IdentifierCounterVisitor(); globalVisitor.visit(compilationUnit, null); System.out.println("Total identifiers in file: " + globalVisitor.getIdentifierCount()); // Optional: Count identifiers per individual class in the file for (ClassOrInterfaceDeclaration clazz : compilationUnit.findAll(ClassOrInterfaceDeclaration.class)) { IdentifierCounterVisitor classVisitor = new IdentifierCounterVisitor(); classVisitor.visit(clazz, null); System.out.println("Identifiers in class " + clazz.getName() + ": " + classVisitor.getIdentifierCount()); } } else { // Handle parsing errors parseResult.getProblems().forEach(problem -> System.err.println("Parsing error: " + problem.getMessage()) ); } } }
Key Notes
- Filtering Flexibility: Adjust the condition in the
visit(Identifier)method to narrow down which identifiers you count. Remove the filter entirely if you want to include every identifier (like loop variables or parameter names). - AST Traversal: Never skip
super.visit(identifier, arg)—it ensures the visitor continues traversing all child nodes in the tree, so you don’t miss any identifiers. - Version Compatibility: This example uses JavaParser v3.x/v4.x. If you’re on an older version, the parsing API may differ slightly (e.g.,
JavaParser.parse(File)directly returns aCompilationUnitinstead of aParseResult).
内容的提问来源于stack exchange,提问作者undisp
相关产品推荐
相关产品推荐

