code: public static boolean isAssignable(Class<?> lhsType, Class<?> rhsType) {
          if (rhsType == null) {
              return !lhsType.isPrimitive();
          }
          if (lhsType.isArray() || rhsType.isArray()) {
              if ((lhsType.isArray() && rhsType.isArray())) {
                  return isAssignable(lhsType.getComponentType(), rhsType.getComponentType());
              }
          } else {
              if (lhsType.isAssignableFrom(rhsType)) {
                  return true;
              }
              if (rhsType.isPrimitive() && !lhsType.isPrimitive() && lhsType.equals(getPrimitiveWrapper(rhsType))) {
                  return true;
              }
              if (lhsType.isPrimitive() && !rhsType.isPrimitive() && rhsType.equals(getPrimitiveWrapper(lhsType))) {
                  return true;
              }
          }
          return false;
      }
docs: Check if the right-hand side type may be assigned to the left-hand side
  type, assuming setting by reflection. Considers primitive wrapper
  classes as assignable to the corresponding primitive types.
  
  @param lhsType the target type
  @param rhsType the value type that should be assigned to the target type
  @return if the target type is assignable from the value type