Method from sun.invoke.util.Wrapper Detail: |
public Class<?> arrayType() {
return emptyArray.getClass();
}
|
public static Class<T> asPrimitiveType(Class<T> type) {
Wrapper w = findWrapperType(type);
if (w != null) {
return forceType(w.primitiveType(), type);
}
return type;
}
If {@code type} is a wrapper type, return the corresponding
primitive type, else return {@code type} unchanged. |
public static Class<T> asWrapperType(Class<T> type) {
if (type.isPrimitive()) {
return forPrimitiveType(type).wrapperType(type);
}
return type;
}
If {@code type} is a primitive type, return the corresponding
wrapper type, else return {@code type} unchanged. |
public char basicTypeChar() {
return basicTypeChar;
}
What is the bytecode signature character for this wrapper's
primitive type? |
public static char basicTypeChar(Class<?> type) {
if (!type.isPrimitive())
return 'L';
else
return forPrimitiveType(type).basicTypeChar();
}
What is the bytecode signature character for this type?
All non-primitives, including array types, report as 'L', the signature character for references. |
public int bitWidth() {
return (format > > Format.SIZE_SHIFT) & Format.SIZE_MASK;
}
How many bits are in the wrapped value? Returns 0 for OBJECT or VOID. |
public T cast(Object x,
Class<T> type) {
return convert(x, type, true);
}
Cast a wrapped value to the given type, which may be either a primitive or wrapper type.
The given target type must be this wrapper's primitive or wrapper type.
If this wrapper is OBJECT, the target type may also be an interface, perform no runtime check.
Performs standard primitive conversions, including truncation and float conversions.
The given type must be compatible with this wrapper. That is, it must either
be the wrapper type (or a subtype, in the case of {@code OBJECT}) or else
it must be the wrapper's primitive type.
Primitive conversions are only performed if the given type is itself a primitive. |
public T convert(Object x,
Class<T> type) {
return convert(x, type, false);
}
Convert a wrapped value to the given type.
The given target type must be this wrapper's primitive or wrapper type.
This is equivalent to #cast , except that it refuses to perform
narrowing primitive conversions. |
public void copyArrayBoxing(Object a,
int apos,
Object[] values,
int vpos,
int length) {
if (a.getClass() != arrayType())
arrayType().cast(a); // throw NPE or CCE if bad type
for (int i = 0; i < length; i++) {
Object value = java.lang.reflect.Array.get(a, i+apos);
//Already done: value = convert(value, primitiveType);
assert(value.getClass() == wrapperType);
values[i+vpos] = value;
}
}
|
public void copyArrayUnboxing(Object[] values,
int vpos,
Object a,
int apos,
int length) {
if (a.getClass() != arrayType())
arrayType().cast(a); // throw NPE or CCE if bad type
for (int i = 0; i < length; i++) {
Object value = values[i+vpos];
value = convert(value, primitiveType);
java.lang.reflect.Array.set(a, i+apos, value);
}
}
|
public String detailString() {
return simpleName+
java.util.Arrays.asList(wrapperType, primitiveType,
basicTypeChar, zero,
"0x"+Integer.toHexString(format));
}
For debugging, give the details of this wrapper. |
static Wrapper findPrimitiveType(Class<?> type) {
Wrapper w = FROM_PRIM[hashPrim(type)];
if (w != null && w.primitiveType == type) {
return w;
}
return null;
}
|
static Wrapper findWrapperType(Class<?> type) {
Wrapper w = FROM_WRAP[hashWrap(type)];
if (w != null && w.wrapperType == type) {
return w;
}
return null;
}
|
public static Wrapper forBasicType(char type) {
Wrapper w = FROM_CHAR[hashChar(type)];
if (w != null && w.basicTypeChar == type) {
return w;
}
for (Wrapper x : values())
if (w.basicTypeChar == type)
throw new InternalError(); // redo hash function
throw newIllegalArgumentException("not basic type char: "+type);
}
Return the wrapper that corresponds to the given bytecode
signature character. Return {@code OBJECT} for the character 'L'. |
public static Wrapper forBasicType(Class<?> type) {
if (type.isPrimitive())
return forPrimitiveType(type);
return OBJECT; // any reference, including wrappers or arrays
}
Return the wrapper for the given type, if it is
a primitive type, else return {@code OBJECT}. |
public static Wrapper forPrimitiveType(Class<?> type) {
Wrapper w = findPrimitiveType(type);
if (w != null) return w;
if (type.isPrimitive())
throw new InternalError(); // redo hash function
throw newIllegalArgumentException("not primitive: "+type);
}
Return the wrapper that wraps values of the given type.
The type may be {@code Object}, meaning the {@code OBJECT} wrapper.
Otherwise, the type must be a primitive. |
public static Wrapper forWrapperType(Class<?> type) {
Wrapper w = findWrapperType(type);
if (w != null) return w;
for (Wrapper x : values())
if (x.wrapperType == type)
throw new InternalError(); // redo hash function
throw newIllegalArgumentException("not wrapper: "+type);
}
Return the wrapper that wraps values into the given wrapper type.
If it is {@code Object}, return {@code OBJECT}.
Otherwise, it must be a wrapper type.
The type must not be a primitive type. |
static Class<T> forceType(Class<?> type,
Class<T> exampleType) {
boolean z = (type == exampleType ||
type.isPrimitive() && forPrimitiveType(type) == findWrapperType(exampleType) ||
exampleType.isPrimitive() && forPrimitiveType(exampleType) == findWrapperType(type) ||
type == Object.class && !exampleType.isPrimitive());
if (!z)
System.out.println(type+" < = "+exampleType);
assert(type == exampleType ||
type.isPrimitive() && forPrimitiveType(type) == findWrapperType(exampleType) ||
exampleType.isPrimitive() && forPrimitiveType(exampleType) == findWrapperType(type) ||
type == Object.class && !exampleType.isPrimitive());
@SuppressWarnings("unchecked")
Class< T > result = (Class< T >) type; // unchecked warning is expected here
return result;
}
Cast a reference type to another reference type.
If the target type is an interface, perform no runtime check.
(This loophole is safe, and is allowed by the JVM verifier.)
If the target type is a primitive, change it to a wrapper. |
public boolean isConvertibleFrom(Wrapper source) {
if (this == source) return true;
if (this.compareTo(source) < 0) {
// At best, this is a narrowing conversion.
return false;
}
// All conversions are allowed in the enum order between floats and signed ints.
// First detect non-signed non-float types (boolean, char, Object, void).
boolean floatOrSigned = (((this.format & source.format) & Format.SIGNED) != 0);
if (!floatOrSigned) {
if (this.isOther()) return true;
// can convert char to int or wider, but nothing else
if (source.format == Format.CHAR) return true;
// no other conversions are classified as widening
return false;
}
// All signed and float conversions in the enum order are widening.
assert(this.isFloating() || this.isSigned());
assert(source.isFloating() || source.isSigned());
return true;
}
Does the JLS 5.1.2 allow a variable of this wrapper's
primitive type to be assigned from a value of the given wrapper's primitive type?
Cases:
- unboxing followed by widening primitive conversion
- any type converted to {@code void} (i.e., dropping a method call's value)
- boxing conversion followed by widening reference conversion to {@code Object}
These are the cases allowed by MethodHandle.asType. |
public boolean isDoubleWord() {
return (format & (2 < < Format.SLOT_SHIFT)) != 0;
}
Does the wrapped value occupy two JVM stack slots? |
public boolean isFloating() {
return format >= Format.FLOAT;
}
Is the wrapped type either float or double? |
public boolean isIntegral() {
return isNumeric() && format < Format.FLOAT;
}
Is the wrapped type a primitive other than float, double, or void? |
public boolean isNumeric() {
return (format & Format.NUM_MASK) != 0;
}
Is the wrapped type numeric (not void or object)? |
public boolean isOther() {
return (format & ~Format.SLOT_MASK) == 0;
}
Is the wrapped type either void or a reference? |
public static boolean isPrimitiveType(Class<?> type) {
return type.isPrimitive();
}
Query: Is the given type a primitive, such as {@code int} or {@code void}? |
public boolean isSigned() {
return format < Format.VOID;
}
|
public boolean isSingleWord() {
return (format & (1 < < Format.SLOT_SHIFT)) != 0;
}
Does the wrapped value occupy a single JVM stack slot? |
public boolean isSubwordOrInt() {
return isIntegral() && isSingleWord();
}
Is the wrapped type one of int, boolean, byte, char, or short? |
public boolean isUnsigned() {
return format >= Format.BOOLEAN && format < Format.FLOAT;
}
|
public static boolean isWrapperType(Class<?> type) {
return findWrapperType(type) != null;
}
Query: Is the given type a wrapper, such as {@code Integer} or {@code Void}? |
public Object makeArray(int len) {
return java.lang.reflect.Array.newInstance(primitiveType, len);
}
|
public Class<?> primitiveType() {
return primitiveType;
}
What is the primitive type wrapped by this wrapper? |
public Wrapper rawPrimitive() {
switch (basicTypeChar) {
case 'S': case 'B':
case 'C': case 'Z':
case 'V':
case 'F':
return INT;
case 'D':
return LONG;
}
return this;
}
Report, as a wrapper, what primitive type holds this guy's raw value.
Returns self for INT, LONG, OBJECT; returns LONG for DOUBLE,
else returns INT. |
public Class<?> rawPrimitiveType() {
return rawPrimitive().primitiveType();
}
Report what primitive type holds this guy's raw value. |
public String simpleName() {
return simpleName;
}
What is the simple name of the wrapper type? |
public int stackSlots() {
return (format > > Format.SLOT_SHIFT) & Format.SLOT_MASK;
}
How many JVM stack slots occupied by the wrapped value? Returns 0 for VOID. |
public long unwrapRaw(Object x) {
switch (basicTypeChar) {
case 'F': return Float.floatToRawIntBits((Float) x);
case 'D': return Double.doubleToRawLongBits((Double) x);
case 'L': throw newIllegalArgumentException("cannot unwrap from sobject type");
case 'V': return 0;
case 'I': return (int)(Integer) x;
case 'J': return (long)(Long) x;
case 'S': return (short)(Short) x;
case 'B': return (byte)(Byte) x;
case 'C': return (char)(Character) x;
case 'Z': return (boolean)(Boolean) x ? 1 : 0;
}
throw new InternalError("bad wrapper");
}
Produce bitwise value which encodes the given wrapped value.
Does not perform floating point conversion.
Returns zero for {@code VOID}. |
public Object wrap(Object x) {
// do non-numeric wrappers first
switch (basicTypeChar) {
case 'L': return x;
case 'V': return null;
}
Number xn = numberValue(x);
switch (basicTypeChar) {
case 'I': return Integer.valueOf(xn.intValue());
case 'J': return Long.valueOf(xn.longValue());
case 'F': return Float.valueOf(xn.floatValue());
case 'D': return Double.valueOf(xn.doubleValue());
case 'S': return Short.valueOf((short) xn.intValue());
case 'B': return Byte.valueOf((byte) xn.intValue());
case 'C': return Character.valueOf((char) xn.intValue());
case 'Z': return Boolean.valueOf(boolValue(xn.longValue()));
}
throw new InternalError("bad wrapper");
}
Wrap a value in this wrapper's type.
Performs standard primitive conversions, including truncation and float conversions.
Performs returns the unchanged reference for {@code OBJECT}.
Returns null for {@code VOID}.
Returns a zero value for a null input. |
public Object wrap(int x) {
if (basicTypeChar == 'L') return (Integer)x;
switch (basicTypeChar) {
case 'L': throw newIllegalArgumentException("cannot wrap to object type");
case 'V': return null;
case 'I': return Integer.valueOf((int)x);
case 'J': return Long.valueOf(x);
case 'F': return Float.valueOf(x);
case 'D': return Double.valueOf(x);
case 'S': return Short.valueOf((short) x);
case 'B': return Byte.valueOf((byte) x);
case 'C': return Character.valueOf((char) x);
case 'Z': return Boolean.valueOf(boolValue(x));
}
throw new InternalError("bad wrapper");
}
Wrap a value (an int or smaller value) in this wrapper's type.
Performs standard primitive conversions, including truncation and float conversions.
Produces an {@code Integer} for {@code OBJECT}, although the exact type
of the operand is not known.
Returns null for {@code VOID}. |
public Object wrapRaw(long x) {
switch (basicTypeChar) {
case 'F': return Float.valueOf(Float.intBitsToFloat((int)x));
case 'D': return Double.valueOf(Double.longBitsToDouble(x));
case 'L': // same as 'J':
case 'J': return (Long) x;
}
// Other wrapping operations are just the same, given that the
// operand is already promoted to an int.
return wrap((int)x);
}
Wrap a value (a long or smaller value) in this wrapper's type.
Does not perform floating point conversion.
Produces a {@code Long} for {@code OBJECT}, although the exact type
of the operand is not known.
Returns null for {@code VOID}. |
public Class<?> wrapperType() {
return wrapperType;
}
What is the wrapper type for this wrapper? |
public Class<T> wrapperType(Class<T> exampleType) {
if (exampleType == wrapperType) {
return exampleType;
} else if (exampleType == primitiveType ||
wrapperType == Object.class ||
exampleType.isInterface()) {
return forceType(wrapperType, exampleType);
}
throw newClassCastException(exampleType, primitiveType);
}
What is the wrapper type for this wrapper?
Otherwise, the example type must be the wrapper type,
or the corresponding primitive type.
(For {@code OBJECT}, the example type can be any non-primitive,
and is normalized to {@code Object.class}.)
The resulting class type has the same type parameter. |
public Object zero() {
return zero;
}
Produce a zero value for the given wrapper type.
This will be a numeric zero for a number or character,
false for a boolean, and null for a reference or void.
The common thread is that this is what is contained
in a default-initialized variable of the given primitive
type. (For void, it is what a reflective method returns
instead of no value at all.) |
public T zero(Class<T> type) {
return convert(zero, type);
}
Produce a zero value for the given wrapper type T.
The optional argument must a type compatible with this wrapper.
Equivalent to {@code this.cast(this.zero(), type)}. |