Java Code Examples for sun.invoke.util.Wrapper#forPrimitiveType()

The following examples show how to use sun.invoke.util.Wrapper#forPrimitiveType() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: MethodHandles.java    From openjdk-jdk8u with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Produces a method handle of the requested return type which returns the given
 * constant value every time it is invoked.
 * <p>
 * Before the method handle is returned, the passed-in value is converted to the requested type.
 * If the requested type is primitive, widening primitive conversions are attempted,
 * else reference conversions are attempted.
 * <p>The returned method handle is equivalent to {@code identity(type).bindTo(value)}.
 * @param type the return type of the desired method handle
 * @param value the value to return
 * @return a method handle of the given return type and no arguments, which always returns the given value
 * @throws NullPointerException if the {@code type} argument is null
 * @throws ClassCastException if the value cannot be converted to the required return type
 * @throws IllegalArgumentException if the given type is {@code void.class}
 */
public static
MethodHandle constant(Class<?> type, Object value) {
    if (type.isPrimitive()) {
        if (type == void.class)
            throw newIllegalArgumentException("void type");
        Wrapper w = Wrapper.forPrimitiveType(type);
        value = w.convert(value, type);
        if (w.zero().equals(value))
            return zero(w, type);
        return insertArguments(identity(type), 0, value);
    } else {
        if (value == null)
            return zero(Wrapper.OBJECT, type);
        return identity(type).bindTo(value);
    }
}
 
Example 2
Source File: VarargsArrayTest.java    From dragonwell8_jdk with GNU General Public License v2.0 6 votes vote down vote up
private static String toArrayString(Object a) {
    if (a == null)  return "null";
    Class<?> elemType = a.getClass().getComponentType();
    if (elemType == null)  return a.toString();
    if (elemType.isPrimitive()) {
        switch (Wrapper.forPrimitiveType(elemType)) {
            case INT:      return Arrays.toString((int[])a);
            case BYTE:     return Arrays.toString((byte[])a);
            case BOOLEAN:  return Arrays.toString((boolean[])a);
            case SHORT:    return Arrays.toString((short[])a);
            case CHAR:     return Arrays.toString((char[])a);
            case FLOAT:    return Arrays.toString((float[])a);
            case LONG:     return Arrays.toString((long[])a);
            case DOUBLE:   return Arrays.toString((double[])a);
        }
    }
    return Arrays.toString((Object[])a);
}
 
Example 3
Source File: MethodHandles.java    From dragonwell8_jdk with GNU General Public License v2.0 6 votes vote down vote up
/**
 * Produces a method handle of the requested return type which returns the given
 * constant value every time it is invoked.
 * <p>
 * Before the method handle is returned, the passed-in value is converted to the requested type.
 * If the requested type is primitive, widening primitive conversions are attempted,
 * else reference conversions are attempted.
 * <p>The returned method handle is equivalent to {@code identity(type).bindTo(value)}.
 * @param type the return type of the desired method handle
 * @param value the value to return
 * @return a method handle of the given return type and no arguments, which always returns the given value
 * @throws NullPointerException if the {@code type} argument is null
 * @throws ClassCastException if the value cannot be converted to the required return type
 * @throws IllegalArgumentException if the given type is {@code void.class}
 */
public static
MethodHandle constant(Class<?> type, Object value) {
    if (type.isPrimitive()) {
        if (type == void.class)
            throw newIllegalArgumentException("void type");
        Wrapper w = Wrapper.forPrimitiveType(type);
        value = w.convert(value, type);
        if (w.zero().equals(value))
            return zero(w, type);
        return insertArguments(identity(type), 0, value);
    } else {
        if (value == null)
            return zero(Wrapper.OBJECT, type);
        return identity(type).bindTo(value);
    }
}
 
