我想了解类是如何工作的。我想使用此代码最终字段值在字节码生成中不起作用
dout.writeShort(1);//field count
dout.writeShort(Modifier.PUBLIC|Modifier.STATIC|Modifier.FINAL);//modifiers
dout.writeShort(utfConstant("jjj"));//name
dout.writeShort(utfConstant("I"));//signature
dout.writeShort(1);//attribute count
dout.writeShort(utfConstant("ConstantValue"));//constant value attribute
dout.writeShort(2);//size of attribute
dout.writeShort(intConstant(8));//value
最后的字段添加到我的课,但当我尝试编译它
Exception in thread "main" java.lang.ClassFormatError: Invalid ConstantValue field attribute length 131082 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:161)
at Bytecode.BytecodeTest.makeClass(BytecodeTest.java:39)
at Bytecode.BytecodeTest.buildClass(BytecodeTest.java:24)
at Bytecode.BytecodeTest.main(BytecodeTest.java:17)
这里我得到这个错误是我的其他代码
private void writeConstantPool(DataOutputStream dout) throws IOException
{
dout.writeShort(poolIndex);
for (Data data : poolMap)
{
int tag = (byte) data.getData()[0];
dout.writeByte(tag);
switch (tag)
{
case CONSTANT_Utf8:
dout.writeUTF((String) data.getData()[1]);
break;
case CONSTANT_Class:
dout.writeShort((Integer) data.getData()[1]);
break;
case CONSTANT_Integer:
dout.writeInt((Integer) data.getData()[1]);
break;
default:
throw new RuntimeException();
}
}
}
private int utfConstant(String s)
{
return constant(CONSTANT_Utf8, s);
}
private int intConstant(int i)
{
return constant(CONSTANT_Integer, i);
}
private int classConstant(String s)
{
int classNameIndex = utfConstant(s.replace('.', '/'));
return constant(CONSTANT_Class, classNameIndex);
}
private int constant(Object... data)
{
Data constantData = new Data(data);
if (poolMap.contains(constantData))
return poolMap.indexOf(constantData)+1;
poolMap.add(poolIndex-1, constantData);
return poolIndex++;
}
private final Stack<Data> poolMap = new Stack<Data>();
private int poolIndex = 1;
private static class Data
{
private Object[] data;
public Data(Object... data)
{
this.data = data;
}
public Object[] getData()
{
return data;
}
public boolean equals(Object o)
{
if(o instanceof Data)
{
Data other = (Data) o;
return Arrays.equals(data, other.getData());
}
return false;
}
}
我这样做的方式是通过生成所有的方法和字段,然后生成常量池,然后我将常量池放在方法和字段之前的字节数组中。
任何人都可以告诉我我在做什么错我可以显示更多的代码,如果有必要,另外我认为这个问题可能与intConstant或常量值属性。
用字节码编辑器看这个后,它看起来像intConstant方法工作正常,所以我认为它是没有工作的字段代码。另外我看了一个字节码编辑器中的一个常量,它看起来是一样的我很困惑。
我曾经不得不使用bytcode操作,而我所做的就是编写一个简单的java类,其中包含相当于我想要在字节码中完成的源代码。我编译了这个类,然后用javap来查看字节码是什么。此外,JVM规范可能会非常有用。 – user3001
我知道我已经尝试了两个,我已经看了字节码中的常量值属性,我仍然不能看到我做错了什么。 – Popgalop
你可以发布类文件本身吗?我可以看看有什么不对。 – Antimony