以前没觉得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)
反之亦然
最近看到一个冲绳独立的慕容复策略. 于是稍微查了下,感觉还蛮有意思的. 它的法理依据是旧金山和约中将冲绳置于联合国托管领土框架内. 这个框架的设定主要是为了解决殖民地问题. 传统意义的二战主要限定在欧洲战场. 太平洋战场从西方认知上来说,并不太属于第二次世界大战的范围. 所以狭义...
-
下午查了下关于仿制药的一点东西. 首先是关于一致性定义的相关文件. 简单的Google一般会指向NMPA/国家药监局的一些关于 化学药品注射剂仿制药质量和疗效一致性评价技术要求 的相关政策公告或者是更早期一些的关于这个文件起草意见稿. 一般理解的西药就是指化学药品. 这个文件本...
-
看完了一部未完成的电影. 这部片片子比较有意思的是一开始那段自嘲. 秦昊关于既然拍了也播不了,只是私下小圈子里自嗨的事情又什么意义的质问. 片里导演也 讪讪地承认生活的现实. 到这里其实沿着原有的思路,把补拍和一些意外穿插进去,可能还是一个不错的文艺片. 至少于戏里戏外的导演来说...
-
最近在补觉醒年代,发觉有几点细节蛮有意思的. 或者蛮值得把玩的. 一个是新青年单价2毛多. 按照0.2银元理解的话,相当于现在什么概念呢? Gemini给的人均年收入数据在5-30银元的区间,因沿海和地区已经行业属性而不同. 按30银元年收入等价现在6k月社平工资换算的话,大概一...
没有评论:
发表评论