Types方法之isCastable-isConvertible
阿新 • • 發佈:2017-10-02
ner types sig unbox byte span motion all 子類
5. Conversions and Promotions
- 5.1. Kinds of Conversion
- 5.1.1. Identity Conversion
- 5.1.2. Widening Primitive Conversion
- 5.1.3. Narrowing Primitive Conversion
- 5.1.4. Widening and Narrowing Primitive Conversion
- 5.1.5. Widening Reference Conversion
- 5.1.6. Narrowing Reference Conversion
- 5.1.7. Boxing Conversion
- 5.1.8. Unboxing Conversion
- 5.1.9. Unchecked Conversion
- 5.1.10. Capture Conversion
- 5.1.11. String Conversion
- 5.1.12. Forbidden Conversions
- 5.1.13. Value Set Conversion
- 5.2. Assignment Conversion
- 5.3. Method Invocation Conversion
- 5.4. String Conversion
- 5.5. Casting Conversion
- 5.5.1. Reference Type Casting
- 5.5.2. Checked Casts and Unchecked Casts
- 5.5.3. Checked Casts at Run Time
- 5.6. Numeric Promotions
- 5.6.1. Unary Numeric Promotion
- 5.6.2. Binary Numeric Promotion
/** * Is t a subtype of or convertible via boxing/unboxing conversion to s? */ public boolean isConvertible(Type t, Type s, Warner warn) { if (t.tag == ERROR) return true; boolean tPrimitive = t.isPrimitive(); boolean sPrimitive = s.isPrimitive(); if (tPrimitive == sPrimitive) { return isSubtypeUnchecked(t, s, warn); } if (!allowBoxing) return false; return tPrimitive ? isSubtype(boxedClass(t).type, s) : isSubtype(unboxedType(t), s); }
當兩個類型相同時(同時為原始類型或引用類型)通過調用isSubtypeUnchecked()方法來進一步判斷。
/**
* Is t an unchecked subtype of s?
*/
public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) {
boolean result = isSubtypeUncheckedInternal(t, s, warn);
if (result) {
checkUnsafeVarargsConversion(t, s, warn);
}
return result;
}
在如上方法中涉及到兩個重要的方法isSubtypeUncheckedInternal()與checkUnsafeVarargsConversion(),不過優先調用前一個方法,如果是Unchecked Subtype關系,則需要檢查是否為Unsafe Varargs Conversion。
private boolean isSubtypeUncheckedInternal(Type t, Type s, Warner warn) {
if (t.tag == ARRAY && s.tag == ARRAY) {
if (((ArrayType)t).elemtype.tag <= lastBaseTag) {
return isSameType(elemtype(t), elemtype(s));
} else {
return isSubtypeUnchecked(elemtype(t), elemtype(s), warn);
}
} else if (isSubtype(t, s)) {
return true;
}
else if (t.tag == TYPEVAR) {
return isSubtypeUnchecked(t.getUpperBound(), s, warn);
}
else if (s.tag == UNDETVAR) {
UndetVar uv = (UndetVar)s;
if (uv.inst != null)
return isSubtypeUnchecked(t, uv.inst, warn);
}
else if (!s.isRaw()) {
Type t2 = asSuper(t, s.tsym);
if (t2 != null && t2.isRaw()) {
if (isReifiable(s))
warn.silentWarn(LintCategory.UNCHECKED);
else
warn.warn(LintCategory.UNCHECKED);
return true;
}
}
return false;
}
當兩個類型是數組類型時,並且是原始數組類型時,則數組類型的元素類型必須相同,也就是byte[]與int[]沒有父子類關系,如下代碼會報錯:
byte[] x = new byte[10];
int[] y = (int[])x;
/**
* Is t is castable to s?
* s is assumed to be an erased type.
* (not defined for Method and ForAll types).
*/
public boolean isCastable(Type t, Type s, Warner warn) {
if (t == s)
return true;
if (t.isPrimitive() != s.isPrimitive())
return allowBoxing && (
isConvertible(t, s, warn) ||
(
allowObjectToPrimitiveCast &&
s.isPrimitive() &&
isSubtype(boxedClass(s).type, t)
)
);
if (warn != warnStack.head) {
try {
warnStack = warnStack.prepend(warn);
checkUnsafeVarargsConversion(t, s, warn);
return isCastable.visit(t,s);
} finally {
warnStack = warnStack.tail;
}
} else {
return isCastable.visit(t,s);
}
}
Types方法之isCastable-isConvertible