Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 最终字段值在字节码生成中不起作用_Java_Bytecode_Bytecode Manipulation - Fatal编程技术网

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

Java 最终字段值在字节码生成中不起作用,java,bytecode,bytecode-manipulation,Java,Bytecode,Bytecode Manipulation,我正在努力学习如何上课。我正在尝试使用此代码向类中添加最后一个字段 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);//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;
        }
    }
private void writeConstantPool(DataOutputStream dout)引发IOException
{
dout.writeShort(poolidex);
对于(数据:poolMap)
{
int标记=(字节)data.getData()[0];
双写字节(tag);
开关(标签)
{
外壳常数\u Utf8:
dout.writeUTF((字符串)data.getData()[1]);
打破
案例常数\u类:
dout.writeShort((整数)data.getData()[1]);
打破
大小写常量\u整数:
dout.writeInt((整数)data.getData()[1]);
打破
违约:
抛出新的RuntimeException();
}
}
}
专用int utfConstant(字符串s)
{
返回常数(常数μUtf8,s);
}   
私有整数常量(整数i)
{
返回常量(常量\整数,i);
}
私有int类常量(字符串s)
{
int classNameIndex=utfConstant(s.replace('.','/');
返回常量(常量\u类,classNameIndex);
}
私有int常量(对象…数据)
{
数据常量数据=新数据(数据);
if(poolMap.contains(constantData))
返回poolMap.indexOf(constantData)+1;
poolMap.add(Pooldex-1,constantData);
返回pooldex++;
}
私有最终堆栈池映射=新堆栈();
私有int-poolidex=1;
私有静态类数据
{
私有对象[]数据;
公共数据(对象…数据)
{
这个数据=数据;
}
公共对象[]获取数据()
{
返回数据;
}
公共布尔等于(对象o)
{           
if(o数据实例)
{
数据其他=(数据)o;
返回Arrays.equals(data,other.getData());
}
返回false;
}
}
我这样做的方式是生成所有方法和字段,然后生成常量池,然后将常量池放在方法和字段之前的字节数组中

有人能告诉我我做错了什么吗?如果需要,我可以显示更多的代码,此外,我认为问题可能出在intConstant或常量值属性上


在使用字节码编辑器查看这一点之后,看起来intConstant方法工作得很好,所以我认为是字段代码不起作用。另外,我在字节码编辑器中查看了一个常量,它看起来和我所困惑的一样。

我相信属性的
长度应该是32位整数,一点也不短。

我曾经不得不处理字节码操作,我所做的是编写一个简单的java类,其中包含与我想在字节码中执行的操作等效的源代码。我编译了这个类,然后使用javap查看字节码是什么。JVM规范也非常有用。我知道我已经尝试了这两种方法,并且我已经查看了字节码中的常量值属性,但我仍然看不出我做错了什么。你能发布类文件本身吗?我可以看看有什么问题。接得好。即使有经验,也很难发现这些东西。