4、isSameType() 方法
/** * Is t the same type as s? */ public boolean isSameType(Type t, Type s) { return isSameType.visit(t, s); }
会对t为各种类型进行单独判断,下面来具体阐述。
(1)t为Type类型
public Boolean visitType(Type t, Type s) { if (t == s) return true; if (s.tag >= firstPartialTag) return visit(s, t); switch (t.tag) { case BYTE: case CHAR: case SHORT: case INT: case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID: case BOT: case NONE: return t.tag == s.tag; case TYPEVAR: { if (s.tag == TYPEVAR) { //type-substitution does not preserve type-var types //check that type var symbols and bounds are indeed the same return t.tsym == s.tsym && visit(t.getUpperBound(), s.getUpperBound()); } else { //special case for s == ? super X, where upper(s) = u //check that u == t, where u has been set by Type.withTypeVar return s.isSuperBound() && !s.isExtendsBound() && // 这样可以确保为 ? super X 而不是? visit(t, upperBound(s)); // 判断t是否为upperBound(s)的子类 } } default: throw new AssertionError("isSameType " + t.tag); } }
(2)t为visitClassType类型
@Override public Boolean visitClassType(ClassType t, Type s) { if (t == s) return true; if (s.tag >= firstPartialTag) return visit(s, t); if (s.isSuperBound() && !s.isExtendsBound()) return visit(t, upperBound(s)) && visit(t, lowerBound(s)); if (t.isCompound() && s.isCompound()) { if (!visit(supertype(t), supertype(s))) return false; HashSet<SingletonType> set = new HashSet<SingletonType>(); for (Type x : interfaces(t)) set.add(new SingletonType(x)); for (Type x : interfaces(s)) { if (!set.remove(new SingletonType(x))) return false; } return (set.isEmpty()); } return t.tsym == s.tsym && visit(t.getEnclosingType(), s.getEnclosingType()) && containsTypeEquivalent(t.getTypeArguments(), s.getTypeArguments()); }
(2)t为visitArrayType类型
@Override public Boolean visitArrayType(ArrayType t, Type s) { if (t == s) return true; if (s.tag >= firstPartialTag) return visit(s, t); return s.tag == ARRAY && containsTypeEquivalent(t.elemtype, elemtype(s)); }
(3)t为visitForAll类型
@Override public Boolean visitForAll(ForAll t, Type s) { if (s.tag != FORALL) return false; ForAll forAll = (ForAll)s; return hasSameBounds(t, forAll) && visit(t.qtype, subst(forAll.qtype, forAll.tvars, t.tvars)); }
(4)t为visitUndetVar类型
@Override public Boolean visitUndetVar(UndetVar t, Type s) { if (s.tag == WILDCARD) // FIXME, this might be leftovers from before capture conversion return false; if (t == s || t.qtype == s || s.tag == ERROR || s.tag == UNKNOWN) return true; if (t.inst != null) return visit(t.inst, s); t.inst = fromUnknownFun.apply(s); for (List<Type> l = t.lobounds; l.nonEmpty(); l = l.tail) { if (!isSubtype(l.head, t.inst)) return false; } for (List<Type> l = t.hibounds; l.nonEmpty(); l = l.tail) { if (!isSubtype(t.inst, l.head)) return false; } return true; }
(5)others