2 个回答
-
| 2017-10-08 10:15:04 广告
J++是什么?
J++是微软的Java实现版本,表达式、关键字、语法规约都和Java一致,符合Java的语言规范,2004年1月停止支持。
Sun为什么要告微软
Sun一开始是授权微软可以使用Java的,随后对微软提起了商标侵权的诉讼,因为Sun的商标授权协议里要求实现必须是“兼容的”,才能使用Java的商标。而微软的MSJVM没有通过Java的符合性测试。最终Sun和微软和解,条件是J++只能开发到1.1.4版本,并且停止MSJVM的分发和下载。
J++的部分技术被回收利用,吸收到了.Net平台,演化成为J#,最终到现在的C#。
J++与Java的不同点- J++没有实现部分Java的特征,如RMI (Remote Method Invocation), JNI (Java Native Interface)
- J++增加了一些Java没有的特征,如callback,delegate,event,从这时起就已经算是一个不同于Java的新语言了。现在可以在C#里看到这些特征。
- J++没有遵守Java对操作系统层调用的标准,而是采用了J/Direct框架,提供了一套完全绕过Java类库与API访问OS的机制,能直接调用Win32 API,因而有更好的性能。在现在的.Net框架中,有一套P/Invoke机制与其对应。
- 使用了MS扩展特征的J++程序不能直接运行在Java SDK上,但有项目能使这些程序跑在开源的JVM上。不过这些扩展并没有被广泛的使用。
- J++支持ActiveX
- J++提供了WFC(Windows Foundation Classes)框架,封装了Win 32 API以及DHTML对象模型,主要用于在Windows上开发GUI应用程序。
After Math
从法律和道义的角度来讲,微软违约很不厚道这点毋庸置疑,以下主要是从技术的角度来进行评价,一言以概之,时间证明Sun并没有站在先进生产力的一边。
最核心的槽点,可能就是J++搞私有API/不跨平台。但这直接带来了性能上的提升,虽然影响了跨平台,但作为一种工程上的trade off,不一定是坏事,想想当年的电脑有多慢吧。现在微软官方的.Net CLR实现出于性能考虑,同样把不少工作推到了平台相关的native代码层上,也并没有影响mono实现跨平台,可见这个槽点根本就不算个事。
J++可以认为一直延伸到了今天的.Net一系的产品线,所以要评价J++是怎样一种存在,在很大程度上需要把今天的C#/.Net和Java对比。现在Java和C#相比,除了(官方)跨平台,以及因为起步早+成本相对可以较低所以行业应用较多以外,毫无撸点,语言特征方面C#更是甩Java几条街。
J++增加的语法特征,不少延续到了C#上,用过都知道爽。
JNI和C# P/Invoke相比,易用性完全不在一个档次上。
Java至今还鸡肋的泛型,谁用谁蛋碎。
由于mono项目的存在,使得C#跨平台根本不是问题,唯一影响其广泛在开源社区被采用(如默认在Linux发行版中集成)是因为开源社区普遍不待见微软,并且对微软的CP(Community Promise,微软承诺允许开源社区自由的对包括C#在内的部分微软专利产品、规范编写自己的实现)持保留意见。但这并不影响mono的广泛使用,不少的应用程序、开发框架都采用mono作为脚本引擎,比如Unity3D引擎。
最近在研究把CoffeeScript编译到CLR上执行,顺便再说下运行时环境,JVM vs CLR。这么多年来,产生了一些编译到Java byte code,然后在JVM上运行的的语言,比如Scala,但并没有证据表明Sun一开始的设计就考虑到了JVM大生态圈的建立。而.Net CLR则提供了一系列相当凶残的方案,比如DLR(Dynamic Language Runtime),编译器的开发者只需要解析出代码的AST(Abstract Syntax Tree),再加上少量的glue code,就能把一种新语言target到.Net上运行,完全无需操心代码生成、代码优化、runtime等等需要花费大量精力的编译器后端环节,并且能在后续.Net升级时,自动获得新的改进(比如更加NB的代码优化算法)。这代表什么?一个开发者甚至不需要把《编译原理》一书读完,翻了前几章能写个词法分析和语法分析,会解决Grammar的Shift-Reduce conflict,就能撸出一个能用于生产的以CLR为目标平台的编译器出来。不管最后结果会如何,从技术的角度而言,微软的解决方案是更有利于开发生态的建立。
从这些角度来看,J++虽然不能说是完爆Java,青出于蓝四个字还是能提的,进步的态度和力度都是值得称道的。微软在当年受制于Sun的许可协议时,尚且大胆的对Java进行扩展改进,后续衍生的C#/.Net平台的每个新版本的演化力度都不弱,反观Java这么多年来的进展,不免让人呵上一呵。
和微软现在C#的Community Promise相对比,当年Sun给微软的Java授权协议,不得不说实在是太狭隘了,最终在一定程度上限制了自身的发展。本问答由RednaxelaFX提供
- J++没有实现部分Java的特征,如RMI (Remote Method Invocation), JNI (Java Native Interface)
-
| 2017-10-08 09:52:27 广告
目前排名第一的猫杀的答案不错。我想就所谓“Microsoft J++”到底是什么稍微补充几点。
本文提到的“Sun JVM”主要说的是Sun JDK 1.0.2带的那个元祖JVM。它在后来的Sun JDK里被称为Classic VM,再后来被HotSpot VM所替代。
当时(Sun JDK 1.0.2)的Java跟现在的Java不可同日而语。别提标准不标准,当时的Java毛都没有,很多东西所谓“标准”就是“Sun怎么实现”。
为什么Sun要告微软?微软“不乖”,“擅自”扩展Java让它在Windows上变得更好自然是一方面;另一方面Sun对它的Java合作伙伴们普遍态度恶劣,非常傲慢和小心眼,这才是更重要的方面。
这方面请参考另一个问题的回答:如果当时 Sun 没有起诉微软,而微软继续保持对 Java 的热情的话,Java 的现状会是怎样? - RednaxelaFX 的回答
另外,想从别的侧面看看当年Sun的行为,看看1997年Sun在benchmark上作弊的事情:Sun accused over JIT compiler results。这还不是Sun第一次做这种事嗯。
关于控告的过程,请参考当时的新闻稿:Washingtonpost.com: WashTech -- U.S. v. Microsoft Special Report
Microsoft J++
Microsoft J++是外界对微软所实现的Java的开发套件和运行时环境的统称。微软自己其实并没有一个叫做“Microsoft J++”的产品(或语言)。微软一直觉得自己实现的就是Java语言,只是稍微根据Windows环境的需要“增强”了一点而已。
微软在JDK 1.0.x时期就获得了Java的授权,将Java移植到Windows平台上。当时的Java真是烂得掉渣,JVM的速度又慢,Java核心库的功能又是要啥啥没有:
例如说能用的容器数据结构就只有Vector、Stack(包装了Vector)、Hashtable(不允许null值)、BitSet,连LinkedList都还没有——“谁会要用链表呢”。
java.math、java.text、java.sql、java.rmi之类的重要的类库都还不存在,locale支持还不存在,图形库只有又慢又不好用的AWT⋯
嗯对,JDK 1.0.2的时候连反射都还没API,java.lang.reflect也还不存在。Java语言里“接口”这个语言结构也还不存在。
JNI(Java Native Interface)标准也还不存在。Sun JDK 1.0.2只有一个非常原始的native interface,而它允许native代码直接访问Java对象的内部结构,既不安全也不可移植。更新信息可以参考当时的文档:Integrating Native Methods into Java Programs。
而这个时候Windows上已经有很多可用的库,更重要的是:- 它们有很多都以COM的方式暴露接口
- Java的对象技术其实跟COM有许多重叠之处
- J/Direct与RNI(Raw Native Interface):用于与native代码交互
- Java/COM:让Java能够使用COM的库,也让Java程序能够暴露出COM接口,便于与其它程序交互。参考这里:Can You Implement COM Components Using Java?
- 委托(delegate):现在Java 8也有lambda,大家都知道这个是什么了。当时要引入委托主要是为了更好的支持事件模型的回调。详情可以参考微软对Java委托的专利:Patent WO1999063433A1,以及MSDN的文档 Delegates in Visual J++ 6.0。微软当时为Java实现了委托之后把全套代码交给了Sun,向Sun申请添加该功能到标准Java。结果Sun暴跳如雷急忙批判微软要分裂Java…
- 还有一大堆的库。例如Windows Foundation Classes(WFC)。WFC包装了Win32和DHTML的图形组件库。Win32的部分跟后来.NET的Windows Forms(WinForms)很像。
- 等等⋯
微软版的RNI在Sun版的JNI之前就已发布,自然就不大愿意再实现一个功能非常相似的东西。但微软决定不在MSJVM里实现完整的JNI成为了后来打官司的关键因素之一。
当年微软给Java加了的功能,现在Oracle在一点点给Java加上⋯- Java SE 8给Java语言加上了lambda与method reference;
- Java SE 9正在计划给Java加上跟J/Direct类似的新的、更方便的native interface
Microsoft Visual J++
Visual J++,这是一个实际存在的产品的名字。它是一个用于开发Java应用程序的IDE,里面还包含有IE3.0之类的“附属物”。Visual J++有单独发布的版本,后来被整合到Visual Studio里发布。
Microsoft SDK for Java(MSJDK)
这是Sun JDK的微软版对应物,独立于Visual J++免费发布。它包含开发Java应用程序所需要的工具套件,例如Java源码编译器 jvc(与Sun JDK的javac对应),Java的命令行启动程序 jview (与Sun JRE的java命令对应) ,Java Applet Viewer,Java核心库,还有Java虚拟机(MSJVM),等。
有个有趣的工具叫做 jexegen。顾名思义,它用于为Java程序创建一个可执行程序,把Java程序所需的Class文件打包在生成的exe里。这跟后来.NET Assembly的做法很接近:它是一个PE文件,不过启动之后马上会去加载MSJVM来执行打包的Class文件。能生成出可执行文件让Java写出来的程序能更符合Windows的用户习惯。
Microsoft Compiler for Java(jvc)
jvc 是微软自己实现的Java源码编译器,应该是用C++实现的(求证)。
它的编译速度非常快,而且编译时会做许多优化,编译出来的代码质量也比较高。
相比之下,同时期Sun的javac是用Java实现的,编译速度慢一些;虽然也做一定量的优化,但没 jvc 做得深。
jvc 跟当时IBM的 Jikes编译器(跟后来的Jikes RVM不是同一个东西)地位相似。两者都用native语言实现(Jikes用C++),编译速度都比较快,而且都做比较多优化。
同年代同样用native语言实现的Java源码编译器还有Symantec Café Compiler。
jvc 支持所有标准的Java语言特性,外加支持如delegate、J/Direct之类的微软扩展的特性。
话说有个黑历史非常搞笑:Sun在控告微软的jvc不兼容Java规范的时候,指责jvc生成的Class文件通不过TCK1.1;然后微软不但说明Sun没用对命令(故意打开了微软扩展来测试),而且进一步说明Sun的javac其实也不能完全通过TCK1.1;关掉了扩展的jvc能通过的TCK1.1测试比Sun的javac能通过更多。
Microsoft Virtual Machine for Java(MSJVM, Microsoft VM, MSVM)
这是微软实现的JVM。最初的代码来自Sun授权的Sun元祖JVM,后来被魔改成Windows上最快的JVM实现。
IE3 Beta 1的时候带的MSJVM还只有解释器,到IE3 Beta 2就开始带有JIT编译器了。
MSJVM魔改了Sun JVM核心的每一方面。- 对象模型:Sun JVM的对象模型把“对象头”放在了handle里,使“对象头”跟对象实例数据分离到不同的地方了。MSJVM去掉了handle这层间接,于是把对象头与对象实例数据重新“粘”到了一块。关于MSJVM的对象模型,我在另一个回答里简单提了一下:为什么bs虚函数表的地址(int*)(&bs)与虚函数地址(int*)*(int*)(&bs) 不是同一个? - RednaxelaFX 的回答
- 基于直接指针而不是基于handle的引用,访问效率更高。
- GC:准确式的、分两代的copying GC。文档里还专门说了没使用mark-compact算法。当时的Sun JVM使用的是半保守式、不分代的mark-sweep(带可选compaction) GC。
- 对象同步:使用synchronization block而不是老Sun JVM的monitor cache。在对像头里包含有一个指向synchronization block的指针;该指针位于对象的负偏移量上。后来的CLR的对象头采用了同样的布局。在对象头里持有这样的指针大幅减少了查找对象的monitor的事件。Sun JVM是维护一个全局的用hash table实现的“monitor cache”,把对象的handle强制转换成int当作key去查找这个cache里的monitor,每次查找都是一个hash lookup。
- 线程:使用native线程,管理线程用的数据结构稍微调整过。Sun JVM在Windows上的版本用native thread,而在Solaris上的版本则是使用green thread(JVM自己调度的用户级线程)。
- 添加了JIT编译器:Sun JVM在JDK 1.0.x的时候只有个很简陋的JIT编译器接口,但没有发布JIT编译器的实现。MSJVM改造了这个接口并且提供了一个当时性能还不错的JIT编译器实现,而且配合准确式GC提供必要的信息。
- RNI:在Sun JVM的native interface的基础上衍生出的一套native interface。
- Java/COM在MSJVM内的支持
Sun那边的JIT编译器有好多黑历史⋯Sun JDK 1.0.2自己没有带JIT,不过有一个单独销售的产品叫“Java Workshop”,里面带有一个能插入Sun JVM的JIT,这个JIT编译器叫做“sunwjit”。
可以从这里下载到描述sunwjit的一篇文章(CompileJava97.pdf,“Compiling Java Just in Time”)。
后来Sun JDK 1.1.x的时候开始带JIT发布了,但却只在Solaris版上带有sunwjit,而在Windows版上带的是Symantec的JIT(“symcjit”)。
据说James Gosling原本自己写过一个JIT编译器,但是没发布被抛弃了。不知道这跟sunwjit是啥关系呢。
Microsoft Internet Explorer 3.0(IE3.0)
IE3.0真是当年的技术急先锋。一方面搭载了JScript来跟Netscape的JavaScript抗衡,另一方面捆绑了MSJVM以便支持Java。
先写这么多吧⋯
=============================================
后话
所以说当时MSJVM至少可以从三个地方获取:IE3、Visual J++/Visual Studio、MSJDK。MSJVM的许可证也允许第三方程序捆绑它发布。
顺带一提,根据Patrick Dussud在Channel 9上的一个访谈里提到的,微软里其实还有过一小撮人做过一个非正式项目,是写一个全新的、“clean-room”(不衍生自Sun的代码)的JVM原型。这个项目最后没有进入产品。或许如果当年Sun没有禁止微软开发新版本Java的话,微软也会像IBM开发出全新、clean-room的J9 VM一样有自己独立的JVM。
然而历史没有如果。那个clean-room的JVM原型为后来的CLR的研发积累了不少经验。
我觉得现在这样也挺好的。.NET总算没把Java所有的历史包袱都带上,CLI(Common Language Infrastructure)的基础设计又比JVM的更进步和完善。本问答由RednaxelaFX提供
更多
- 盛刷pos机24小时400客服电话是多少?
- 33
- 3
- 盛刷pos机刷卡不到账怎么办?
- 75
- 3
- U米pos机客户服务电话是多少?
- 83
- 3
- 速刷pos机400客户服务电话是什么?
- 45
- 3
- 闪电宝pos机官方客服电话24小时客服电话
- 14
- 3
- 速刷pos机24小时在线客服热线
- 34
- 3
- 汇付天下pos机24小时在线客服热线
- 87
- 3
- 速刷pos机售后服务热线是什么?
- 89
- 3
- 速刷pos机24小时在线客服热线
- 87
- 3
- 闪电宝pos机全国24小时服务热线号码
- 62
- 3