A comprehensive Java parsing library providing complete support for parsing Java source code from Java 1.0 through Java 21 with advanced analysis functionalities.
—
JavaParser provides a comprehensive Abstract Syntax Tree (AST) model with over 100 node types representing all Java language constructs. The AST supports navigation, search, modification, and observation of changes.
All AST nodes extend the abstract Node class, providing common functionality for traversal, search, and manipulation.
/**
* Base class for all AST nodes
*/
public abstract class Node implements Cloneable, HasParentNode<Node>, Visitable, NodeWithRange<Node>, NodeWithTokenRange<Node> {
/**
* Accept a generic visitor that returns a value
* @param v The visitor to accept
* @param arg Argument passed to visitor methods
* @return Value returned by visitor
*/
public <R, A> R accept(GenericVisitor<R, A> v, A arg);
/**
* Accept a void visitor for side effects
* @param v The visitor to accept
* @param arg Argument passed to visitor methods
*/
public <A> void accept(VoidVisitor<A> v, A arg);
/**
* Find all descendant nodes of a specific type
* @param clazz Class of nodes to find
* @return List of nodes matching the type
*/
public <T extends Node> List<T> findAll(Class<T> clazz);
/**
* Find first descendant node of a specific type
* @param clazz Class of node to find
* @return Optional containing first match, empty if none found
*/
public <T extends Node> Optional<T> findFirst(Class<T> clazz);
/**
* Get parent node
* @return Optional containing parent, empty if this is root
*/
public Optional<Node> getParentNode();
/**
* Replace this node with another node
* @param node Replacement node
* @return true if replacement was successful
*/
public boolean replace(Node node);
/**
* Remove this node from its parent
* @return true if removal was successful
*/
public boolean remove();
/**
* Create deep copy of this node
* @return Cloned node
*/
public Node clone();
/**
* Get range of this node in source code
* @return Optional containing range, empty if not available
*/
public Optional<Range> getRange();
/**
* Set data associated with this node
* @param key Data key
* @param value Data value
*/
public <T> void setData(DataKey<T> key, T value);
/**
* Get data associated with this node
* @param key Data key
* @return Data value
* @throws IllegalStateException if key is not found
*/
public <T> T getData(DataKey<T> key);
/**
* Find data associated with this node
* @param key Data key
* @return Optional containing data value, empty if not found
*/
public <T> Optional<T> findData(DataKey<T> key);
/**
* Get token range of this node in source code
* @return Optional containing token range, empty if not available
*/
public Optional<TokenRange> getTokenRange();
/**
* Stream all descendant nodes
* @return Stream of all descendant nodes
*/
public Stream<Node> stream();
/**
* Stream descendant nodes with specific traversal strategy
* @param traversal Tree traversal strategy
* @return Stream of nodes using specified traversal
*/
public Stream<Node> stream(TreeTraversal traversal);
/**
* Walk the AST tree and apply consumer to each node
* @param consumer Function to apply to each node
*/
public void walk(Consumer<Node> consumer);
/**
* Walk the AST tree with specific traversal and apply consumer
* @param traversal Tree traversal strategy
* @param consumer Function to apply to each node
*/
public void walk(TreeTraversal traversal, Consumer<Node> consumer);
/**
* Find all descendant nodes matching predicate
* @param clazz Class of nodes to find
* @param predicate Condition to match
* @return List of matching nodes
*/
public <T extends Node> List<T> findAll(Class<T> clazz, Predicate<T> predicate);
/**
* Find first descendant node matching predicate
* @param clazz Class of node to find
* @param predicate Condition to match
* @return Optional containing first match, empty if none found
*/
public <T extends Node> Optional<T> findFirst(Class<T> clazz, Predicate<T> predicate);
/**
* Check if this node contains data for the given key
* @param key Data key to check
* @return true if data exists for key
*/
public boolean containsData(DataKey<?> key);
/**
* Remove data associated with key
* @param key Data key to remove
*/
public void removeData(DataKey<?> key);
/**
* Get all data keys associated with this node
* @return Set of data keys
*/
public Set<DataKey<?>> getDataKeys();
/**
* Find the root node of the AST
* @return Root node of the tree
*/
public Node findRootNode();
/**
* Find the CompilationUnit containing this node
* @return Optional containing CompilationUnit, empty if not found
*/
public Optional<CompilationUnit> findCompilationUnit();
}Usage Examples:
CompilationUnit cu = StaticJavaParser.parse(code);
// Find all method declarations
List<MethodDeclaration> methods = cu.findAll(MethodDeclaration.class);
// Find first class declaration
Optional<ClassOrInterfaceDeclaration> firstClass =
cu.findFirst(ClassOrInterfaceDeclaration.class);
// Navigate parent-child relationships
for (MethodDeclaration method : methods) {
Optional<Node> parent = method.getParentNode();
if (parent.isPresent() && parent.get() instanceof ClassOrInterfaceDeclaration) {
ClassOrInterfaceDeclaration owner = (ClassOrInterfaceDeclaration) parent.get();
System.out.println("Method " + method.getNameAsString() +
" belongs to class " + owner.getNameAsString());
}
}
// Clone nodes
MethodDeclaration originalMethod = methods.get(0);
MethodDeclaration clonedMethod = originalMethod.clone();The CompilationUnit represents a complete Java source file and serves as the root of the AST.
/**
* Root AST node representing a Java source file
*/
public class CompilationUnit extends Node {
/**
* Get all type declarations (classes, interfaces, enums, annotations)
* @return NodeList of type declarations
*/
public NodeList<TypeDeclaration<?>> getTypes();
/**
* Get all import declarations
* @return NodeList of import declarations
*/
public NodeList<ImportDeclaration> getImports();
/**
* Get package declaration
* @return Optional containing package declaration, empty if default package
*/
public Optional<PackageDeclaration> getPackageDeclaration();
/**
* Get primary type declaration (usually first public type)
* @return Optional containing primary type
*/
public Optional<TypeDeclaration<?>> getPrimaryType();
/**
* Get primary type name
* @return Optional containing primary type name
*/
public Optional<String> getPrimaryTypeName();
/**
* Get module declaration
* @return Optional containing module declaration, empty if not a module
*/
public Optional<ModuleDeclaration> getModule();
/**
* Set module declaration
* @param module Module declaration to set
* @return This CompilationUnit for chaining
*/
public CompilationUnit setModule(ModuleDeclaration module);
/**
* Set module by name
* @param name Module name
* @return This CompilationUnit for chaining
*/
public CompilationUnit setModule(String name);
/**
* Remove module declaration
* @return This CompilationUnit for chaining
*/
public CompilationUnit removeModule();
/**
* Get class declaration by name
* @param className Name of class to find
* @return Optional containing class declaration
*/
public Optional<ClassOrInterfaceDeclaration> getClassByName(String className);
/**
* Get interface declaration by name
* @param interfaceName Name of interface to find
* @return Optional containing interface declaration
*/
public Optional<ClassOrInterfaceDeclaration> getInterfaceByName(String interfaceName);
/**
* Get enum declaration by name
* @param enumName Name of enum to find
* @return Optional containing enum declaration
*/
public Optional<EnumDeclaration> getEnumByName(String enumName);
/**
* Get annotation declaration by name
* @param annotationName Name of annotation to find
* @return Optional containing annotation declaration
*/
public Optional<AnnotationDeclaration> getAnnotationDeclarationByName(String annotationName);
/**
* Get record declaration by name (Java 14+)
* @param recordName Name of record to find
* @return Optional containing record declaration
*/
public Optional<RecordDeclaration> getRecordByName(String recordName);
/**
* Add a new class to this compilation unit
* @param name Class name
* @return Created ClassOrInterfaceDeclaration
*/
public ClassOrInterfaceDeclaration addClass(String name);
/**
* Add a new interface to this compilation unit
* @param name Interface name
* @return Created ClassOrInterfaceDeclaration
*/
public ClassOrInterfaceDeclaration addInterface(String name);
/**
* Add a new enum to this compilation unit
* @param name Enum name
* @return Created EnumDeclaration
*/
public EnumDeclaration addEnum(String name);
/**
* Set package declaration
* @param packageDeclaration Package declaration to set
* @return This CompilationUnit for chaining
*/
public CompilationUnit setPackageDeclaration(PackageDeclaration packageDeclaration);
/**
* Set package name
* @param name Package name
* @return This CompilationUnit for chaining
*/
public CompilationUnit setPackageDeclaration(String name);
/**
* Add import declaration
* @param importDeclaration Import to add
* @return This CompilationUnit for chaining
*/
public CompilationUnit addImport(ImportDeclaration importDeclaration);
/**
* Add import by name
* @param name Import name (e.g., "java.util.List")
* @return This CompilationUnit for chaining
*/
public CompilationUnit addImport(String name);
/**
* Add static import
* @param name Static import name
* @return This CompilationUnit for chaining
*/
public CompilationUnit addStaticImport(String name);
}Usage Examples:
CompilationUnit cu = StaticJavaParser.parse(sourceCode);
// Access package and imports
Optional<PackageDeclaration> pkg = cu.getPackageDeclaration();
NodeList<ImportDeclaration> imports = cu.getImports();
// Get all types
NodeList<TypeDeclaration<?>> types = cu.getTypes();
for (TypeDeclaration<?> type : types) {
System.out.println("Found type: " + type.getNameAsString());
}
// Modify compilation unit
CompilationUnit newCu = new CompilationUnit();
newCu.setPackageDeclaration("com.example");
newCu.addImport("java.util.List");
newCu.addImport("java.util.ArrayList");
ClassOrInterfaceDeclaration newClass = newCu.addClass("MyClass");
newClass.addField("String", "name").setPrivate(true);JavaParser uses NodeList, an observable list implementation, for collections of AST nodes.
/**
* Observable list for AST nodes
*/
public class NodeList<T> extends ArrayList<T> implements Observable {
/**
* Create empty node list
*/
public NodeList();
/**
* Create node list from collection
* @param collection Initial elements
*/
public NodeList(Collection<? extends T> collection);
/**
* Register observer for changes
* @param observer Observer to register
*/
public void register(AstObserver observer);
/**
* Unregister observer
* @param observer Observer to unregister
*/
public void unregister(AstObserver observer);
// Standard List interface methods...
// All methods fire change notifications to observers
}Advanced search capabilities for finding specific nodes in the AST.
/**
* Find nodes matching a predicate
* @param predicate Condition to match
* @return List of matching nodes
*/
public <T> List<T> findAll(Class<T> clazz, Predicate<T> predicate);
/**
* Check if any descendant nodes match condition
* @param predicate Condition to check
* @return true if any nodes match
*/
public boolean containsData(Predicate<Node> predicate);
/**
* Walk the AST tree and collect results
* @param visitor Function to apply to each node
* @return Stream of results
*/
public <T> Stream<T> walk(Function<Node, Stream<T>> visitor);Usage Examples:
// Find all public methods
List<MethodDeclaration> publicMethods = cu.findAll(MethodDeclaration.class,
method -> method.isPublic());
// Find methods with specific name
List<MethodDeclaration> getMethods = cu.findAll(MethodDeclaration.class,
method -> method.getNameAsString().startsWith("get"));
// Find all string literals
List<StringLiteralExpr> strings = cu.findAll(StringLiteralExpr.class);
// Check for specific patterns
boolean hasMainMethod = cu.findAll(MethodDeclaration.class).stream()
.anyMatch(method -> method.getNameAsString().equals("main")
&& method.isStatic()
&& method.isPublic());Modify AST nodes by adding, removing, or replacing elements.
// Add new elements to classes
ClassOrInterfaceDeclaration clazz = cu.findFirst(ClassOrInterfaceDeclaration.class).get();
// Add field
FieldDeclaration field = clazz.addField(String.class, "newField");
field.setPrivate(true);
// Add method
MethodDeclaration method = clazz.addMethod("getValue", Modifier.Keyword.PUBLIC);
method.setType("String");
method.setBody(StaticJavaParser.parseBlock("{ return this.value; }"));
// Add constructor
ConstructorDeclaration constructor = clazz.addConstructor(Modifier.Keyword.PUBLIC);
constructor.addParameter("String", "value");
constructor.setBody(StaticJavaParser.parseBlock("{ this.value = value; }"));
// Remove elements
field.remove(); // Remove from parent
method.replace(newMethod); // Replace with new method// Type declarations
public class ClassOrInterfaceDeclaration extends TypeDeclaration<ClassOrInterfaceDeclaration> {
public boolean isInterface();
public NodeList<ClassOrInterfaceType> getExtendedTypes();
public NodeList<ClassOrInterfaceType> getImplementedTypes();
}
public class MethodDeclaration extends CallableDeclaration<MethodDeclaration> {
public Type getType();
public NodeList<Parameter> getParameters();
public Optional<BlockStmt> getBody();
}
public class FieldDeclaration extends BodyDeclaration<FieldDeclaration> {
public NodeList<VariableDeclarator> getVariables();
}
// Expressions
public abstract class Expression extends Node {
public boolean isAssignExpr();
public boolean isBinaryExpr();
public boolean isMethodCallExpr();
// ... type checking methods for all expression types
}
// Statements
public abstract class Statement extends Node {
public boolean isBlockStmt();
public boolean isIfStmt();
public boolean isForStmt();
// ... type checking methods for all statement types
}Install with Tessl CLI
npx tessl i tessl/maven-com-github-javaparser--javaparser-core