Example 4
Source File: VarargsArrayTest.java    From openjdk-jdk9 with GNU General Public License v2.0 6 votes vote down vote up
private static String toArrayString(Object a) {
    if (a == null)  return "null";
    Class<?> elemType = a.getClass().getComponentType();
    if (elemType == null)  return a.toString();
    if (elemType.isPrimitive()) {
        switch (Wrapper.forPrimitiveType(elemType)) {
            case INT:      return Arrays.toString((int[])a);
            case BYTE:     return Arrays.toString((byte[])a);
            case BOOLEAN:  return Arrays.toString((boolean[])a);
            case SHORT:    return Arrays.toString((short[])a);
            case CHAR:     return Arrays.toString((char[])a);
            case FLOAT:    return Arrays.toString((float[])a);
            case LONG:     return Arrays.toString((long[])a);
            case DOUBLE:   return Arrays.toString((double[])a);
        }
    }
    return Arrays.toString((Object[])a);
}
 
Example 5
Source File: MethodHandleImpl.java    From openjdk-jdk8u with GNU General Public License v2.0 5 votes vote down vote up
static
MethodHandle makeGuardWithCatch(MethodHandle target,
                                Class<? extends Throwable> exType,
                                MethodHandle catcher) {
    MethodType type = target.type();
    LambdaForm form = makeGuardWithCatchForm(type.basicType());

    // Prepare auxiliary method handles used during LambdaForm interpreation.
    // Box arguments and wrap them into Object[]: ValueConversions.array().
    MethodType varargsType = type.changeReturnType(Object[].class);
    MethodHandle collectArgs = varargsArray(type.parameterCount()).asType(varargsType);
    // Result unboxing: ValueConversions.unbox() OR ValueConversions.identity() OR ValueConversions.ignore().
    MethodHandle unboxResult;
    Class<?> rtype = type.returnType();
    if (rtype.isPrimitive()) {
        if (rtype == void.class) {
            unboxResult = ValueConversions.ignore();
        } else {
            Wrapper w = Wrapper.forPrimitiveType(type.returnType());
            unboxResult = ValueConversions.unboxExact(w);
        }
    } else {
        unboxResult = MethodHandles.identity(Object.class);
    }

    BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLLL();
    BoundMethodHandle mh;
    try {
        mh = (BoundMethodHandle)
                data.constructor().invokeBasic(type, form, (Object) target, (Object) exType, (Object) catcher,
                                               (Object) collectArgs, (Object) unboxResult);
    } catch (Throwable ex) {
        throw uncaughtException(ex);
    }
    assert(mh.type() == type);
    return mh;
}
 
Example 6
Source File: MethodHandleImpl.java    From jdk8u60 with GNU General Public License v2.0 5 votes vote down vote up
static
MethodHandle makeGuardWithCatch(MethodHandle target,
                                Class<? extends Throwable> exType,
                                MethodHandle catcher) {
    MethodType type = target.type();
    LambdaForm form = makeGuardWithCatchForm(type.basicType());

    // Prepare auxiliary method handles used during LambdaForm interpreation.
    // Box arguments and wrap them into Object[]: ValueConversions.array().
    MethodType varargsType = type.changeReturnType(Object[].class);
    MethodHandle collectArgs = varargsArray(type.parameterCount()).asType(varargsType);
    // Result unboxing: ValueConversions.unbox() OR ValueConversions.identity() OR ValueConversions.ignore().
    MethodHandle unboxResult;
    Class<?> rtype = type.returnType();
    if (rtype.isPrimitive()) {
        if (rtype == void.class) {
            unboxResult = ValueConversions.ignore();
        } else {
            Wrapper w = Wrapper.forPrimitiveType(type.returnType());
            unboxResult = ValueConversions.unboxExact(w);
        }
    } else {
        unboxResult = MethodHandles.identity(Object.class);
    }

    BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLLL();
    BoundMethodHandle mh;
    try {
        mh = (BoundMethodHandle)
                data.constructor().invokeBasic(type, form, (Object) target, (Object) exType, (Object) catcher,
                                               (Object) collectArgs, (Object) unboxResult);
    } catch (Throwable ex) {
        throw uncaughtException(ex);
    }
    assert(mh.type() == type);
    return mh;
}
 
