以前没觉得java的类型系统有什么问题. 不过就两条机制在,box/unbox的问题而已. 当然,接触java的时间不算久,所以没有经历过那段没有autobox的日子. 不过,从一些例子看来,autobox也未必是好事情. 比如这段代码int n = 0; int another = int.class.cast(n);
从表面上看来,这应该是一段很符合表面语义的代码. 一个类型转换,而且应该是没什么问题的. 只是,由于cast的函数声明参数是一个Object. 而在java里,primitive和object是两套类型系统. 在java引入autobox之前,这段代码应该是会编译错误的. 但是,有了autobox之后,没有编译错误,但是肯定会有运行错误. 在调用的时候,java隐式地将int box成java.lang.Integer. 想想,既然有autobox,那么应该也问题不大. 最多返回Integer之后,再unbox隐式转换回int. 但问题是,cast做了一些类型兼容的检测. 从jvm的角度来说,int和Integer是两个不兼容的类型. 于是,在调用cast的时候,会抛一个ClassCastException. 也就是说,在java两套类型系统存在的前提下, primitive.class.cast()的行为就变得有些古怪了. 一些语义上看上去无误的代码,也许运行时就必然要抛异常. 当然,对于这类可以显式调用的也许可以避免. 但程序复杂了就难免会有这样那样的trick/trap. 比如:void
这段代码. 初看上去似乎还行.实现了某种程度的模板/复用. 但是,注意那个cast. 所以,很难保证在实际情况下不会出现这种box/unbox带来的cast的问题. 于是,解决方案就是尽量避免使用cast做转型,或者时刻记住box/unbox的问题. 问题是,如果不用cast转型就要自己写个检测null的东西了. 这当然不是什么大问题. 最好的方法估计还是统一一下类型系统吧. 做接口的时候也许最好是使用非primitive的类型吧. 这样或许能够避免一些问题. 虽然在诸如做序列化的时候,非primitive类型会有一些额外开销. 不过,真要做序列化的话,这些开销也是可以避免的. 比如,最直接的一堆if,else做对应的类型映射. 总而言之,java的两个类型系统是个头疼的存在. 不仅存在陷阱,还使得在做reflect的时候经常让人崩溃. 在这方面,后来者C#做得貌似就好得多了. 比较,Java老了. 语言这东西,也许不是说年代越久越成熟. 毕竟,需要解决的总是新问题.Type method(Class type){ .... return type.class.cast(value); }
2010-12-05
Java Class.cast的问题
订阅:
博文评论 (Atom)
瑕不掩瑜
新加坡哪吒2终于上映了. 也终于有机会去看了. 客观地说, 剧本应该是还算可以的.但是叙事成熟度还是不太够. 虽然哪吒二阶重生的片段确实很打动人,但切割开来看的话,缺少一个比较明显的叙事主线. 或者说在剧情长短安排上还是有些不太平衡. 像第一关的土拨鼠. 作为一个单元片段放出来算...
-
最近尝试了下海淘. 当然,方向上来说是从国内到新加坡. 先是买了个iPhone,算上运费和双重征税,到手比官方还是便宜个一两百新的. 换算回来也不多事10%的纯粹价格因素差异. 当然,之类有电商促销的因素. 也有比较基准是新加坡Apple Store售价的原因. 但如果同样比较A...
-
最近在改一个SparkSQL AST解析相关的问题. 主要做一些权限管控校验重写的事情. 之前做过一版重写,现在反馈了几个问题. 一个是类似delete from table where子句的错漏. 一个是select from where not exists in (subq...
-
最近算跟风玩了下黑神话. 用的Geforce Now加月卡. 勉强到第二回打完沙国父子,回头准备去打地狼吧,然后20小时优先卡就被踢出去了. 难度对于个人这种没接触过的玩家来说还是挺大的. 一个Boss花个三四个小时很常见,或者说必然吧. 像第一个头目幽魂就卡了挺久. 后来学会拆...
没有评论:
发表评论