gpt4 book ai didi

java - 最终字段值在字节码生成中不起作用

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:28:55 25 4
gpt4 key购买 nike

我正在尝试了解类(class)的运作方式。我正在尝试使用此代码向我的类(class)添加最终字段

    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 方法看起来工作正常,所以我认为是字段代码不起作用。我还查看了字节码编辑器中的一个常量,它看起来一样,我很困惑。

最佳答案

我认为属性的长度 应该是 32 位整数,而不是 16 位短整数。

关于java - 最终字段值在字节码生成中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17260753/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com