Example 7
Source File: MethodHandles.java    From openjdk-8 with GNU General Public License v2.0 5 votes vote down vote up
/**
 * Provides a target method handle with one or more <em>bound arguments</em>
 * in advance of the method handle's invocation.
 * The formal parameters to the target corresponding to the bound
 * arguments are called <em>bound parameters</em>.
 * Returns a new method handle which saves away the bound arguments.
 * When it is invoked, it receives arguments for any non-bound parameters,
 * binds the saved arguments to their corresponding parameters,
 * and calls the original target.
 * <p>
 * The type of the new method handle will drop the types for the bound
 * parameters from the original target type, since the new method handle
 * will no longer require those arguments to be supplied by its callers.
 * <p>
 * Each given argument object must match the corresponding bound parameter type.
 * If a bound parameter type is a primitive, the argument object
 * must be a wrapper, and will be unboxed to produce the primitive value.
 * <p>
 * The {@code pos} argument selects which parameters are to be bound.
 * It may range between zero and <i>N-L</i> (inclusively),
 * where <i>N</i> is the arity of the target method handle
 * and <i>L</i> is the length of the values array.
 * @param target the method handle to invoke after the argument is inserted
 * @param pos where to insert the argument (zero for the first)
 * @param values the series of arguments to insert
 * @return a method handle which inserts an additional argument,
 *         before calling the original method handle
 * @throws NullPointerException if the target or the {@code values} array is null
 * @see MethodHandle#bindTo
 */
public static
MethodHandle insertArguments(MethodHandle target, int pos, Object... values) {
    int insCount = values.length;
    MethodType oldType = target.type();
    int outargs = oldType.parameterCount();
    int inargs  = outargs - insCount;
    if (inargs < 0)
        throw newIllegalArgumentException("too many values to insert");
    if (pos < 0 || pos > inargs)
        throw newIllegalArgumentException("no argument type to append");
    MethodHandle result = target;
    for (int i = 0; i < insCount; i++) {
        Object value = values[i];
        Class<?> ptype = oldType.parameterType(pos+i);
        if (ptype.isPrimitive()) {
            char btype = 'I';
            Wrapper w = Wrapper.forPrimitiveType(ptype);
            switch (w) {
            case LONG:    btype = 'J'; break;
            case FLOAT:   btype = 'F'; break;
            case DOUBLE:  btype = 'D'; break;
            }
            // perform unboxing and/or primitive conversion
            value = w.convert(value, ptype);
            result = result.bindArgument(pos, btype, value);
            continue;
        }
        value = ptype.cast(value);  // throw CCE if needed
        if (pos == 0) {
            result = result.bindReceiver(value);
        } else {
            result = result.bindArgument(pos, 'L', value);
        }
    }
    return result;
}
 
Example 8
Source File: MethodHandles.java    From TencentKona-8 with GNU General Public License v2.0 5 votes vote down vote up
private static BoundMethodHandle insertArgumentPrimitive(BoundMethodHandle result, int pos,
                                                         Class<?> ptype, Object value) {
    Wrapper w = Wrapper.forPrimitiveType(ptype);
    // perform unboxing and/or primitive conversion
    value = w.convert(value, ptype);
    switch (w) {
    case INT:     return result.bindArgumentI(pos, (int)value);
    case LONG:    return result.bindArgumentJ(pos, (long)value);
    case FLOAT:   return result.bindArgumentF(pos, (float)value);
    case DOUBLE:  return result.bindArgumentD(pos, (double)value);
    default:      return result.bindArgumentI(pos, ValueConversions.widenSubword(value));
    }
}
 
Example 9
Source File: MethodHandles.java    From jdk-1.7-annotated with Apache License 2.0 5 votes vote down vote up
/**
 * Provides a target method handle with one or more <em>bound arguments</em>
 * in advance of the method handle's invocation.
 * The formal parameters to the target corresponding to the bound
 * arguments are called <em>bound parameters</em>.
 * Returns a new method handle which saves away the bound arguments.
 * When it is invoked, it receives arguments for any non-bound parameters,
 * binds the saved arguments to their corresponding parameters,
 * and calls the original target.
 * <p>
 * The type of the new method handle will drop the types for the bound
 * parameters from the original target type, since the new method handle
 * will no longer require those arguments to be supplied by its callers.
 * <p>
 * Each given argument object must match the corresponding bound parameter type.
 * If a bound parameter type is a primitive, the argument object
 * must be a wrapper, and will be unboxed to produce the primitive value.
 * <p>
 * The {@code pos} argument selects which parameters are to be bound.
 * It may range between zero and <i>N-L</i> (inclusively),
 * where <i>N</i> is the arity of the target method handle
 * and <i>L</i> is the length of the values array.
 * @param target the method handle to invoke after the argument is inserted
 * @param pos where to insert the argument (zero for the first)
 * @param values the series of arguments to insert
 * @return a method handle which inserts an additional argument,
 *         before calling the original method handle
 * @throws NullPointerException if the target or the {@code values} array is null
 * @see MethodHandle#bindTo
 */
