動的バイトコード生成を使用して値 2 を返す hello という名前のメソッドを生成しようとしています。これが私の現在のコードです。メソッドを生成します。
dout.writeShort(Modifier.PUBLIC);//class modifier
dout.writeShort(classConstant("test"));//class name
dout.writeShort(classConstant(Object.class.getName()));//superclass
dout.writeShort(0);//interface count
dout.writeShort(0);//field count
dout.writeShort(1);//method count
dout.writeShort(Modifier.PUBLIC|Modifier.STATIC);//modifiers
dout.writeShort(utfConstant("test"));//name
dout.writeShort(utfConstant(methodDescriptor(int.class, new Class[]{})));//descriptor
dout.writeShort(1);//attribute count
dout.writeShort(utfConstant("Code"));//attribute name
dout.writeInt(34);//attribute length
dout.writeShort(1);//max stack
dout.writeShort(0);//max locals
dout.writeInt(2);//code length
dout.writeByte(0x05);//iconst_2 opcode
dout.writeByte(0xAC);//ireturn opcode
dout.writeShort(0);//exception count
dout.writeShort(0);//attribute count
dout.writeShort(0);//class attributes
問題は、このコードを実行すると、この例外が発生することです
Exception in thread "main" java.lang.ClassFormatError: Invalid method Code length 0 in class file test
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
at java.lang.ClassLoader.defineClass(ClassLoader.java:634)
at Bytecode.BytecodeTest$BytecodeClassLoader.buildClass(BytecodeTest.java:229)
at Bytecode.BytecodeTest.makeClass(BytecodeTest.java:42)
at Bytecode.BytecodeTest.buildClass(BytecodeTest.java:27)
at Bytecode.BytecodeTest.main(BytecodeTest.java:19)
奇妙なことは、コードの長さを 0 よりも大きくし、2 にしていることです。Oracle の仕様に戻りましたが、それでも正しく見えます。一部のデータを間違ったタイプで書き込んでいるような気がしますが、まだ問題が見つかりません。