Eclipse JDT (Java Development Tools) 提供了強大的 AST (Abstract Syntax Tree) API,是構建 Java 代碼分析、重構、生成工具的核心基礎。本文梳理 org.eclipse.jdt.core.dom 包中 AST 節點的繼承體系、Expression 關鍵分支的完整子類列表,並提供一段可運行的代碼實現「掃描 JAR 獲取指定父類的所有子類」。
ASTNode (根節點)
├─ Expression (表達式節點)
│ ├─ MethodInvocation (方法調用)
│ ├─ ClassInstanceCreation (new 表達式)
│ ├─ Assignment (賦值)
│ ├─ InfixExpression (中綴表達式 a+b)
│ ├─ ... (詳見下文完整列表)
├─ Statement (語句節點)
│ ├─ Block (塊語句 {})
│ ├─ IfStatement, ForStatement, WhileStatement...
├─ Declaration (聲明節點)
│ ├─ TypeDeclaration (類/接口聲明)
│ ├─ MethodDeclaration (方法聲明)
│ ├─ FieldDeclaration (字段聲明)
├─ Type (類型節點)
│ ├─ SimpleType, ParameterizedType, ArrayType...
└─ ... (Name, Modifier, Annotation 等)
以下類均直接或間接繼承 Expression,涵蓋 Java 所有表達式形態:
TypeLiteral、MarkerAnnotation、BooleanLiteral、ConditionalExpression (三元運算)StringLiteral、VariableDeclarationExpression、InfixExpressionSuperFieldAccess、NullLiteral、AssignmentSingleMemberAnnotation、ArrayInitializer、ArrayAccessName (通用名稱)、SuperMethodInvocation、Expression (抽象基類)CharacterLiteral、ThisExpression、ClassInstanceCreationPrefixExpression (前綴 ++i)、NormalAnnotationCreationReference (構造方法引用 ::new)、TypeMethodReferenceSimpleName (簡單標識符)、ArrayCreationParenthesizedExpression (括號表達式)、Annotation (註解基類)MethodReference (方法引用 ::)、FieldAccess (字段訪問)QualifiedName (限定名 a.b)、SuperMethodReferenceInstanceofExpression、CastExpression (強轉)ExpressionMethodReference、PostfixExpression (後綴 i++)NumberLiteral、MethodInvocation (方法調用)、LambdaExpression (Lambda)註:具體層級關係請參考 JDT 文檔或 IDE 中的類圖,以上為扁平化列表。
ClassLoader 加載目標 JAR (org.eclipse.jdt.core_x.x.x.jar).class 文件targetClass.isAssignableFrom(clazz) 且 clazz != targetClassimport org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.Expression;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
public class JdtSubClassScanner {
public static void main(String[] args) throws Exception {
// 1. 定位 JDT JAR (請根據實際環境修改路徑)
String jarPath = "C:\\0workspace\\AtiPlatf_cms\\libx\\org.eclipse.jdt.core_3.10.0.v20140902-0626.jar";
// 2. 目標父類
Class<?> parentClass = Expression.class; // 可換為 ASTNode.class 等
// 3. 掃描並輸出
List<Class<?>> subClasses = getSubClassesFromJar(jarPath, parentClass);
System.out.println("共發現 " + subClasses.size() + " 個 " + parentClass.getSimpleName() + " 子類:");
subClasses.forEach(c -> System.out.println(" " + c.getName()));
}
/**
* 從 JAR 文件中掃描指定父類的所有非抽象子類
*/
public static List<Class<?>> getSubClassesFromJar(String jarPath, Class<?> parentClass)
throws IOException, ClassNotFoundException {
List<Class<?>> result = new ArrayList<>();
// 建立只加載該 JAR 的隔離 ClassLoader,避免污染主 ClassLoader
URL jarUrl = new URL("file:" + jarPath);
try (URLClassLoader jarLoader = new URLClassLoader(new URL[]{jarUrl}, null)) {
try (JarFile jarFile = new JarFile(jarPath)) {
Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String name = entry.getName();
// 只處理 .class 文件,且在 org.eclipse.jdt.core.dom 包下
if (name.endsWith(".class") && name.startsWith("org/eclipse/jdt/core/dom/")) {
String className = name.substring(0, name.length() - 6).replace('/', '.');
try {
Class<?> clazz = jarLoader.loadClass(className);
// 過濾:是父類的子類、非父類本身、非接口、非抽象類(可選)
if (parentClass.isAssignableFrom(clazz)
&& clazz != parentClass
&& !clazz.isInterface()
&& (clazz.getModifiers() & Modifier.ABSTRACT) == 0) {
result.add(clazz);
}
} catch (ClassNotFoundException | NoClassDefFoundError e) {
// 忽略依賴缺失的類
}
}
}
}
}
return result;
}
}
URLClassLoader(parent=null) 僅加載目標 JAR,避免版本衝突污染應用主 ClassLoader。org/eclipse/jdt/core/dom/,大幅提升速度並減少雜訊。NoClassDefFoundError 通常因依賴類不在該 JAR 中,直接忽略。MethodInvocation 批量重命名/遷移 API。TypeDeclaration 生成 Builder/DTO/Mapper 代碼。ImportDeclaration 繪製模塊依賴圖。掌握 JDT AST 節點體系是進行 Java 靜態分析的入場磚。本文提供的繼承樹全景、Expression 子類清單與掃描工具代碼,可直接用於工具開發或作為查閱手冊。下一步建議深入學習 ASTVisitor 訪問者模式進行樹遍歷,以及 ASTRewrite 進行代碼修改重寫。