.class
files.See: Description
Interface | Description |
---|---|
AttrContainer |
An interface for objects that (may) contain Attribute objects.
|
Filter<T> | |
Member |
Class | Description |
---|---|
Access |
Access flags.
|
AnnotationDefaultAttr |
Represents a "AnnotationDefault" attribute.
|
AnnotationEntry |
An annotation value mirror.
|
AnnotationEntry.Value | |
ArrayClassLoader |
Load classes from a set of byte arrays.
|
ArrayType | |
Attribute |
Represents an Attribute of an AttrContainer.
|
ClassFileInput |
Class to read a ClassType from a DataInputStream (.class file).
|
ClassType | |
ClassTypeWriter |
This class prints out in contents of a ClassType in human-readable form.
|
CodeAttr |
Represents the contents of a standard "Code" attribute.
|
ConstantPool |
Manages a pool of constants, as used in .class files and Java interpreters.
|
ConstantValueAttr | |
CpoolClass |
A CONSTANT_Class entry in the constant pool.
|
CpoolEntry |
An entry in the constant pool of a ClassType.
|
CpoolInvokeDynamic |
A CONSTANT_InvokeDynamic entry in the constant pool.
|
CpoolMethodHandle |
A CONSTANT_MethodHandle entry in the constant pool.
|
CpoolMethodType |
A CONSTANT_MethodType entry in the constant pool.
|
CpoolNameAndType |
A CONSTANT_NameAndType entry in the constant pool.
|
CpoolRef |
A CONSTANT_{Field,Method,InterfaceMethod}Ref entry in the constant pool.
|
CpoolString |
A CONSTANT_String entry in the constant pool.
|
CpoolUtf8 |
A CONSTANT_Utf8 entry in the constant pool.
|
CpoolValue1 |
A CONSTANT_Integer or CONSTANT_Float entry in the constant pool.
|
CpoolValue2 |
A CONSTANT_Long or CONSTANT_Double entry in the constant pool.
|
dump |
Application to read a ClassType from a DataInputStream (.class file).
|
EnclosingMethodAttr | |
ExceptionsAttr |
Represents the contents of a standard "Exceptions" attribute.
|
ExitableBlock |
Support for code block that one may be exited.
|
Field | |
IfState |
The state of a conditional expression or statement.
|
InnerClassesAttr | |
Label |
A Label represents a location in a Code attribute.
|
LineNumbersAttr |
Represents the contents of a standard "LineNumberTable" attribute.
|
ListCodeSize |
Application that lists the number of bytes in named methods.
|
LocalVarsAttr | |
Location |
An abstracted "variable", inherited by Field and Variable.
|
Method |
Represents a method in a
ClassType . |
MiscAttr | |
ObjectType |
Semi-abstract class object reference types.
|
ParameterizedType | |
PrimType | |
RuntimeAnnotationsAttr |
Represents a "RuntimeVisibleAnnotations" or "RuntimeInvisibleAnnotations" attribute.
|
Scope | |
SignatureAttr | |
SourceDebugExtAttr |
Represents the contents of a JSR-45 "SourceDebugExtension" attribute.
|
SourceFileAttr | |
SpecialObjectType |
Used for object types that don't correspond to JVM types.
|
StackMapTableAttr |
Represents a "StackMapTable" attribute, as added in Java 6.
|
SwitchState |
Maintains the state for generating a switch statement or expression.
|
TryState |
The state of a try statement.
|
Type |
An abstract type as used by both gnu.bytecode and gnu.expr.
|
Type.NeverReturns |
A marker class, used for
Type.neverReturnsType . |
TypeVariable |
A type variable in a parameterized type.
|
UninitializedType |
A pseudo-type used for allocated but uninitialized objects.
|
VarEnumerator |
Use this Enuemration class to iterate over the Variables in a Scope.
|
Variable |
Information about a local variable in a method's code.
|
ZipArchive |
A class to manipulate a .zip archive.
|
ZipLoader |
Load classes from a Zip archive.
|
Contains classes to generate, read,
write, and print Java bytecode in the form of .class
files.
It is used by Kawa to compile Scheme into bytecodes; it should be useful for other languages that need to be compiled into Java bytecodes. (An interesting exercise would be an interactive Java expression evaluator.) The classes here are relatively low-level. If you want to use them to generate bytecode from a high-level language, it would be easier to use the gnu.expr package, which works at the expression level, and handles all the code-generation for you.
The most important class is ClassType
.
This contains information
about a single class. Note that the difference between ClassType
and java.lang.Class
is that the latter can only represent existing
classes that have been loaded into the Java VM; in contrast,
ClassType
can be used to build new classes
incrementally and on the fly. A ClassType
can also
wrap
a java.lang.Class
, or data read in
from a .class
file.
Use ClassType.make
to refer to
existing classes and new ClassType
to refer to classes you're
generating.
A ClassType
has a list of Field
objects;
new ones can be added using
the various addField
methods. A ClassType
manages a ConstantPool
.
A ClassType
also has a list of Method
objects;
new ones can be created by the various addMethod
objects.
Calling Method.startCode
gives you a CodeAttr
object
you can use to emit bytecodes for that method.
Once you have finished generating a ClassType
, you
can write it to a .class
file with
the writeToFile
method. You can also make a
byte array suitable for ClassLoader.defineClass
using the
writeToArray
method. This is useful if you want to compile and immediately load a class,
without going via disk.
You can print out the contents of a ClassType
in
human-readable
form using the class ClassTypeWriter
. This prints a fair bit of
information of the generated class, including
dis-assembling the code of the methods.
You can also build a ClassType
by reading it from an
existing .class
file by using a ClassFileInput
class. This reads the constant
pool, the fields, methods, superclass, and interfaces.
The gnu.bytecode.dump
class has a main
method
that prints out the information in a named class file, which you can use as
a replacement for javap(1)
.
Here's a complete example showing the basics. If this was really all you wanted to do, the code could be shorter, but you get to see more of what's available this way.
import gnu.bytecode.*; public class MetaHelloWorld { public static void main(String[] args) throws Exception { // "public class HelloWorld extends java.lang.Object". ClassType c = new ClassType("HelloWorld"); c.setSuper("java.lang.Object"); c.setModifiers(Access.PUBLIC); // "public static int add(int, int)". Method m = c.addMethod("add", "(II)I", Access.PUBLIC | Access.STATIC); CodeAttr code = m.startCode(); code.pushScope(); code.emitLoad(code.getArg(0)); code.emitLoad(code.getArg(1)); code.emitAdd(Type.intType); Variable resultVar = code.addLocal(Type.intType, "result"); code.emitDup(); code.emitStore(resultVar); code.emitReturn(); code.popScope(); // Get a byte[] representing the class file. // We could write this to disk if we wanted. byte[] classFile = c.writeToArray(); // Disassemble this class. // The output is similar to javap(1). ClassTypeWriter.print(c, System.out, 0); // Load the generated class into this JVM. // gnu.bytecode provides ArrayClassLoader, or you can use your own. ArrayClassLoader cl = new ArrayClassLoader(); cl.addClass("HelloWorld", classFile); // Actual invocation is just the usual reflection code. Class<?> helloWorldClass = cl.loadClass("HelloWorld", true); Class[] argTypes = new Class[] { int.class, int.class }; int result = (Integer) helloWorldClass.getMethod("add", argTypes).invoke(null, 1, 2); System.err.println(result); } }
gnu.bytecode
package is currently distributed as part of
Kawa, though it can be used independently
of the rest of Kawa.