精灵巫婆 发表于 2015-1-18 11:32:07

JAVA网站制作之为何JVM上没有C#言语?浅谈Java言语的Type Erasure特征仓酷云

还是要自己一点一点写代码,然后编译,改错再编译好那。还有最重要的是.net网页编程的编译环境非常好,你甚是不需要了解太多工具,对于简单的系统,你可以之了解一些语法就哦了。每次提到言语的时分我老是不由得骂Java是一学生产力低下,抱残守缺的言语——这估量要一向比及Java言语被JVM上的其他言语代替以后吧。JVM上今朝已有很多言语了:JRuby,Jython;另有一些特定于JVM平台的言语,如Scala和Groovy等等。可是,为何JVM上没有C#言语呢?按理说,这门和Java非常类似,却又壮大很多的言语更简单被Java程序员承受才对。您大概会说,Sun和微软是仇人,怎样大概将C#移植到JVM平台上呢?嗯,有事理,可是为何社区里也没有人这么做呢(要晓得JVM上其他言语都是由社区倡议的)?实在在我看来,这仍是遭到了手艺方面的限定。
泛型是Java和C#言语的主要特征,它使得程序员能够便利地举行范例平安的编程,而不必要像之前那样不休举行范例转换。比方,我们要在Java中写一个泛型字典的封装即可以这么做:
publicclassDictWrapper{privateHashMap<K,V>m_container=newHashMap<K,V>();publicVget(Kkey){returnthis.m_container.get(key);}publicvoidput(Kkey,Vvalue){this.m_container.put(key,value);}}看上往和C#并没有甚么区分,不是吗?不外,假如我们察看编译后天生的bytecode(相似于.NET平台上的IL),便会发明一丝奇奥的地方。利用javap-cDictWrapper失掉的了局是:
Compiledfrom"DictWrapper.java"publicclassjeffz.practices.DictWrapperextendsjava.lang.Object{publicjeffz.practices.DictWrapper();Code:0:        aload_01:        invokespecial        #1;//Methodjava/lang/Object."<init>":()V4:        aload_05:        new        #2;//classjava/util/HashMap8:        dup9:        invokespecial        #3;//Methodjava/util/HashMap."<init>":()V12:        putfield        #4;//Fieldm_container:Ljava/util/HashMap;15:        returnpublicjava.lang.Objectget(java.lang.Object);Code:0:        aload_01:        getfield        #4;//Fieldm_container:Ljava/util/HashMap;4:        aload_15:        invokevirtual        #5;//Methodjava/util/HashMap.get:(Ljava/lang/Object;)Ljava/lang/Object;8:        areturnpublicvoidput(java.lang.Object,java.lang.Object);Code:0:        aload_01:        getfield        #4;//Fieldm_container:Ljava/util/HashMap;4:        aload_15:        aload_26:        invokevirtual        #6;//Methodjava/util/HashMap.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;9:        pop10:        return}从bytecode中能够看出,个中并没有包括任何与K,V有关的信息。get/put办法的参数和前往值都是Object范例,乃至内置的HashMap也是云云。那末挪用DictWrapper的代码是怎样做到“强范例”的呢?比方:
publicstaticvoidmain(String[]args){DictWrapper<String,String>dict=newDictWrapper<String,String>();dict.put("Hello","World");Stringworld=dict.get("Hello");}它的bytecode即是:
publicstaticvoidmain(java.lang.String[]);Code:0:        new        #2;//classjeffz/practices/DictWrapper3:        dup4:        invokespecial        #3;//Methodjeffz/practices/DictWrapper."<init>":()V7:        astore_18:        aload_19:        ldc        #4;//StringHello11:        ldc        #5;//StringWorld13:        invokevirtual        #6;//Methodjeffz/practices/DictWrapper.put:(Ljava/lang/Object;Ljava/lang/Object;)V16:        aload_117:        ldc        #4;//StringHello19:        invokevirtual        #7;//Methodjeffz/practices/DictWrapper.get:(Ljava/lang/Object;)Ljava/lang/Object;22:        checkcast        #8;//classjava/lang/String25:        astore_226:        return}看到标号为22的那行代码没有?这条checkcast指令即是将上一句invokevirtual的了局转化为String范例——DictWrapper.get所前往的是个最一般不外的Object。
这即是Java言语的泛型完成——请注重我这里说的是Java言语,而不是JVM。由于JVM自己并没有“泛型”的观点,Java言语的泛型则完整是编译器的邪术。我们写出的泛型代码,现实上都是和Object对象在打交道,是编译器在帮我们省往了冗余的范例转换代码,以此包管了代码层面的范例平安。因为在运转时往除一切泛型的范例信息,因而这类泛型完成体例叫做TypeErasure(范例擦除)。
在.NET中则完整分歧,“泛型”是真逼真切落其实CLR层面上的功效。比方DictWrapper.Get办法在.NET上的IL代码即是:
.methodpublichidebysiginstance!TValueGet(!TKeykey)cilmanaged{.maxstack2.localsinit(!TValueCS$1$0000)L_0000:nopL_0001:ldarg.0L_0002:ldfldclass...Dictionary`2...DictWrapper`2::m_containerL_0007:ldarg.1L_0008:callvirtinstance!1...Dictionary`2::get_Item(!0)L_000d:stloc.0L_000e:br.sL_0010L_0010:ldloc.0L_0011:ret}您能够发明,.NET的IL便切实包括了TKey和TValue的范例信息。而在运转的时分,CLR会为分歧的泛型范例天生分歧的详细范例代码,这在我之前的文章中也有所说起。
那末,Java和C#两种泛型完成体例分离有甚么上风和优势呢?Java这类TypeErasure做法,最年夜的上风便在于其兼容性:即使利用了泛型,但最初天生的二进制文件也能够运转在泛型呈现之前的JVM上(乃至JDK中不必要增加分外的类库)——由于这里的泛型基本不触及JVM的变更。而.NET中的泛型必要CLR方面的“新才能”,因而.NET2.0的程序集是没法运转在CLR1.0上的——固然.NET1.0的程序集能够间接在CLR2.0上实行。而CLR完成体例的上风,便在于能够在运转时代表现出“模板化”的上风。.NET程序员都晓得,泛型能够节俭值范例的装箱和拆箱的开支,即使是援用范例也能够制止分外的范例转化,这些都能带来功能上的进步。
因而,在.NET社区常常会把Java的这类完成体例称之为“假泛型”,而同时也会有人辩驳到:泛型原本就是言语上的观点,完成分歧又有甚么干系,凭甚么说是“假”的呢?实在,因为得到了JVM的撑持,一些.NET平台上经常使用的,十分无效的开辟体例都难以使用在Java上。比方所谓的泛型字典:
publicclassCache<TKey,TValue>{publicstaticTValueInstance;}publicclassFactory{publicstaticstringCreate<TKey>(){if(Cache<TKey,string>.Instance==null){Cache<TKey,string>.Instance=//someexpensivecomputation}returnCache<TKey,string>.Instance;}}因为Cache<TKey>在运转时是个详细自力的范例,因而泛型字典是功能最高的存储体例,比O(1)工夫庞大度的哈希表还要凌驾很多。假如说这也只是运转方面的上风,那末这段代码中的“泛型工场”代码(即Factory.Create<SomeType>(),包含相似的Factory<T>.Create()这类)则是Java言语中没法完成的。这是由于TypeErasure的感化,在运转时JVM已损失了TKey如许的范例信息,而在.NET平台上,TKey则是Create<TKey>署名的构成部分。
TypeErasure酿成的限定另有很多,假如您是一个C#程序员,大概难以信任以下的Java代码都是分歧法的:
publicclassMyClass<E>{publicstaticvoidmyMethod(Objectitem){if(iteminstanceofE){//Compilererror...}Eitem2=newE();//CompilererrorE[]iArray=newE;//Compilererror}}因为JVM不供应对泛型的撑持,因而关于JVM上撑持泛型的言语,如Scala,这方面的压力就完整落在编译器身上了。并且,因为这些言语以JVM为底,TypeErasure会影响JVM平台上几近一切言语。以Scala为例,它的形式婚配语法能够用来判别一个变量的范例:
valuematch{casex:String=>println("ValueisaString")casex:HashMap=>println("ValueisHashMap")case_=>println("ValueisnotaStringorHashMap")}猜猜看,假如value变量是个HashMap范例的对象,下面的代码会输入甚么了局呢?假如是C#或是F#如许运转在.NET平台上的言语,终极输入的必定是“Valueisnot...”。只惋惜,因为JVM的TypeErasure特征,以上代码输入的倒是“ValueisHashMap”。这是由于在运转时代JVM其实不包括泛型的范例信息,HashMap便是HashMap,不管HashMap仍是HashMap都是HashMap,JVM没法判别分歧泛型范例的汇合之间有甚么区分。不外还好,Scala编译器碰到这类情形会收回告诫,程序员能够懂得这些代码大概会呈现的“误解”。
因而,为何有IKVM.NET如许的项目能够将Java言语编译成.NET程序集(也能够将Java的jar包转化成.NET程序集),却没有项目将C#编译到JVM上(或是将C#程序集转化为jar包)。这是由于,JVM不敷以支持C#言语所必要的一切特征。而从运转时的两头代码角度来讲,JVMBytecode的才能也是.NETIL的子集——又有甚么举措能够将超集塞进它的子集呢?
别的,如CLR的值范例大概也很难间接落其实JVM上,这也是JVM上运转C#的又一拦阻。
固然,假如真要在JVM上完成完全的C#也并不是不成以。只需在JVM长进行一层封装(比方仍是就叫做CLR,CLRLanguageRuntime),必定能够满意C#的全体请求。可是这个价值太高,即便完成了这点大概也没甚么实践意义。而现实上,已有人在JVM上完成了一个x86摹拟器,那末又有是做不了的呢?其实不可,我们就在摹拟器上装一个Windows操纵体系,然后装一个Microsoft.NET,再……
本文来自:http://www.ckuyun.com/JeffreyZhao/archive/2010/02/22/why-not-csharp-on-jvm-type-erasure.html


有了这样一个呼声:让java代替C语言成为基本语言。这些足以说明java简单易学的这个优点。其次,java的功能强大,前面我也提到了,EJB3.0的推出使java成为了大型项目的首选。

分手快乐 发表于 2015-1-21 19:52:18

是一种为 Internet发展的计算机语言

再现理想 发表于 2015-1-24 05:03:39

另外编写和运行Java程序需要JDK(包括JRE),在sun的官方网站上有下载,thinking in java第三版用的JDK版本是1.4,现在流行的版本1.5(sun称作J2SE 5.0,汗),不过听说Bruce的TIJ第四版国外已经出来了,是专门为J2SE 5.0而写的。

因胸联盟 发表于 2015-1-25 22:00:59

关于设计模式的资料,还是向大家推荐banq的网站 http://www.jdon.com/,他把GOF的23种模式以通俗易懂的方式诠释出来,纯Java描述,真是经典中的经典。

活着的死人 发表于 2015-2-1 19:53:17

多重继承(以接口取代)等特性,增加了垃圾回收器功能用于回收不再被引用的对象所占据的内存空间,使得程序员不用再为内存管理而担忧。在 Java 1.5 版本中,Java 又引入了泛型编程(Generic Programming)、类型安全的枚举、不定长参数和自动装/拆箱等语言特性。

灵魂腐蚀 发表于 2015-2-7 04:28:48

其实说这种话的人就如当年小日本号称“三个月拿下中国”一样大言不惭。不是Tomjava泼你冷水,你现在只是学到了Java的骨架,却还没有学到Java的精髓。接下来你得研究设计模式了。

蒙在股里 发表于 2015-2-9 13:43:20

是一种突破用户端机器环境和CPU

金色的骷髅 发表于 2015-2-27 06:37:22

任职于太阳微系统的詹姆斯·高斯林等人于1990年代初开发Java语言的雏形,最初被命名为Oak,目标设置在家用电器等小型系统的程序语言

精灵巫婆 发表于 2015-3-1 16:51:09

是一种由美国SUN计算机公司(Sun Microsystems, Inc.)所研究而成的语言

爱飞 发表于 2015-3-10 19:58:49

Jive的资料在很多网站上都有,大家可以找来研究一下。相信你读完代码后,会有脱胎换骨的感觉。遗憾的是Jive从2.5以后就不再无条件的开放源代码,同时有licence限制。不过幸好还有中国一流的Java程序员关注它,外国人不开源了,中国人就不能开源吗?这里向大家推荐一个汉化的Jive版本—J道。Jive(J道版)是由中国Java界大名 鼎鼎的banq在Jive 2.1版本基础上改编而成, 全中文,增加了一些实用功能,如贴图,用户头像和用户资料查询等,而且有一个开发团队在不断升级。你可以访问banq的网站

乐观 发表于 2015-3-14 21:54:50

你一定会高兴地说,哈哈,原来成为Java高手就这么简单啊!记得Tomjava也曾碰到过一个项目经理,号称Java很简单,只要三个月就可以学会。

小妖女 发表于 2015-3-21 14:26:14

象、泛型编程的特性,广泛应用于企业级Web应用开发和移动应用开发。

仓酷云 发表于 2015-4-2 13:33:04

Pet Store.(宠物店)是SUN公司为了演示其J2EE编程规范而推出的开放源码的程序,应该很具有权威性,想学J2EE和EJB的朋友不要 错过了。

老尸 发表于 2015-4-9 04:41:32

是一种将安全性(Security)列为第一优先考虑的语言

不帅 发表于 2015-4-10 17:16:16

关于设计模式的资料,还是向大家推荐banq的网站 http://www.jdon.com/,他把GOF的23种模式以通俗易懂的方式诠释出来,纯Java描述,真是经典中的经典。

飘飘悠悠 发表于 2015-4-11 14:48:58

是一种为 Internet发展的计算机语言

莫相离 发表于 2015-4-12 03:57:56

Java是一个纯的面向对象的程序设计语言,它继承了 C++语言面向对象技术的核心。Java舍弃了C ++语言中容易引起错误的指针(以引用取代)、运算符重载(operator overloading)

第二个灵魂 发表于 2015-4-12 14:53:30

设计模式是高级程序员真正掌握面向对象核心思想的必修课。设计模式并不是一种具体"技术",它讲述的是思想,它不仅仅展示了接口或抽象类在实际案例中的灵活应用和智慧

透明 发表于 2015-4-16 04:30:54

设计模式是高级程序员真正掌握面向对象核心思想的必修课。设计模式并不是一种具体"技术",它讲述的是思想,它不仅仅展示了接口或抽象类在实际案例中的灵活应用和智慧

飘灵儿 发表于 2015-4-18 06:49:08

如果要向java web方向发展也要吧看看《Java web从入门到精通》学完再到《Struts2.0入门到精通》这样你差不多就把代码给学完了。有兴趣可以看一些设计模块和框架的包等等。
页: [1]
查看完整版本: JAVA网站制作之为何JVM上没有C#言语?浅谈Java言语的Type Erasure特征仓酷云