2010-04-13 2 views
4

자바 파일을 읽고 패키지, 클래스 및 메서드 이름을 콘솔에 표시하려고합니다. 이 같은 :Java를 사용하여 Java 파일 구조를 읽는 방법은 무엇입니까?

파일 : Test.java

package tspec.test; 

public class Test { 
    public void addTest() {} 
    public void deleteTest() {} 
} 

출력 : 사전에

package name: tspec.test 
class name: Test 
method name: 
addTest 
deleteTest 

감사합니다 :)

+0

"Java 파일 읽기"는 Java 소스 코드 파일 (.java) 또는 Java 바이트 코드 파일 (.class)을 의미합니까? –

+0

.java 파일을 의미합니다. – Iso

+0

'javac '소스를 살펴보고'.java' 파일을 파싱하는 방법을 볼 수 있습니다. 이 작업을 간단하게 수행하고 있습니까? 아니면 더 큰 프로젝트의 일부입니까? –

답변

0

유일한 어려움은 자바 코드가 잘 서식하지 않을 수있다 . 함수 선언과 같이 여러 줄로 확산 될 수 있습니다.

궁극적 인 해결책은 소스 코드를 토큰 화하기위한 오토마타를 생성 한 다음 구문 분석기를 사용하여 파싱 된 데이터에서 원하는 것을 가져 오는 것입니다.

+0

정규식은 여러 줄을 처리 할 수 ​​있지만 궁극적 인 해결 방법은 파서입니다. –

3

Java 코드를 내부 검사하고 그 내용을보고하는 것이 목적입니다.

Class.forName(className).getDeclaredMethods(); 
  • 자바도 비슷한 기능을 가진 Java Mirror API이 있지만, 같은 일반적으로 사용되지 않습니다 반사하면 같은 일을 할 수 있습니다.

두 가지 솔루션 모두 타사 라이브러리 또는 도구가 필요하지 않습니다.

0

우리는 비슷한 문제를 해결하기 위해 PMD Java 코드 분석기를 사용합니다. 유용합니다.

http://pmd.sourceforge.net/

0

당신은 자바 파일을 직접 분석하여이 작업을 수행 할 필요가 없습니다! Java에는 이미 자체 클래스, 메소드 및 패키지에 대한 정보를 가져 오는 방법이 포함되어 있습니다. reflection이라고합니다.

java.lang.Class 클래스를 살펴보십시오. 이 클래스의 각 인스턴스는 특정 Java 클래스를 나타내며 클래스 이름, 패키지가있는 패키지, 포함 된 메서드 및 많은 추가 정보를 반환하는 메서드를 포함합니다.

또한 java.lang.reflect 패키지를 살펴볼 가치가 있습니다. 일부 패키지는 Class의 리턴 유형입니다. 패키지에는 메서드, 유형, 필드 등과 같은 것을 나타내는 클래스가 포함되어 있습니다. 이 꺾쇠 괄호 안에 물음표는 경우의 의미입니다 알 수없는 유형의 클래스를 반환

Class<?> testclass = Class.forName("tspec.test.Test"); 

:

Test 클래스의 Class 인스턴스를 얻으려면 다음과 같은 코드를 사용할 수 있습니다 제네릭에 익숙하지 않습니다. 클래스 인스턴스의 유형을 알 수없는 이유는 런타임에 파싱되는 문자열로 클래스 이름을 지정하기 때문입니다. 컴파일시에 자바는 forName에 전달 된 문자열이 유효한 클래스를 나타낼 지조차 확신 할 수 없습니다.

그러나 위에 정의 된대로 testclass은 클래스 이름, 메소드 및 패키지를 가져 오는 데 적합합니다.

+4

포스터에는 .class 파일이 아니라 .java 파일에 대한 액세스 권한이 있다고 생각합니다. –

6

Java Compiler API (Java 6에서 소개 됨)을 사용하여 수행 할 수 있습니다. 불행하게도이 솔루션은 Sun의 JDK로 제한됩니다. 따라서 해당 JDK가 으로 설치되어 있어야하며 클래스 경로에 tools.jar 파일을 포함시켜야합니다. 패키지 이름이 저장되는 위치

 
class name: Test 
method name: 
addTest 
deleteTest 

은 불행히도, 난 아직 파악되지 않은 : 나는 File 내용이 샘플이 방법을 전달하는 경우

public void displayInformation(File javaSourceFile) throws Exception { 
    JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); 

    // The file manager locates your Java source file for the compiler. Null arguments indicate I am comfortable with its default behavior. 
    StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null); 

    // These will be parsed by the compiler 
    Iterable<? extends JavaFileObject> fileObjects = fileManager.getJavaFileObjects(javaSourceFile); 

    // Creates a new compilation task. This doesn't actually start the compilation process. 
    // Null arguments indicate I am comfortable with its default behavior. 
    CompilationTask task = compiler.getTask(null, null, null, null, null, fileObjects); 

    // Cast to the Sun-specific CompilationTask. 
    com.sun.tools.javac.api.JavacTaskImpl javacTask = (com.sun.tools.javac.api.JavacTaskImpl) task; 

    // The Sun-specific JavacTaskImpl can parse the source file without compiling it, returning 
    // one CompilationUnitTree for each JavaFileObject given to the compiler.getTask call (only one in our case). 
    Iterable<? extends CompilationUnitTree> trees = javacTask.parse(); 
    CompilationUnitTree tree = trees.iterator().next(); 

    // Create a class that implements the com.sun.source.tree.TreeVisitor interface. 
    // The com.sun.source.util.TreeScanner is a good choice because it already implements most of the logic. 
    // We just override the methods we're interested in. 
    class MyTreeVisitor extends TreeScanner<Void, Void> { 

     @Override 
     public Void visitClass(ClassTree classTree, Void p) { 
      System.out.println("class name: " + classTree.getSimpleName()); 
      System.out.println("method name:"); 
      return super.visitClass(classTree, p); 
     } 

     @Override 
     public Void visitMethod(MethodTree methodTree, Void p) { 
      System.out.println(methodTree.getName()); 
      return super.visitMethod(methodTree, p); 
     } 

    } 

    tree.accept(new MyTreeVisitor(), null); 
} 

는,이 출력이 나타납니다.

+0

"@Override public void Void visitCompilationUnit (CompilationUnitTree unit, Void arg)을 사용하십시오. return super.visitCompilationUnit (단위 : arg); } 패키지를 얻으려면. –

관련 문제