public static TypeBearer mergeType(TypeBearer ft1, TypeBearer ft2) {
    if ((ft1 == null) || ft1.equals(ft2)) {
      return ft1;
    } else if (ft2 == null) {
      return null;
    } else {
      Type type1 = ft1.getType();
      Type type2 = ft2.getType();

      if (type1 == type2) {
        return type1;
      } else if (type1.isReference() && type2.isReference()) {
        if (type1 == Type.KNOWN_NULL) {
          /*
           * A known-null merges with any other reference type to
           * be that reference type.
           */
          return type2;
        } else if (type2 == Type.KNOWN_NULL) {
          /*
           * The same as above, but this time it's type2 that's
           * the known-null.
           */
          return type1;
        } else if (type1.isArray() && type2.isArray()) {
          TypeBearer componentUnion = mergeType(type1.getComponentType(), type2.getComponentType());
          if (componentUnion == null) {
            /*
             * At least one of the types is a primitive type,
             * so the merged result is just Object.
             */
            return Type.OBJECT;
          }
          return ((Type) componentUnion).getArrayType();
        } else {
          /*
           * All other unequal reference types get merged to be
           * Object in this phase. This is fine here, but it
           * won't be the right thing to do in the verifier.
           */
          return Type.OBJECT;
        }
      } else if (type1.isIntlike() && type2.isIntlike()) {
        /*
         * Merging two non-identical int-like types results in
         * the type int.
         */
        return Type.INT;
      } else {
        return null;
      }
    }
  }
Merges two frame types.

@param ft1 {@code non-null;} a frame type
@param ft2 {@code non-null;} another frame type
@return {@code non-null;} the result of merging the two types
android/android_framework/dex-maker/src/main/java/com/android/dx/cf/code/Merger.java