public static
MethodHandle insertArguments(MethodHandle target, int pos, Object... values) {
    int insCount = values.length;
    MethodType oldType = target.type();
    int outargs = oldType.parameterCount();
    int inargs  = outargs - insCount;
    if (inargs < 0)
        throw newIllegalArgumentException("too many values to insert");
    if (pos < 0 || pos > inargs)
        throw newIllegalArgumentException("no argument type to append");
    MethodHandle result = target;
    for (int i = 0; i < insCount; i++) {
        Object value = values[i];
        Class<?> ptype = oldType.parameterType(pos+i);
        if (ptype.isPrimitive()) {
            char btype = 'I';
            Wrapper w = Wrapper.forPrimitiveType(ptype);
            switch (w) {
            case LONG:    btype = 'J'; break;
            case FLOAT:   btype = 'F'; break;
            case DOUBLE:  btype = 'D'; break;
            }
            // perform unboxing and/or primitive conversion
            value = w.convert(value, ptype);
            result = result.bindArgument(pos, btype, value);
            continue;
        }
        value = ptype.cast(value);  // throw CCE if needed
        if (pos == 0) {
            result = result.bindReceiver(value);
        } else {
            result = result.bindArgument(pos, 'L', value);
        }
    }
    return result;
}
 
Example 10
Source File: MethodHandles.java    From JDKSourceCode1.8 with MIT License 5 votes vote down vote up
private static BoundMethodHandle insertArgumentPrimitive(BoundMethodHandle result, int pos,
                                                         Class<?> ptype, Object value) {
    Wrapper w = Wrapper.forPrimitiveType(ptype);
    // perform unboxing and/or primitive conversion
    value = w.convert(value, ptype);
    switch (w) {
    case INT:     return result.bindArgumentI(pos, (int)value);
    case LONG:    return result.bindArgumentJ(pos, (long)value);
    case FLOAT:   return result.bindArgumentF(pos, (float)value);
    case DOUBLE:  return result.bindArgumentD(pos, (double)value);
    default:      return result.bindArgumentI(pos, ValueConversions.widenSubword(value));
    }
}
 
Example 11
Source File: MethodHandleImpl.java    From TencentKona-8 with GNU General Public License v2.0 5 votes vote down vote up
static
MethodHandle makeGuardWithCatch(MethodHandle target,
                                Class<? extends Throwable> exType,
                                MethodHandle catcher) {
    MethodType type = target.type();
    LambdaForm form = makeGuardWithCatchForm(type.basicType());

    // Prepare auxiliary method handles used during LambdaForm interpreation.
    // Box arguments and wrap them into Object[]: ValueConversions.array().
    MethodType varargsType = type.changeReturnType(Object[].class);
    MethodHandle collectArgs = varargsArray(type.parameterCount()).asType(varargsType);
    // Result unboxing: ValueConversions.unbox() OR ValueConversions.identity() OR ValueConversions.ignore().
    MethodHandle unboxResult;
    Class<?> rtype = type.returnType();
    if (rtype.isPrimitive()) {
        if (rtype == void.class) {
            unboxResult = ValueConversions.ignore();
        } else {
            Wrapper w = Wrapper.forPrimitiveType(type.returnType());
            unboxResult = ValueConversions.unboxExact(w);
        }
    } else {
        unboxResult = MethodHandles.identity(Object.class);
    }

    BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLLL();
    BoundMethodHandle mh;
    try {
        mh = (BoundMethodHandle)
                data.constructor().invokeBasic(type, form, (Object) target, (Object) exType, (Object) catcher,
                                               (Object) collectArgs, (Object) unboxResult);
    } catch (Throwable ex) {
        throw uncaughtException(ex);
    }
    assert(mh.type() == type);
    return mh;
}
 
