从类名获取Java源代码

时间:2010-07-06 21:17:08

标签: java class reflection reverse-engineering

有没有办法从类名中获取Java源代码?

例如,如果我可以访问具有类java.io.File的库,我想要它的源代码。

我正在研究一种解析器,我需要在执行时使用源代码。我还要递归搜索它。

说上面提到的类有这个方法:

int method (User user) {...}

我需要获取User的源代码,依此类推及其内部类。

8 个答案:

答案 0 :(得分:7)

有没有办法从类名中获取java源代码?例如:...

您可能想要几种可能的解决方案之一。如果不知道你真正想要对这些信息做些什么,我们就不能非常精确地推荐我们的建议,但是如果可能的话,我首先会引导你远离源代码。 JSE source code可以在线获得,许多开源库也可以在线获得,但情况可能并非总是如此。另外,当你想要找到它时,你需要保持整齐有序,就像类路径一样,而Class对象更容易掌握和操作,而不必再次解析文本。

反射

如果您只需要在运行时获取有关类的信息,请使用the Java Reflection API。有了它,给定Class object,你可以获得特定字段的类型,列出所有字段并迭代它们等等......:

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

反射对于发现有关程序中的类的信息非常有用,当然,您可以遍历整个树而无需查找源代码或解析任何内容。

请记住,您可以使用Class.forName("MyClass")查找类对象(只要它在运行时的类路径上)并反映生成的类。

字节码操作

如果您需要的不仅仅是信息,而且实际上想要操作类,那么您需要字节码操作。有些人试图生成源代码,编译成字节码并加载到他们的程序中,但相信我 - 使用可靠的字节码操作API要容易得多。我推荐ASM

有了它,您不仅可以获取有关类的信息,还可以添加新字段,新方法,创建新类...如果您感觉自我侮辱,甚至可以加载类的多个变体。使用ASM的示例可以是found here

反编译

如果你确实需要源代码,并且没有它可用,你可以使用各种反编译器之一从类对象反编译它。他们使用与上述两者相同的信息和技术,但进一步[尝试]生成源代码。请注意,它并不总是有效。我推荐Jode,但是一个不错的列表,其他人的比较是available online

文件查找

如果您有源代码并且真的只想查找它,可能只需要将.java文件放在一个大树中,并根据需要检索包名称。

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

您需要更多逻辑来检查类类型,因为显然primatives没有类定义,并且您希望以不同方式处理数组类型。

您可以使用Class.forName("MyClass")按名称查找类(如果.class文件位于类路径中)。

答案 1 :(得分:3)

您可以使用JAVA decompiler of your choice从类文件中获得良好的近似值。但是,如果你真的在追踪java.io.File的源代码,那么你可以download that

答案 2 :(得分:3)

最好也是最简单的赌注可以是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");
    }
}

做一个javap hello,你会得到这个:

Compiled from "hello.java"
public class hello extends java.lang.Object{
    public hello();
    public static void main(java.lang.String[]);
    public static void world();
}

答案 3 :(得分:2)

是的,如果您下载源代码。它可以在官方下载页面上公开下载。

如果您在使用该课程时使用Eclipse,则可以右键单击>查看来源(或只是点击类> F3),它会打开一个包含来源的新标签页。

答案 4 :(得分:0)

所以你要做的就是在执行时获取Java类 。为此,您需要Java reflections

答案 5 :(得分:0)

如果您的目标是获取有关课程内容的信息,您可能会发现Java reflection API更容易。您可以使用反射在运行时查找类的字段,方法,构造函数,继承层次结构等,而无需使用该类的源代码。

答案 6 :(得分:0)

  

有没有办法从类名中获取java源代码?

答案很复杂,尤其是因为你的问题模糊不清。 (尽管有例子)。

  • 通常,不可能获得类的真实,实际的Java源代码。

  • 如果您(例如)包含类的源代码的ZIP或JAR文件,则可以根据类完全限定名称提取相关源文件。但是你必须首先从某个地方获得这些ZIP / JAR文件。

  • 如果您只对方法签名,属性名称和类型等感兴趣,那么在运行时使用Java反射API可以获得大部分此类信息。但是,它取决于是否使用调试信息编译类(请参阅-g编译器的javac选项)将有多少可用。这与您从真实源代码中获得的信息无关。

  • 反编译器可能能够从字节码文件生成类的可编译源代码。但反编译代码看起来与原始源代码完全不同。

  • 我想,如果你有一个填充了类的javadocs的网站的URL,你可以在运行时从类名,方法名或公共属性名转到相应的javadoc URL。你甚至可以从javadocs中“屏蔽”描述。但再一次,这不是真正的源代码。

答案 7 :(得分:0)

您可以从加载类的位置打印资源路径

URL sourceURL=obj.getClass().getProtectionDomain().getCodeSource().getLocation();

它将是.class文件,.jar,.zip或其他内容。