tags:

views:

127

answers:

8

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

import java.io.File;
.
.
.

I want the java.io.File source.

I'm working on a kind of parser and I need the source at execution. The problem is that I've to search recursively. For example:

int function (User user){...}

and User class is

public User{ private int var; . . . }

I want to obtain the variable type in execution

+1  A: 

Yes, if you download the source code. It's available for public download on the official download page.

If you're using Eclipse whenever you use the class you could right click > View Source (or simply click the class > F3) and it'll open a new tab with the source.

msakr
The source code is part of the JDK, look for src.zip located in your Java home directory (pointed to by JAVA_HOME).
Steve Kuo
and how I can get it in a program?
Federico
+2  A: 

You can get a good approximation of the source from a class file using the JAVA decompiler of your choice. However, if you're really after the source of java.io.File then you can download that.

JamesG
A: 

I'm working on a kind of parser and I need the source at execution. The problem is that I've to search recursively.

for example

int function (User user){...}

and User class is

public User{ private int var; . . . }

I want to obtain the variable type in execution

Federico
Welcome to Stack Overflow, **Federico**! Please **edit** your question and add these details.
ZoogieZork
And delete this un-answer
Stephen C
+1  A: 

The best and simplest bet can be javap

hello.java

public class hello
{
    public static void main(String[] args)
    {
    System.out.println("hello world!");
    world();
    }

    static public void world()
    {
    System.out.println("I am second method");
    }
}

do a javap hello and you will get this:

Compiled from "hello.java"
public class hello extends java.lang.Object{
    public hello();
    public static void main(java.lang.String[]);
    public static void world();
}
zengr
works with Javadocs too?
Federico
It just disassembles a class file. What do you mean by "it works with javadocs"?
zengr
I want to obtain the javadoc from the source
Federico
Just tried it out, I guess it does not.
zengr
A: 

So what you're trying to do is get the Java class at execution. For this, you need Java reflections.

msakr
A: 

If your goal is to get information about what's in a class, you may find the Java reflection API to be an easier approach. You can use reflection to look up the fields, methods, constructors, inheritance hierarchy, etc. of a class at runtime, without needing to have the source code for the class available.

Paul Kuliniewicz
+3  A: 

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").

Chadwick
Thanks man, I'm new here and the question was a little bit incomplete.I did the File Lookup way, because I need the javadoc and comments from the methods and fields, so the reflection is not the best alternative.
Federico
Welcome to SO, glad it helped. As you get used to things here, remember to upvote answers that are helpful (on answers for any question, not just yours), and click the accept checkbox on the best answer to your own questions.
Chadwick
A: 

Is there any way to obtain the java source from a class name?

The answer is complicated, not least because of the vagueness of your question. (Example notwithstanding).

  • In general it is not possible to get the real, actual Java source code for a class.

  • If you have (for example) a ZIP or JAR file containing the source code for the classes, then it is simple to extract the relevant source file based on the classes fully qualified name. But you have to have gotten those ZIP / JAR files from somewhere in the first place.

  • If you are only interested in method signatures, attribute names and types and so on, then much of this information is available at runtime using the Java reflection APIs. However, it depends on whether the classes were compiled with debug information (see the -g option to the javac compiler) how much will be available. And this is nowhere like the information that you can get from the real source code.

  • A decompiler may be able to generate compilable source code for a class from the bytecode files. But the decompiled code will look nothing like the original source code.

  • I guess, if you have a URL for a website populated with the javadocs for the classes, you could go from a class name, method name, or public attribute name to the corresponding javadoc URL at runtime. You could possibly even "screen scrape" the descriptions out of the javadocs. But once again, this is not the real source code.

Stephen C