Example 12
Source File: MethodHandleImpl.java    From jdk8u_jdk with GNU General Public License v2.0 5 votes vote down vote up
static
MethodHandle makeGuardWithCatch(MethodHandle target,
                                Class<? extends Throwable> exType,
                                MethodHandle catcher) {
    MethodType type = target.type();
    LambdaForm form = makeGuardWithCatchForm(type.basicType());

    // Prepare auxiliary method handles used during LambdaForm interpreation.
    // Box arguments and wrap them into Object[]: ValueConversions.array().
    MethodType varargsType = type.changeReturnType(Object[].class);
    MethodHandle collectArgs = varargsArray(type.parameterCount()).asType(varargsType);
    // Result unboxing: ValueConversions.unbox() OR ValueConversions.identity() OR ValueConversions.ignore().
    MethodHandle unboxResult;
    Class<?> rtype = type.returnType();
    if (rtype.isPrimitive()) {
        if (rtype == void.class) {
            unboxResult = ValueConversions.ignore();
        } else {
            Wrapper w = Wrapper.forPrimitiveType(type.returnType());
            unboxResult = ValueConversions.unboxExact(w);
        }
    } else {
        unboxResult = MethodHandles.identity(Object.class);
    }

    BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLLL();
    BoundMethodHandle mh;
    try {
        mh = (BoundMethodHandle)
                data.constructor().invokeBasic(type, form, (Object) target, (Object) exType, (Object) catcher,
                                               (Object) collectArgs, (Object) unboxResult);
    } catch (Throwable ex) {
        throw uncaughtException(ex);
    }
    assert(mh.type() == type);
    return mh;
}
 
Example 13
Source File: MethodHandles.java    From jdk8u-dev-jdk with GNU General Public License v2.0 5 votes vote down vote up
private static BoundMethodHandle insertArgumentPrimitive(BoundMethodHandle result, int pos,
                                                         Class<?> ptype, Object value) {
    Wrapper w = Wrapper.forPrimitiveType(ptype);
    // perform unboxing and/or primitive conversion
    value = w.convert(value, ptype);
    switch (w) {
    case INT:     return result.bindArgumentI(pos, (int)value);
    case LONG:    return result.bindArgumentJ(pos, (long)value);
    case FLOAT:   return result.bindArgumentF(pos, (float)value);
    case DOUBLE:  return result.bindArgumentD(pos, (double)value);
    default:      return result.bindArgumentI(pos, ValueConversions.widenSubword(value));
    }
}
 
Example 14
Source File: MethodHandleImpl.java    From hottub with GNU General Public License v2.0 5 votes vote down vote up
static
MethodHandle makeGuardWithCatch(MethodHandle target,
                                Class<? extends Throwable> exType,
                                MethodHandle catcher) {
    MethodType type = target.type();
    LambdaForm form = makeGuardWithCatchForm(type.basicType());

    // Prepare auxiliary method handles used during LambdaForm interpreation.
    // Box arguments and wrap them into Object[]: ValueConversions.array().
    MethodType varargsType = type.changeReturnType(Object[].class);
    MethodHandle collectArgs = varargsArray(type.parameterCount()).asType(varargsType);
    // Result unboxing: ValueConversions.unbox() OR ValueConversions.identity() OR ValueConversions.ignore().
    MethodHandle unboxResult;
    Class<?> rtype = type.returnType();
    if (rtype.isPrimitive()) {
        if (rtype == void.class) {
            unboxResult = ValueConversions.ignore();
        } else {
            Wrapper w = Wrapper.forPrimitiveType(type.returnType());
            unboxResult = ValueConversions.unboxExact(w);
        }
    } else {
        unboxResult = MethodHandles.identity(Object.class);
    }

    BoundMethodHandle.SpeciesData data = BoundMethodHandle.speciesData_LLLLL();
    BoundMethodHandle mh;
    try {
        mh = (BoundMethodHandle)
                data.constructor().invokeBasic(type, form, (Object) target, (Object) exType, (Object) catcher,
                                               (Object) collectArgs, (Object) unboxResult);
    } catch (Throwable ex) {
        throw uncaughtException(ex);
    }
    assert(mh.type() == type);
    return mh;
}
 
