繁体   English   中英

从类名获取Java源代码

[英]Obtaining Java source code from class name

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

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

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

假设前面提到的类有这个方法:

int method (User user) {...}

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

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

您可能需要几种可能的解决方案之一。 在不知道您真正想用这些信息做什么的情况下,我们的建议无法非常准确,但如果可能的话,我会首先引导您远离源代码。 JSE 源代码可在线获取,许多开源库也是如此,但情况并非总是如此。 此外,当您想找到它时,您需要将其全部组织起来,就像类路径一样,而 Class 对象更容易掌握和操作,而无需再次解析文本。

反射

如果您在运行时只需要有关类的信息,只需使用Java 反射 API 有了它,给定一个Class 对象,例如,您可以获取特定字段的类型、列出所有字段并对其进行迭代等...:

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

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

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

字节码操作

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

有了它,您不仅可以获取有关类的信息,还可以添加新字段、新方法、创建新类……如果您感到自虐,甚至可以加载类的多个变体。 可以在此处找到使用 ASM 的示例。

反编译

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

文件查找

如果您有源代码并且真的只想查找它,也许您只需要将 .java 文件放在一棵大树中的某个位置,然后根据需要根据包名进行检索。

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

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

您可以使用Class.forName("MyClass")按名称查找类(如果 .class 文件在您的类路径上Class.forName("MyClass")

您可以使用您选择JAVA 反编译器从类文件中获得源代码的近似值。 但是,如果您真的在寻找 java.io.File 的源代码,那么您可以下载该.

最好和最简单的赌注可以是javap

你好.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();
}

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

如果您在每次使用该类时都在使用 Eclipse,则可以右键单击 > 查看源代码(或只需单击该类 > F3),它将打开一个包含源代码的新选项卡。

因此,您要做的是在执行时获取 Java 类。 为此,您需要Java 反射

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

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

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

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

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

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

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

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

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

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

它将是一个 .class 文件、.jar、.zip 或其他文件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM