scala对比java_Scala与Java之间的型变对比

就如之前所说的那样,Scala的型变的行为定义在Scala类型的声明处,而Java则是在调用处. 类型的委托(client)定义型变通常默认是不变类型. Java不允许你在定义处指定型变的行为,尽管你可以使用类似的表达式.这些表达式定义了类型绑定,这些我们待会讨论.

Java的在调用出调用两个大的弊端. 首先,它应该是类库设计者的工作,设计者了解正确的型变行为而且能够编码出和类库本身的行为. 确实会更加类库使用者的负担. 这就导致了第二个弊端. 对于Java使用者来说使用不正确的类型注释是很容易的,由此可能会导致不安全的代码.

在Java类型系统中的另一个问题则是Arrays是协变的,对于每个类型T而言. 考虑下面这个例子.

public class JavaArrays {

public static void main(String[] args) {

Integer[] array1 = new Integer[]{

new Integer(1), new Integer(2), new Integer(3)};

Number[] array2 = array1; // Compiles fine array2[2] = new Double(3.14); // Compiles, but throws a runtime error! }

}

//Exception in thread "main" java.lang.ArrayStoreException: java.lang.Double at//JavaArrays.main(JavaArrays.java:6)

怎么回事?我们之前讨论过,可变及集合必须是不变类型才是安全的.因为Java 数组是协变类型,所以编译器允许吧Array[Integer]实例赋值给Array[Number]引用.然后编译器认为把任意的Number赋值给数组中的元素是Ok的,但是事实上来说,array在 “内部”知道它只接受Integer值(如果可以的话,还有该值的子类型信息),所以它就抛出了运行时异常,破坏了静态类型检查的功能.注意,尽管Scala封装了Java Array类,但是Scala 类Scala.Array是不变类型,所以它就避免了这个 “洞”.

可以看下Maurice Naftalin and Philip Wadler, Java Generics and Collections, O’Reilly Media,2006 这本书关于Java泛型的和数组的详细细节.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值