JDK Parser에서 Java 소스 코드 상세 정보 확인
5231 단어 JDKParser 해석Java 소스 코드
이 API는 현재 관련 문서가 부족하기 때문에 사용하기가 비교적 어렵다. 예를 들어 소스 코드의 모든 변수를 분석하고 인쇄하는 것이다.
public class JavaParser {
private static final String path = "User.java";
private JavacFileManager fileManager;
private JavacTool javacTool;
public JavaParser() {
Context context = new Context();
fileManager = new JavacFileManager(context, true, Charset.defaultCharset());
javacTool = new JavacTool();
}
public void parseJavaFiles() {
Iterable<!--? extends JavaFileObject--> files = fileManager.getJavaFileObjects(path);
JavaCompiler.CompilationTask compilationTask = javacTool.getTask(null, fileManager, null, null, null, files);
JavacTask javacTask = (JavacTask) compilationTask;
try {
Iterable<!--? extends CompilationUnitTree--> result = javacTask.parse();
for (CompilationUnitTree tree : result) {
tree.accept(new SourceVisitor(), null);
}
} catch (IOException e) {
e.printStackTrace();
}
}
static class SourceVisitor extends TreeScanner<void, void=""> {
private String currentPackageName = null;
@Override
public Void visitCompilationUnit(CompilationUnitTree node, Void aVoid) {
return super.visitCompilationUnit(node, aVoid);
}
@Override
public Void visitVariable(VariableTree node, Void aVoid) {
formatPtrln("variable name: %s, type: %s, kind: %s, package: %s",
node.getName(), node.getType(), node.getKind(), currentPackageName);
return null;
}
}
public static void formatPtrln(String format, Object... args) {
System.out.println(String.format(format, args));
}
public static void main(String[] args) {
new JavaParser().parseJavaFiles();
}
}</void,>
여기서 사용자.java 코드는 다음과 같습니다.
package com.ragnarok.javaparser;
import com.sun.istack.internal.Nullable;
import java.lang.Override;
public class User {
@Nullable
private String foo = "123123";
private Foo a;
public void UserMethod() {}
static class Foo {
private String fooString = "123123";
public void FooMethod() {}
}
}
위의 JavaParser 결과는 다음과 같습니다.
variable: foo, annotaion: Nullable
variable name: foo, type: String, kind: VARIABLE, package: com.ragnarok.javaparser
variable name: a, type: Foo, kind: VARIABLE, package: com.ragnarok.javaparser
여기서 우리는 먼저 JavaCompiler를 통해CompilationTask는 원본 파일을 해석한 후에 사용자 정의 SourceVisitor(TreeScanner로부터 계승)를 사용하여 원본 코드의 구조에 접근합니다. SourceVisitor 클래스에서visitVariable을 다시 불러와서 컴파일된 단원(단일 원본 코드 파일)을 해석하고 그 중의 모든 변수에 접근합니다. 여기서 알 수 있듯이 우리는 이 변수 유형의 전체 한정된 이름(패키지 이름 포함)을 얻을 수 없습니다.대응하는 간단한 이름만 얻을 수 있기 때문에 유형의 확정은 외부에서 자체적으로 확정해야 한다. 예를 들어 클래스가 있는 패키지 이름을 기록하고 전체 원본 코드 디렉터리를 검색하여 모든 클래스의 전체 한정된 이름을 추적하고import에 대응하는 유형이 포함되어 있는지 찾아낼 수 있다.TreeScanner에는 visitVariable 방법 외에 대량의 다른visitXYZ 방법이 포함되어 있다. 예를 들어 모든 import, 방법 정의, Annotation 등을 두루 훑어볼 수 있고 OpenJDK에서 이것에 관한 원본 코드를 구체적으로 볼 수 있다.
여기서 다음 또 다른 예를 살펴보면visitClass 방법을 다시 불러와 모든 내부 클래스와 클래스 자체를 방문한다.
@Override
public Void visitClass(ClassTree node, Void aVoid) {
formatPtrln("class name: %s", node.getSimpleName());
for (Tree member : node.getMembers()) {
if (member instanceof VariableTree) {
VariableTree variable = (VariableTree) member;
List<!--? extends AnnotationTree--> annotations = variable.getModifiers().getAnnotations();
if (annotations.size() > 0) {
formatPtrln("variable: %s, annotaion: %s", variable.getName(), annotations.get(0).getAnnotationType());
} else {
formatPtrln("variable: %s", variable.getName());
}
}
}
return super.visitClass(node, aVoid);
}
클래스 이름과 변수의 이름, 형식, annotation 형식을 간단하게 인쇄하고 위의 코드를 실행합니다. 결과는 다음과 같습니다.
class name: User
variable: foo, annotaion: Nullable
variable: a
class name: Foo
variable: fooString
우리가 클래스 이름과 클래스 중의 변수를 모두 인쇄한 것을 알 수 있다.한편visitClass 방법에서 우리는 getMembers 방법을 통해 클래스의 모든 구성원을 얻을 수 있다. 변수, 방법, annotation 등을 포함하여 각각 다른 유형에 대응한다. 예를 들어 변수는 VariableTree 유형에 대응하고 방법은 대응하는 MethodTree 유형에 대응한다.어쨌든 실제 사용은 특별히 복잡하지 않지만 문서가 부족하기 때문에 사용에 큰 장애를 초래했다. 그리고 현재 소개한 것은 이 API의 일부분일 뿐이다. 이후에 나는 이 API와 관련된 함수를 계속 연구할 것이다.
이상은 JDK의 Parser가 자바 원본 코드를 해석하는 자료 정리입니다. 후속으로 관련 자료를 계속 보충합니다. 본 사이트에 대한 지지에 감사드립니다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
【Java】 STS (Eclipse)에 AdoptOpen JDK 설정· Eclipse를 2020-09로 업데이트하면 jre로 Eclipse를 움직이고 있습니다! 라는 메시지가 나온다. ・메모리 상태의 파악을 위해 MissionControl 넣으려고 하면 JDK로 움직이지 않으면 안 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.