private static boolean merge(
            final SymbolTable symbolTable,
            final int sourceType,
            final int[] dstTypes,
            final int dstIndex
    ) {
        int dstType = dstTypes[dstIndex];
        if (dstType == sourceType) {
            // If the types are equal, merge(sourceType, dstType) = dstType, so there is no change.
            return false;
        }
        int srcType = sourceType;
        if ((sourceType & ~DIM_MASK) == NULL) {
            if (dstType == NULL) {
                return false;
            }
            srcType = NULL;
        }
        if (dstType == 0) {
            // If dstTypes[dstIndex] has never been assigned, merge(srcType, dstType) = srcType.
            dstTypes[dstIndex] = srcType;
            return true;
        }

        final String TYPE_JAVA_OBJECT = "java/lang/Object";

        int mergedType;
        if ((dstType & DIM_MASK) != 0 || (dstType & KIND_MASK) == REFERENCE_KIND) {
            // If dstType is a reference type of any array dimension.
            if (srcType == NULL) {
                // If srcType is the NULL type, merge(srcType, dstType) = dstType, so there is no change.
                return false;
            }

            if ((srcType & (DIM_MASK | KIND_MASK)) == (dstType & (DIM_MASK | KIND_MASK))) {
                // If srcType has the same array dimension and the same kind as dstType.
                if ((dstType & KIND_MASK) == REFERENCE_KIND) {
                    // If srcType and dstType are reference types with the same array dimension,
                    // merge(srcType, dstType) = dim(srcType) | common super class of srcType and dstType.
                    mergedType =
                            (srcType & DIM_MASK)
                                    | REFERENCE_KIND
                                    | symbolTable.addMergedType(srcType & VALUE_MASK, dstType & VALUE_MASK);
                } else {
                    // If srcType and dstType are array types of equal dimension but different element types,
                    // merge(srcType, dstType) = dim(srcType) - 1 | java/lang/Object.
                    int mergedDim = ELEMENT_OF + (srcType & DIM_MASK);
                    mergedType = mergedDim | REFERENCE_KIND | symbolTable.addType(TYPE_JAVA_OBJECT);
                }
            } else if ((srcType & DIM_MASK) != 0 || (srcType & KIND_MASK) == REFERENCE_KIND) {
                // If srcType is any other reference or array type,
                // merge(srcType, dstType) = min(srcDdim, dstDim) | java/lang/Object
                // where srcDim is the array dimension of srcType, minus 1 if srcType is an array type
                // with a non reference element type (and similarly for dstDim).
                int srcDim = srcType & DIM_MASK;
                if (srcDim != 0 && (srcType & KIND_MASK) != REFERENCE_KIND) {
                    srcDim = ELEMENT_OF + srcDim;
                }
                int dstDim = dstType & DIM_MASK;
                if (dstDim != 0 && (dstType & KIND_MASK) != REFERENCE_KIND) {
                    dstDim = ELEMENT_OF + dstDim;
                }
                mergedType =
                        Math.min(srcDim, dstDim) | REFERENCE_KIND | symbolTable.addType(TYPE_JAVA_OBJECT);
            } else {
                // If srcType is any other type, merge(srcType, dstType) = TOP.
                mergedType = TOP;
            }
        } else {
            mergedType = dstType == NULL && ((srcType & DIM_MASK) != 0 || (srcType & KIND_MASK) == REFERENCE_KIND)
                    ? srcType : TOP;
        }

        if (mergedType != dstType) {
            dstTypes[dstIndex] = mergedType;
            return true;
        }
        return false;
    }
Merges the type at the given index in the given abstract type array with the given type.
Returns {@literal true} if the type array has been modified by this operation.

@param symbolTable the type table to use to lookup and store type {@link Symbol}.
@param sourceType  the abstract type with which the abstract type array element must be merged.
                   This type should be of {@link #CONSTANT_KIND}, {@link #REFERENCE_KIND} or {@link
                   #UNINITIALIZED_KIND} kind, with positive or {@literal null} array dimensions.
@param dstTypes    an array of abstract types. These types should be of {@link #CONSTANT_KIND},
                   {@link #REFERENCE_KIND} or {@link #UNINITIALIZED_KIND} kind, with positive or {@literal
                   null} array dimensions.
@param dstIndex    the index of the type that must be merged in dstTypes.
@return {@literal true} if the type array has been modified by this operation.
core/src/main/java/com/alibaba/fastjson2/internal/asm/Frame.java