科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道Java世界的Ruby2

Java世界的Ruby2

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

这篇文章,我希望能够和你一起分享我在开发Java系统的时候使用Ruby的那种兴奋感。我比较一下Java和Ruby的优点和缺点,而且介绍一下JRuby解释器的支持者和反对者...

作者:silentbalanceyh, 来源:IT专家网 2008年6月4日

关键字: RUBY 世界 java

  • 评论
  • 分享微博
  • 分享邮件
即使在没有使用反射的Java代码中,你会经常丢失掉静态类型的信息。比如,在Command设计模式里面使用execute()方法必须返回Object胜于在Java代码里面使用的特殊类型,结果会导致很多ClassCastException发生。同样的,当在编译时和运行时修改方法签名的时候,运行时错误就会发生。在实践开发中,不论是Java还是Ruby,这样的错误很少引起严重的程序Bug。一个健壮的单元测试——任何时候你都会用到的——通常都能够及时捕捉他们。

  Ruby的动态类型意思是你不用重复问你自己一个问题:在Java里面你是否经常在一行里面遇到这样冗长的代码:

  XMLPersistence xmlPersistence 
  = (XMLPersistence)persistenceManager.getPersistence();

  Ruby消除了这种对于类型定义和转换的需要,上边的代码用一个典型的Ruby等价表达为;

  xmlPersistence = persistence_manager.persistence.

  Ruby的动态类型意义上不是弱类型——Ruby经常需要你传递正确类型的对象。事实上,Java强制类型转换比Ruby要弱。例如,Java里面:”4”+2 等于”42”,这里会将整数转化为字符串,在Ruby里会抛出一个TypeError,告诉你这个“can't convert Fixnum into String.”(Fixnum类型是不可以转化为String的)。同样的,Java里,因为作类型校正牺牲了速度,而且过多地做了整型操作,产生像Integer.MAX_VALUE + 1的整型,和Integer.MIN_VALUE等价,可是Ruby类型校正整型只是在需要的时候。

  不论Ruby有什么优点,Java的静态类型可以让它在大规模的项目里面作为首选:Java工具能够在开发时候明白代码意思。IDE能够在类之间依赖跟踪,找到方法和类的用处,自动检标识符而且帮助你检测代码。同样的虽然Ruby工具在这些功能上存在限制,它缺乏类型信息所以不能够完成上边这些工作。

  解释性语言

  Ruby是在解释器里面执行的,所以你不需要等待编译可以直接测试你的代码;你能够很平坦地利用交互方式执行Ruby,执行你键入的每一行。除开这些反馈,解释性语言在处理程序Bug地时候很少有明显的优点。使用编译性语言,能够分析代码造成的程序Bug,这些领域工程师必须决定发布过的应用程序的确切版本而且需要在源代码配置管理系统里面查找这些代码。在真实生活中,这些通常很简单。使用解释性语言,另一方面,分析的时候源代码是可以马上利用的而且在需要的时候如果突然异常是可以修复的。

  可是解释性语言因为执行慢有一个不幸的名声。对比Java的历史,一种“semi-compiled”语言:在早些年,JVM经常在运行时解释字节码,Java因为速度慢捐献了它的名声。然而很多应用程序花费了开发者很多时间等待用户或者是网络输入输出而且这些瓶颈一只保持着,Java开发者快速学习高效算法来优化它强于使用低级计算机语言进行开发。最近几年里,Java速度有了一定的提升;例如,基于动态分析的最优化及时编译器(just-in-time)有时候让Java胜过C++,这些在基于静态编译中最优化是受到限制的。

  在很多应用程序中,Ruby不比其他语言速度慢。在不久的将来,Ruby将得到更大的进步就像Ruby本地解释器转移到基于字节码的系统,而且JVM JRuby解释器获得了将Ruby编译成Java字节码的能力。最终的,任何平台对于很多功能来说都逐渐被忽略,由此获得了平台独立性。

功能性编程

  Ruby支持熟练的多样化设计程序范例。另外的对于它的纯面向对象的风格,它同样支持一次性脚本的程序化风格:你可以在类和函数外任何地方写代码,就像函数在任何类之外一样。

  更有趣的是,对于Java程序员寻找的新的和有用的观点,Ruby支持功能范例。你可以在Java里面使用更多的功能程序结构,使用很多类库支持就像Jakarta Commons Collections系列的集合包一样,但是这些语法是笨拙的。Ruby,虽然不是一种纯功能性语言,但是对待功能和匿名块如同完整的语言成员一样,这些都是能够像其他简单对象一样被传递到周围和利用的。

  在Java里面,你经常反复使用集合的Iterator(迭代器),从逻辑上去遍历集合里面的每一个元素。但是这种遍历仅仅是这样一个细节实现:一般来说,你仅仅尝试去接受对集合里面的每一个元素采取同样的逻辑。在Ruby里,你可以将一段代码块传给一个执行它的方法,遍历是在执行后台运行的。例如,[1,2,3,4,5].each{|n|print n*n, “ “}将打印这样的字符串:1 4 9 16 25;迭代器将会遍历这个列表里面的每一个元素将他作为一个变量n传到代码块里面。

  利用在代码块之前和之后执行的指令将代码块封装起来的功能程序是很有用的。比如,在Java里面,你可以使用Command模式保证一个文件的打开和关闭、数据库的事务处理、或者其他的资源调用。这些匿名内部类和回调函数式的无用框架将会使代码变得冗余沉重;除此之外,这里还有一个变迁规则就是变量在匿名Command类里面传递的时候必须定义成为final。而且为了确保最后的代码块在逻辑上能够执行,整个工作就会使用try{…}finally{…}封装起来。

  在Ruby里面,你可以封装任何函数或者代码块,不需要任何方法定义或者匿名内部类。在Listing 2里面,这个文件打开,然后在write()方法执行过后关闭。没有任何需要使用transaction()方法的代码和代码块。

  Listing 2. Wrap a code block

File.open("out.txt", "a") {|f|
    f.write("Hello")
}

  元程序语言

  你一般情况下是定义你的Java类作为你的源程序,但是你仍然可以在运行时进行类定义的操作。这个需要高级技术比如在加载类的时候增加字节码。比如,Hibernate直接插入数据存取逻辑到商业对象的字节码里面,从额外的数据存取层里保存应用程序。但是类操作,又称为元程序,在实践中仅仅是用来组织基础程序的:应用程序是不能有效地引入这些技巧和脆弱的技术的。

  即使在开发的时候,Java限制了开发者改变类的能力。为了加入一个isBlack()方法检测一个String是否全是空字符串,你不得不加入一个带有静态方法的StringUtils 类;理论上,这个新方法是输入String的。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章