java 将类对象转换为字节

flseospp  于 2023-02-20  发布在  Java
关注(0)|答案(5)|浏览(199)

如果我在运行时有一个Class示例,我可以得到它的byte[]表示吗?我感兴趣的字节应该在Class file format中,这样它们才是[ClassLoader.defineClass][3]的有效输入。
[3]:定义类(java语言字符串,字节[],整数,整数)
编辑:我已经接受了getResourceAsStream的答案,因为它非常简单并且在大多数情况下都能工作,ClassFileTransformer看起来是一个更健壮的解决方案,因为它不需要从.class文件中加载类;例如,它可以处理网络加载的类。使用这种方法需要跳过一些步骤,但我会记住的。谢谢大家!

dba5bblo

dba5bblo1#

您通常可以从Classloader中将类作为资源加载。

Class c = ...
String className = c.getName();
String classAsPath = className.replace('.', '/') + ".class";
InputStream stream = c.getClassLoader().getResourceAsStream(classAsPath);

我可能会推荐使用Apache commons-io中的一些东西来将InputStream读入byte[],但是IOUtils.toByteArray()应该可以做到这一点,编写这样的代码很容易出错和/或变慢。

myzjeezk

myzjeezk2#

一般来说,你不能像那样返回,然而,对于一些类加载器,你可以通过获取完全限定的类名,用/替换.,并附加.class(所以mypackage.MyClass变成mypackage/MyClass.class(记住,可能区分大小写))来获得资源文件。

ltskdhd1

ltskdhd13#

你可以试试java instrumentation!特别是ClassFileTransformer可能会让你感兴趣!!
你只需要重写transform方法(来自ClassFileTransformer),你的transform方法将在每个类被加载之前被调用,所以你可以做任何类字节。

9njqaruj

9njqaruj5#

我帮你个忙,
使用

final Class<T> clazz = ...
final byte[] buffer = clazz.getClassLoader().getResourceAsStream(clazz.getName().replace('.', '/').concat(".class"));

来获取类的编译字节码。
并使用

class SimpleClassLoader extends ClassLoader {

    public Clazz<?> loadFromBuffer(final byte[] buffer) {
        return defineClass(buffer, 0, buffer.length);
    }

    public Object newObjectFromBuffer(final byte[] buffer) {
        return loadFromBuffer(buffer).newInstance();
    }

}

以示例化Object或从缓冲器加载回Class

相关问题