java expandoobject_C#在JVM上实现的可行性?

著作权归作者所有。

商业转载请联系作者获得授权,非商业转载请注明出处。

作者:赵劼JVM上目前已经有许多语言了:JRuby,Jython;还有一些特定于JVM平台的语言,如Scala和Groovy等等。但是,为什么JVM上没有C#语言呢?按理说,这门和Java十分相似,却又强大许多的语言更容易被Java程序员接受才对。您可能会说,Sun和微软是对头,怎么可能将C#移植到JVM平台上呢?嗯,有道理,但是为什么社区里也没有人这么做呢(要知道JVM上其他语言都是由社区发起的)?其实在我看来,这还是受到了技术方面的限制。

泛型是Java和C#语言的重要特性,它使得程序员可以方便地进行类型安全的编程,而不需要像以前那样不断进行类型转换。例如,我们要在Java中写一个泛型字典的封装便可以这么做:

public class DictWrapper {

private HashMap m_container = new HashMap();

public V get(K key) {

return this.m_container.get(key);

}

public void put(K key, V value) {

this.m_container.put(key, value);

}

}

看上去和C#并没有什么区别,不是吗?不过,如果我们观察编译后生成的bytecode(类似于.NET平台上的IL),便会发现一丝奇妙之处。

那么,Java和C#两种泛型实现方式分别有什么优势和劣势呢?Java这种Type Erasure做法,最大的优势便在于其兼容性:即便使用了泛型,但最后生成的二进制文件也可以运行在泛型出现之前的JVM上(甚至JDK中不需要添加额外的类库)——因为这里的泛型根本不涉及JVM的变化。而.NET中的泛型需要CLR方面的“新能力”。而CLR实现方式的优势,便在于可以在运行期间体现出“模板化”的优势。.NET程序员都知道,泛型可以节省值类型的装箱和拆箱的开销,即便是引用类型也可以避免额外的类型转化,这些都能带来性能上的提高。

因此,在.NET社区经常会把Java的这种实现方式称之为“假泛型”,而同时也会有人反驳到:泛型本来就是语言上的概念,实现不同又有什么关系,凭什么说是“假”的呢?其实,由于失去了JVM的支持,一些.NET平台上常用的,非常有效的开发方式都难以运用在Java上。例如所谓的泛型字典:

public class Cache

{

public static TValue Instance;

}

public class Factory

{

public static string Create()

{

if (Cache.Instance == null)

{

Cache.Instance = // some expensive computation

}

return Cache.Instance;

}

}

由于Cache在运行时是个具体独立的类型,因此泛型字典是性能最高的存储方式,比O(1)时间复杂度的哈希表还要高出许多。如果说这也只是运行方面的优势,那么这段代码中的“泛型工厂”代码(即Factory.Create(),包括类似的Factory.Create()这种)则是Java语言中无法实现的。这是因为Type Erasure的作用,在运行时JVM已经丧失了TKey这样的类型信息,而在.NET平台上,TKey则是Create签名的组成部分。

猜猜看,如果value变量是个HashMap[Int, Object]类型的对象,上面的代码会输出什么结果呢?如果是C#或是F#这样运行在.NET平台上的语言,最终输出的一定是“Value is not ...”。只可惜,由于JVM的Type Erasure特性,以上代码输出的却是“Value is HashMap[String, Int]”。这是因为在运行期间JVM并不包含泛型的类型信息,HashMap[K, V]即是HashMap,无论HashMap[String, Int]还是HashMap[Int, Object]都是HashMap,JVM无法判断不同泛型类型的集合之间有什么区别。不过还好,Scala编译器遇到这种情况会发出警告,程序员可以了解这些代码可能会出现的“误会”。

因此,为什么有http://IKVM.NET这样的项目可以将Java语言编译成.NET程序集(也可以将Java的jar包转化成.NET程序集),却没有项目将C#编译到JVM上(或是将C#程序集转化为jar包)。这是因为,JVM不足以支撑C#语言所需要的所有特性。而从运行时的中间代码角度来说,JVM 的子集——又有什么办法可以将超集塞入它的子集呢?

此外,如CLR的值类型可能也很难直接落实在JVM上,这也是JVM上运行C#的又一阻碍。由于这些因素存在,我想如F#这样的.NET语言也几乎不可能出现在JVM上了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值