Federico Federico - 10 days ago 5
Java Question

Obtaining Java source code from class name

Is there a way to obtain the Java source code from a class name?

For example, if I have access to the library with the class

java.io.File
, I want its source code.

I am working on a kind of parser and I need the source at execution time. I have also to search it recursively.

Say the aforementioned class has this method:

int method (User user) {...}


I would need to obtain
User
's source code, and so on and so forth with its inner classes.

Answer

Is there any way to obtain the java source from a class name? For example:...

You may want one of several possible solutions. Without knowing what you really want to do with the information, we can't be very precise with our recommendations, but I'd start by steering you away from source code if possible. JSE source code is available online, as are many open source libraries, but that may not always be the case. Additionally, you'll need to keep it all organized when you want to find it, much like a classpath, whereas the Class objects are much easier to get hold of, and manipulate, without having to parse text again.

Reflection

If you just need information about a class at runtime, just use the Java Reflection API. With it, given a Class object you can, for example, get the types of a specific field, list all fields and iterate over them, etc...:

Class clazz = User.class;
Field field = clazz.getDeclaredField("var");
System.out.println(field.getType().getName());

Reflection is useful for discovering information about the classes in the program, and of course you can walk the entire tree without having to find source code, or parse anything.

Remember you can lookup a class object (as long as it's on the classpath at runtime) with Class.forName("MyClass") and reflect on the resulting Class.

Bytecode Manipulation

If you need more than information, and actually want to manipulate the classes, you want bytecode manipulation. Some have tried to generate source code, compile to bytecode and load into their program, but trust me - using a solid bytecode manipulation API is far, far easier. I recommend ASM.

With it, you can not only get information about a class, but add new fields, new methods, create new classes... even load multiple variations of a class if you're feeling self-abusive. An example of using ASM can be found here.

Decompilation

If you really, really do need the source, and don't have it available, you can decompile it from a class object using one of the various decompilers out there. They use the same information and techniques as the above two, but go further and [attempt] to generate source code. Note that it doesn't always work. I recommend Jode, but a decent list, and comparison of others is available online.

File Lookup

If you have the source and really just want to look it up, maybe all you need is to put the .java files somewhere in a big tree, and retrieve based on package name as needed.

Class clazz = User.class;
String path = clazz.getPackage().getName().replaceAll("\\.","/");
File sourceFile = new File(path, clazz.getName() + ".java")

You want more logic there to check the class type, since obviously primatives don't have class definitions, and you want to handle array types differently.

You can lookup a class by name (if the .class files are on your classpath) with Class.forName("MyClass").

Comments