Example 15
Source File: MethodHandles.java    From openjdk-jdk8u-backup with GNU General Public License v2.0 5 votes vote down vote up
private static BoundMethodHandle insertArgumentPrimitive(BoundMethodHandle result, int pos,
                                                         Class<?> ptype, Object value) {
    Wrapper w = Wrapper.forPrimitiveType(ptype);
    // perform unboxing and/or primitive conversion
    value = w.convert(value, ptype);
    switch (w) {
    case INT:     return result.bindArgumentI(pos, (int)value);
    case LONG:    return result.bindArgumentJ(pos, (long)value);
    case FLOAT:   return result.bindArgumentF(pos, (float)value);
    case DOUBLE:  return result.bindArgumentD(pos, (double)value);
    default:      return result.bindArgumentI(pos, ValueConversions.widenSubword(value));
    }
}
 
Example 16
Source File: MethodType.java    From hottub with GNU General Public License v2.0 4 votes vote down vote up
static boolean canConvert(Class<?> src, Class<?> dst) {
    // short-circuit a few cases:
    if (src == dst || src == Object.class || dst == Object.class)  return true;
    // the remainder of this logic is documented in MethodHandle.asType
    if (src.isPrimitive()) {
        // can force void to an explicit null, a la reflect.Method.invoke
        // can also force void to a primitive zero, by analogy
        if (src == void.class)  return true;  //or !dst.isPrimitive()?
        Wrapper sw = Wrapper.forPrimitiveType(src);
        if (dst.isPrimitive()) {
            // P->P must widen
            return Wrapper.forPrimitiveType(dst).isConvertibleFrom(sw);
        } else {
            // P->R must box and widen
            return dst.isAssignableFrom(sw.wrapperType());
        }
    } else if (dst.isPrimitive()) {
        // any value can be dropped
        if (dst == void.class)  return true;
        Wrapper dw = Wrapper.forPrimitiveType(dst);
        // R->P must be able to unbox (from a dynamically chosen type) and widen
        // For example:
        //   Byte/Number/Comparable/Object -> dw:Byte -> byte.
        //   Character/Comparable/Object -> dw:Character -> char
        //   Boolean/Comparable/Object -> dw:Boolean -> boolean
        // This means that dw must be cast-compatible with src.
        if (src.isAssignableFrom(dw.wrapperType())) {
            return true;
        }
        // The above does not work if the source reference is strongly typed
        // to a wrapper whose primitive must be widened.  For example:
        //   Byte -> unbox:byte -> short/int/long/float/double
        //   Character -> unbox:char -> int/long/float/double
        if (Wrapper.isWrapperType(src) &&
            dw.isConvertibleFrom(Wrapper.forWrapperType(src))) {
            // can unbox from src and then widen to dst
            return true;
        }
        // We have already covered cases which arise due to runtime unboxing
        // of a reference type which covers several wrapper types:
        //   Object -> cast:Integer -> unbox:int -> long/float/double
        //   Serializable -> cast:Byte -> unbox:byte -> byte/short/int/long/float/double
        // An marginal case is Number -> dw:Character -> char, which would be OK if there were a
        // subclass of Number which wraps a value that can convert to char.
        // Since there is none, we don't need an extra check here to cover char or boolean.
        return false;
    } else {
        // R->R always works, since null is always valid dynamically
        return true;
    }
}
 
