Types方法之isSameType-isSuperType-isSubType
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
Types方法之isSameType-isSuperType-isSubType的更多相关文章
- Types方法之upperBound-lowerBound-isUnbounded-containsType
1.upperBound(Type t)方法 /** * The "rvalue conversion". * The upper bound of most types is t ...
- Types方法之isCastable-isConvertible
5. Conversions and Promotions 5.1. Kinds of Conversion 5.1.1. Identity Conversion 5.1.2. Widening Pr ...
- runtime第三部分方法和消息
接上一篇http://www.cnblogs.com/ddavidXu/p/5924049.html 转载来源http://www.jianshu.com/p/6b905584f536 http:// ...
- Runtime 动态加载方法
动态加载 #import"ViewController.h" #import"Person.h" @interfaceViewController() @end ...
- Objective-C Runtime 运行时之三:方法与消息
基础数据类型 SEL SEL又叫选择器,是表示一个方法的selector的指针,其定义如下: typedef struct objc_selector *SEL; objc_selector结构体的详 ...
- Objective-C Runtime 运行时之三:方法与消息(转载)
前面我们讨论了Runtime中对类和对象的处理,及对成员变量与属性的处理.这一章,我们就要开始讨论Runtime中最有意思的一部分:消息处理机制.我们将详细讨论消息的发送及消息的转发.不过在讨论消息之 ...
- iOS运行时使用(动态添加方法)
1 举例 我们实现一个Person类 然后Person 其实是没得对象方法eat:的 下面调用person的eat方法 程序是会奔溃的 那么需要借助运行时动态的添加方法 Person *p = [[ ...
- 快速上手Runtime(四)之动态添加方法
如果一个类方法非常多,加载类到内存的时候也比较耗费资源,可以使用动态给某个类,添加方法解决.做到优化内存,节省资源的效果. // // Person.m // ResolveInstanceMetho ...
- iOS---runtime介绍
本文目录 1.Runtime简介 2.Runtime相关的头文件 3.技术点和应用场景 3_1.获取属性\成员变量列表 3_2.交换方法实现 3_3.类\对象的关联对象,假属性 3_4.动态添加方法, ...
随机推荐
- 微信小程序Wepy框架的三个事件交互($broadcast,$emit,$invoke)
$broadcast: $broadcast事件是由父组件发起,所有子组件都会收到此广播事件,除非事件被手动取消.事件广播的顺序为广度优先搜索顺序,如上图,如果页面Page_Index发起一个$bro ...
- Oracle EBS Standard Package Function Add User & Resp
Oracle EBS Standard Package Function Add User & Resp. fnd_user_pkg.CreateUser; fnd_user_pkg.AddR ...
- 使用Docker部署ASP.NET Core应用程序实践
前言 最近把很火的Docker给看了,于是就磨拳擦掌要去实践一下.于是就拿之前一个aps.net core的项目(已被停止)去练手.该项目之前在ubuntu14.04上确保可以正常运行,所以docke ...
- MySQL 笔记整理(20) --幻读是什么,幻读有什么问题?
笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 20) --幻读是什么,幻读有什么问题? 我们先来看看表结构和初始化数据 ...
- Oracle索引技术研究
Oracle索引类型 B树索引 特定类型索引 确定索引列 主键和唯一键值列的索引 外键索引 其他合适的索引列 B树索引 B树索引算法 B树是指B-tree(Balanced Tree),B树的存在是为 ...
- 网页方式访问 QQ 小说书架
iPad.平板电脑 http://bookshelf.html5.qq.com/page?t=pad#!/bookshelf/ iPhone.手机 http://bookshelf.html5.qq. ...
- angular 响应式表单指令
响应式表单都是以 form开头的指令 第一列指令(不以name结尾)在html模版中,用 [ ] 第二列指令(以name结尾)在html模版中,不用 [ ]
- C#之工厂
工厂在我看来分为三种分别都是简单工厂,工厂方法,和抽象工厂,这三种都是将使用和创建分开的一种模式 接下来我来介绍一下我理解的简单工厂模式: 在平时我们需要使用生产对象的一个类当我们需要new 一个对象 ...
- 使用sn.exe为程序集签名
前言 在写上一篇随笔时,为理解EF事务底层的原理,我去Github上把EF的源码下载放到自己项目调试,不过在编译时遇到了下面这个报错信息.经过一番查阅,了解到了程序集签名(也称强名称签名)的概念.报错 ...
- Spring @SCHEDULED(CRON = "0 0 * * * ?")实现定时任务
Spring配置文件xmlns加入 xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocati ...