计算 Java 类校验和的最佳方法是什么?

use*_*892 4 java reflection checksum class

我有一个应用程序,我正在根据 Java“源”类生成“目标文件”。我想在源更改时重新生成目标。我决定最好的方法是获取类内容的字节[]并计算字节[]的校验和。

我正在寻找获取类的 byte[] 的最佳方法。该 byte[] 相当于编译后的 .class 文件的内容。使用 ObjectOutputStream不起作用。下面的代码生成一个比类文件的字节内容小得多的 byte[]。

// Incorrect function to calculate the byte[] contents of a Java class
public static final byte[] getClassContents(Class<?> myClass) throws IOException {
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    try( ObjectOutputStream stream = new ObjectOutputStream(buffer) ) {
        stream.writeObject(myClass);
    }
    // This byte array is much smaller than the contents of the *.class file!!!
    byte[] contents = buffer.toByteArray();
    return contents;
}
Run Code Online (Sandbox Code Playgroud)

有没有办法获取与 *.class 文件内容相同的 byte[] ?计算校验和是简单的部分,困难的部分是获取用于计算 MD5 或 CRC32 校验和的 byte[] 内容。

use*_*892 5

这是我最终使用的解决方案。我不知道这是否是最有效的实现,但以下代码使用类加载器来获取 *.class 文件的位置并读取其内容。为了简单起见,我跳过了读取的缓冲。

// Function to obtain the byte[] contents of a Java class
public static final byte[] getClassContents(Class<?> myClass) throws IOException {
    String path = myClass.getName().replace('.', '/');
    String fileName = new StringBuffer(path).append(".class").toString();
    URL url = myClass.getClassLoader().getResource(fileName);
    ByteArrayOutputStream buffer = new ByteArrayOutputStream();
    try (InputStream stream = url.openConnection().getInputStream()) {
        int datum = stream.read();
        while( datum != -1) {
            buffer.write(datum);
            datum = stream.read();
        }
    }   
    return buffer.toByteArray();
}
Run Code Online (Sandbox Code Playgroud)