Example 17
Source File: MethodType.java    From TencentKona-8 with GNU General Public License v2.0 4 votes vote down vote up
static boolean canConvert(Class<?> src, Class<?> dst) {
    // short-circuit a few cases:
    if (src == dst || src == Object.class || dst == Object.class)  return true;
    // the remainder of this logic is documented in MethodHandle.asType
    if (src.isPrimitive()) {
        // can force void to an explicit null, a la reflect.Method.invoke
        // can also force void to a primitive zero, by analogy
        if (src == void.class)  return true;  //or !dst.isPrimitive()?
        Wrapper sw = Wrapper.forPrimitiveType(src);
        if (dst.isPrimitive()) {
            // P->P must widen
            return Wrapper.forPrimitiveType(dst).isConvertibleFrom(sw);
        } else {
            // P->R must box and widen
            return dst.isAssignableFrom(sw.wrapperType());
        }
    } else if (dst.isPrimitive()) {
        // any value can be dropped
        if (dst == void.class)  return true;
        Wrapper dw = Wrapper.forPrimitiveType(dst);
        // R->P must be able to unbox (from a dynamically chosen type) and widen
        // For example:
        //   Byte/Number/Comparable/Object -> dw:Byte -> byte.
        //   Character/Comparable/Object -> dw:Character -> char
        //   Boolean/Comparable/Object -> dw:Boolean -> boolean
        // This means that dw must be cast-compatible with src.
        if (src.isAssignableFrom(dw.wrapperType())) {
            return true;
        }
        // The above does not work if the source reference is strongly typed
        // to a wrapper whose primitive must be widened.  For example:
        //   Byte -> unbox:byte -> short/int/long/float/double
        //   Character -> unbox:char -> int/long/float/double
        if (Wrapper.isWrapperType(src) &&
            dw.isConvertibleFrom(Wrapper.forWrapperType(src))) {
            // can unbox from src and then widen to dst
            return true;
        }
        // We have already covered cases which arise due to runtime unboxing
        // of a reference type which covers several wrapper types:
        //   Object -> cast:Integer -> unbox:int -> long/float/double
        //   Serializable -> cast:Byte -> unbox:byte -> byte/short/int/long/float/double
        // An marginal case is Number -> dw:Character -> char, which would be OK if there were a
        // subclass of Number which wraps a value that can convert to char.
        // Since there is none, we don't need an extra check here to cover char or boolean.
        return false;
    } else {
        // R->R always works, since null is always valid dynamically
        return true;
    }
}
 
Example 18
Source File: MethodType.java    From openjdk-8-source with GNU General Public License v2.0 4 votes vote down vote up
static boolean canConvert(Class<?> src, Class<?> dst) {
    // short-circuit a few cases:
    if (src == dst || dst == Object.class)  return true;
    // the remainder of this logic is documented in MethodHandle.asType
    if (src.isPrimitive()) {
        // can force void to an explicit null, a la reflect.Method.invoke
        // can also force void to a primitive zero, by analogy
        if (src == void.class)  return true;  //or !dst.isPrimitive()?
        Wrapper sw = Wrapper.forPrimitiveType(src);
        if (dst.isPrimitive()) {
            // P->P must widen
            return Wrapper.forPrimitiveType(dst).isConvertibleFrom(sw);
        } else {
            // P->R must box and widen
            return dst.isAssignableFrom(sw.wrapperType());
        }
    } else if (dst.isPrimitive()) {
        // any value can be dropped
        if (dst == void.class)  return true;
        Wrapper dw = Wrapper.forPrimitiveType(dst);
        // R->P must be able to unbox (from a dynamically chosen type) and widen
        // For example:
        //   Byte/Number/Comparable/Object -> dw:Byte -> byte.
        //   Character/Comparable/Object -> dw:Character -> char
        //   Boolean/Comparable/Object -> dw:Boolean -> boolean
        // This means that dw must be cast-compatible with src.
        if (src.isAssignableFrom(dw.wrapperType())) {
            return true;
        }
        // The above does not work if the source reference is strongly typed
        // to a wrapper whose primitive must be widened.  For example:
        //   Byte -> unbox:byte -> short/int/long/float/double
        //   Character -> unbox:char -> int/long/float/double
        if (Wrapper.isWrapperType(src) &&
            dw.isConvertibleFrom(Wrapper.forWrapperType(src))) {
            // can unbox from src and then widen to dst
            return true;
        }
        // We have already covered cases which arise due to runtime unboxing
        // of a reference type which covers several wrapper types:
        //   Object -> cast:Integer -> unbox:int -> long/float/double
        //   Serializable -> cast:Byte -> unbox:byte -> byte/short/int/long/float/double
        // An marginal case is Number -> dw:Character -> char, which would be OK if there were a
        // subclass of Number which wraps a value that can convert to char.
        // Since there is none, we don't need an extra check here to cover char or boolean.
        return false;
    } else {
        // R->R always works, since null is always valid dynamically
        return true;
    }
}
 
