public byte[] toByteArray() {
        // First step: compute the size in bytes of the ClassFile structure.
        // The magic field uses 4 bytes, 10 mandatory fields (minor_version, major_version,
        // constant_pool_count, access_flags, this_class, super_class, interfaces_count, fields_count,
        // methods_count and attributes_count) use 2 bytes each, and each interface uses 2 bytes too.
        int size = 24 + 2 * interfaceCount;
        int fieldsCount = 0;
        FieldWriter fieldWriter = firstField;
        while (fieldWriter != null) {
            ++fieldsCount;
            size += 8;
            fieldWriter = fieldWriter.fv;
        }
        int methodsCount = 0;
        MethodWriter methodWriter = firstMethod;
        while (methodWriter != null) {
            ++methodsCount;
            size += methodWriter.computeMethodInfoSize();
            methodWriter = methodWriter.mv;
        }

        // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS.
        int attributesCount = 0;
//        if (symbolTable.computeBootstrapMethodsSize() > 0) {
//            ++attributesCount;
//            size += symbolTable.computeBootstrapMethodsSize();
//        }

        // IMPORTANT: this must be the last part of the ClassFile size computation, because the previous
        // statements can add attribute names to the constant pool, thereby changing its size!
        size += symbolTable.constantPool.length;
        int constantPoolCount = symbolTable.constantPoolCount;
        if (constantPoolCount > 0xFFFF) {
            throw new JSONException("Class too large: " + symbolTable.className + ", constantPoolCount " + constantPoolCount);
        }

        // Second step: allocate a ByteVector of the correct size (in order to avoid any array copy in
        // dynamic resizes) and fill it with the ClassFile content.
        ByteVector result = new ByteVector(size);
        result.putInt(0xCAFEBABE).putInt(version);
        result.putShort(constantPoolCount)
                .putByteArray(
                        symbolTable.constantPool.data,
                        0,
                        symbolTable.constantPool.length
                ); // symbolTable.putConstantPool(result);
        int mask = 0;
        result.putShort(accessFlags & ~mask).putShort(thisClass).putShort(superClass);
        result.putShort(interfaceCount);
        for (int i = 0; i < interfaceCount; ++i) {
            result.putShort(interfaces[i]);
        }
        result.putShort(fieldsCount);
        fieldWriter = firstField;
        while (fieldWriter != null) {
            fieldWriter.putFieldInfo(result);
            fieldWriter = fieldWriter.fv;
        }
        result.putShort(methodsCount);
        boolean hasFrames = false;
        boolean hasAsmInstructions = false;
        methodWriter = firstMethod;
        while (methodWriter != null) {
            hasFrames |= methodWriter.stackMapTableNumberOfEntries > 0;
            hasAsmInstructions |= methodWriter.hasAsmInstructions;
            methodWriter.putMethodInfo(result);
            methodWriter = methodWriter.mv;
        }
        // For ease of reference, we use here the same attribute order as in Section 4.7 of the JVMS.
        result.putShort(attributesCount);
//        symbolTable.putBootstrapMethods(result);

        // Third step: replace the ASM specific instructions, if any.
        if (hasAsmInstructions) {
            throw new UnsupportedOperationException();
        } else {
            return result.data;
        }
    }
Returns the content of the class file that was built by this ClassWriter.

@return the binary content of the JVMS ClassFile structure that was built by this ClassWriter.
core/src/main/java/com/alibaba/fastjson2/internal/asm/ClassWriter.java