How to read java file structure using java?

I'm trying to read a java file and display the name of the package, class and method on the console. something like that:

File: Test.java

package tspec.test; public class Test { public void addTest () {} public void deleteTest () {} } 

Conclusion:

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

Thanks in advance:)

+4
source share
5 answers

This can be done using the Java Compiler API (introduced in Java 6). Unfortunately, this solution is limited to Sun JDK. Therefore, you will need to install this JDK, and you must include its tools.jar file in your class path.

 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); } 

When I pass this method a File , the contents of which is your sample, I get this output:

  class name: Test
 method name:
 addTest
 deleteTest

Unfortunately, I still do not understand where the package name is stored.

+6
source

The goal is to inherit Java code and report this to the content. With Reflection, you can do things like:

  Class.forName(className).getDeclaredMethods(); 
  • Java also has a Java Mirror API with similar functionality, but is not used as often.

Both of these solutions do not require third-party libraries or tools.

+3
source

The only tricky one is that java code cannot be well formatted. how a function declaration can be spread over several lines.

The ultimate solution is to create a machine for point-coding the source code, and then apply some compiler technique to capture what you want from the analyzed data.

0
source

We use the PMD Java code analyzer to solve a similar problem. This is useful.

http://pmd.sourceforge.net/

0
source

You do not have to do this by analyzing the Java file yourself! Java already contains a way to get information about its classes, methods, and packages: it is called reflection .

Take a look at the java.lang.Class class. Each instance of this class represents a specific Java class and contains methods for returning the name of the class, the package in which it lives, the methods that it contains, and additional information.

It is also worth looking at java.lang.reflect , as some of the Class methods return types from this package. The package contains classes for representing things such as methods, types, fields, etc.

To get the Class instance of your Test class, you can use the following code:

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

Returns a class of an unknown type, which means a question mark inside angle brackets if you are not familiar with generics. Why the type of the class instance is unknown because you specify the class name with a string that is parsed at runtime. At compile time, Java cannot be sure that the string passed to forName even represents a valid class in general.

However, testclass , as defined above, would be great for getting the class name, methods, and package containing.

0
source

Source: https://habr.com/ru/post/1306863/


All Articles