Example 19
Source File: MethodType.java    From openjdk-8 with GNU General Public License v2.0 4 votes vote down vote up
static boolean canConvert(Class<?> src, Class<?> dst) {
    // short-circuit a few cases:
    if (src == dst || dst == Object.class)  return true;
    // the remainder of this logic is documented in MethodHandle.asType
    if (src.isPrimitive()) {
        // can force void to an explicit null, a la reflect.Method.invoke
        // can also force void to a primitive zero, by analogy
        if (src == void.class)  return true;  //or !dst.isPrimitive()?
        Wrapper sw = Wrapper.forPrimitiveType(src);
        if (dst.isPrimitive()) {
            // P->P must widen
            return Wrapper.forPrimitiveType(dst).isConvertibleFrom(sw);
        } else {
            // P->R must box and widen
            return dst.isAssignableFrom(sw.wrapperType());
        }
    } else if (dst.isPrimitive()) {
        // any value can be dropped
        if (dst == void.class)  return true;
        Wrapper dw = Wrapper.forPrimitiveType(dst);
        // R->P must be able to unbox (from a dynamically chosen type) and widen
        // For example:
        //   Byte/Number/Comparable/Object -> dw:Byte -> byte.
        //   Character/Comparable/Object -> dw:Character -> char
        //   Boolean/Comparable/Object -> dw:Boolean -> boolean
        // This means that dw must be cast-compatible with src.
        if (src.isAssignableFrom(dw.wrapperType())) {
            return true;
        }
        // The above does not work if the source reference is strongly typed
        // to a wrapper whose primitive must be widened.  For example:
        //   Byte -> unbox:byte -> short/int/long/float/double
        //   Character -> unbox:char -> int/long/float/double
        if (Wrapper.isWrapperType(src) &&
            dw.isConvertibleFrom(Wrapper.forWrapperType(src))) {
            // can unbox from src and then widen to dst
            return true;
        }
        // We have already covered cases which arise due to runtime unboxing
        // of a reference type which covers several wrapper types:
        //   Object -> cast:Integer -> unbox:int -> long/float/double
        //   Serializable -> cast:Byte -> unbox:byte -> byte/short/int/long/float/double
        // An marginal case is Number -> dw:Character -> char, which would be OK if there were a
        // subclass of Number which wraps a value that can convert to char.
        // Since there is none, we don't need an extra check here to cover char or boolean.
        return false;
    } else {
        // R->R always works, since null is always valid dynamically
        return true;
    }
}
 
Example 20
Source File: MethodHandles.java    From openjdk-8 with GNU General Public License v2.0 3 votes vote down vote up
/**
 * Produces a method handle of the requested return type which returns the given
 * constant value every time it is invoked.
 * <p>
 * Before the method handle is returned, the passed-in value is converted to the requested type.
 * If the requested type is primitive, widening primitive conversions are attempted,
 * else reference conversions are attempted.
 * <p>The returned method handle is equivalent to {@code identity(type).bindTo(value)}.
 * @param type the return type of the desired method handle
 * @param value the value to return
 * @return a method handle of the given return type and no arguments, which always returns the given value
 * @throws NullPointerException if the {@code type} argument is null
 * @throws ClassCastException if the value cannot be converted to the required return type
 * @throws IllegalArgumentException if the given type is {@code void.class}
 */
public static
MethodHandle constant(Class<?> type, Object value) {
    if (type.isPrimitive()) {
        if (type == void.class)
            throw newIllegalArgumentException("void type");
        Wrapper w = Wrapper.forPrimitiveType(type);
        return insertArguments(identity(type), 0, w.convert(value, type));
    } else {
        return identity(type).bindTo(type.cast(value));
    }
}