Convertir una clase dada (digamos, java.lang.Object) en una matriz de bytes. ¿Es posible?

Dado que los cargadores de clases aceptan tomar como entrada una matriz de bytes de una clase dada, devolviendo una Class , Me pregunto si es posible hacer lo contrario, es decir, pasar una Class Y obtener su matriz de bytes ?

¡Tenga en cuenta que no estoy hablando de serialización!

Puede usar ClassLoader.getResourceAsInputStream () sin embargo, no está garantizado que serán los mismos bytes que se cargó. No creo que los bytes reales cargados se almacenen en cualquier lugar.

No hay forma estándar que yo sepa. Pero puede implementar su propio cargador de clases de delegación, manteniendo un registro de las clases cargadas en términos de nombre y código de bytes.

¿Cuál sería tu caso de uso? – ¿Transfiriendo código a una aplicación remota?

Una implementación de ClassLoader debe desarrollar la representación de una clase para la versión de la especificación del lenguaje Java que admite. Por lo tanto, debe contener la lógica para tomar una matriz de bytes y convertir esto en un objeto de Class , o extender algo de ClassLoader que lo haga. Sin embargo, la clase abstracta ClassLoader que Java define no tiene ningún método que pueda devolver un byte [] desde una clase. Es posible que algunas implementaciones tengan esto (tal vez el bootstrap, el sistema u otro cargador de clases), pero eso sería, en el mejor de los casos, específico de la implementación y no algo en lo que confiar.

Si necesita este tipo de funcionalidad, una forma de hacerlo sería crear su propia implementación de ClassLoader y anular los métodos defineClass de tal manera que las matrices de bytes de entrada se asignen a objetos de Class para que puedan recuperarse más adelante.

Como un comstackdor convierte el código fuente en archivos de clase (básicamente el byte []) y un cargador de clases convierte los archivos de clase en objetos de Class , no hay nada en la cadena que sea directamente adecuado para pasar de la Class a un byte []. Pero con el material que hace el tejido de código de bytes, la generación de código de bytes de tiempo de ejecución y similares, puede encontrar algo que pueda hacer esto.

Aquí hay algo para probar con BCEL :

 JavaClass clazz = Repository.lookupClass("foo.bar.YourClass"); byte[] bytes = clazz.getBytes(); 

No sabía la respuesta antes de leer tu pregunta, pero sabía que debería revisar las siguientes bibliotecas, porque admiten el formato de archivo de clase Java :

  • BCEL
  • javassist
  • asm

Si lo anterior no funciona, busque algo más en estas bibliotecas.