1.4 JRuby语言与Java语言实例分析

这一节我们用三个实例来说明JRuby语言和Java语言代码的差异,第一个实例是JRuby语言代码比Java语言代码更为简洁;第二个实例是Java语言的语法太死板,缺乏灵活性;第三个实例是Java语言的面向对象技术不彻底。

1.4.1 实例一:JRuby语言代码的简洁性

本实例展示JRuby语言的简洁特性。

这里有两个实例程序:Java语言程序如代码清单1-6所示,JRuby语言程序如代码清单1-7所示。它们都采用Java语言的类java.util.TreeMap进行代码编程。在这两个程序中,都使用空行将程序分成为三个部分,各部分的含义基本上是相同的。第一部分是定义该程序所需要的类;第二部分是创建基于类java.util.TreeMap的对象map,并且赋予这个对象初始值;第三部分是利用两门语言的不同技术获取对象map的键和值,并且显示它们的和。

代码清单1-6 Java语言程序JavaTreeMap.java

1  import java.util.Iterator;
2  import java.util.Map;
3  import java.util.TreeMap;

4  public class JavaTreeMap {

5     public static void main( String[] args )  {
6         TreeMap<Integer, Integer> map = new TreeMap<Integer, Integer>();
7         map.put( 1, 10 );
8         map.put( 21, 12 );
9
10         int memo = 0;
11         Iterator it = map.entrySet().iterator();
12         while (it.hasNext()) {
13            Map.Entry me = (Map.Entry)it.next();
14            memo = ((Integer)me.getKey()).intValue() + 【空一格继续】
                      ((Integer)me.getValue()).intValue();
15            System.out.println(memo);
16         }
17     }
18  }

代码清单1-7 JRuby语言程序java_tree_map.rb

1  include Java
2  import java.util.TreeMap

3  map = TreeMap.new
4  map[1], map[21] = 10, 12

5  map.inject(nil) do |memo, (key,value)|
6   puts memo = key+value
7  end

现在来分析这两个程序的不同点。

从代码的数量和简易性角度看,两者的差异是显而易见的。

从理解代码的难度看,两门语言都有难点,但是它们的难易程度完全不同。JRuby语言的难点是第三段第5行代码,Java语言程序的难点也是在第三段,但是Java代码需要理解的内容明显多了许多。我们说明一下JRuby语言的第三段代码。这是使用了Ruby语言的代码块技术,它是Ruby语言中一种最常用的技术。这种技术在本书的第8章第4节中将会详细介绍。在JRuby程序中,函数inject的参数(其中的nil)是应用于变量memo的,而对象map的每一个元素是作用于表达式“(key,value)”的。注意:参数值nil仅仅在对象map的第一个元素出现时对变量memo有作用,之后这个变量memo的值就是nil。在这里开始函数inject的参数值就是nil,因此变量memo的值始终是nil。应该说,这一实例已经是Ruby语言的代码块技术中复杂的实例。

从代码记忆的角度看,每一门计算机语言都需要我们去记忆一些代码和技巧。在JRuby程序中,最需要记忆的技巧就是第5行代码。要是能够很好地理解这一行代码,那么对该方法的记忆也就很容易了。而Java语言的第三段代码,首先需要为对象map生成一个迭代器,之后利用这个迭代器来完成对对象map的元素的获取。

在JRuby语言中,可以利用交互工具jirb对每一行代码进行分析,这是一件非常容易的事情。在本书的第2章第4节中详细说明了工具jirb的使用方法。该工具的启动命令如代码清单1-8所示。在Windows系统的DOS窗口下输入这个命令,会出现“ (main):001:0>”,这说明已经进入了jirb的交互环境,可以输入JRuby语言程序代码了。注意:这个命令已经把程序代码清单1-7的第1行代码包括进去了。前面已经提及过,该工具最简单的启动命令也可以是jirb。

代码清单1-8交互工具jirb的启动命令方法

jirb -rjava

接下来就可以在jirb的交互环境下输入代码清单1-7中第2行以后的其他代码,结果如代码清单1-9所示。

代码清单1-9交互工具jirb的启动命令操作输出结果

irb(main):001:0>irb(main):001:0>import java.util.TreeMap
=> Java::JavaUtil::TreeMap
irb(main):002:0>map = TreeMap.new
=> #<Java::JavaUtil::TreeMap:0x1b9f88b @java_object={}>
irb(main):003:0>map[1] = 10
=> 10
irb(main):004:0>map[21] = 12
=> 12
irb(main):005:0>map.inject(nil) do |memo, (key,value)|
irb(main):006:1*   p memo = key+value
irb(main):007:1>end
11
33
=> nil
irb(main):008:0>exit

1.4.2 实例二:JRuby语言代码的灵活性

第二个实例是想说明Java语言与JRuby语言在语法方面的差异性。程序的代码分别是代码清单1-10和代码清单1-11。

在代码清单1-10的Java语言程序中,有个关键词switch,而在代码清单1-11的JRuby语言程序中也有类似的关键词case,并且它们的使用方法是类似的,但是它们的功能就大不一样。在Java语言中,switch的判断变量(key)必须是int类型或者enum类型(这种数据类型只有Java版本5.0及其以后版本才能够使用)。在软件开发的实践中,这种限制会带来很多不便,如代码的类型转换等问题。而JRuby语言的关键词case后面的判断变量可以是任何类型的。JRuby语言的关键词case的功能还有更多,这里就不一一细说了。

代码清单1-10包含有关键词switch的Java语言程序

public class JavaSwitch {
    public static void main(String[] args) {
        int key = 0;
        switch (key) {
        case 1:
            break;
        default:
            break;
        }
    }
}

代码清单1-11包含有关键词case的JRuby语言程序

1  color = "red"
2  case color
3   when "red"
4     puts color
5   when "yellow"
6     puts color
7   else
8     puts "default color"
9  end

1.4.3 实例三:Java语言面向对象的不彻底性

第三个实例是想要说明一下程序语言的面向对象特点。

尽管Java语言也是号称面向对象的计算机语言,但其实它很多地方并非如此,如Java语言的数据类型int就不是类的对象。但是Java语言也确实存在一个整数类Integer,不过这已是一种不得已的补充。

下面再给出另外一个非面向对象的Java语言代码实例,如代码清单1-12所示。在这个程序中,给出了一个非面向对象的类System和一个面向对象的类Runtime。程序中的两组代码(第一组是第3行,第二组是第4行和第5行)的功能是完全一样的,即都是退出当前运行的程序,返回一个默认值。但是类Runtime的对象能够做更多的事情,正如类Integer和int一样。由此可以看出,Java语言的面向对象的特性是在不断地被完善的。

代码清单1-12包含类System的Java语言程序

    1  public class JavaSystem {
    2     public static void main(String[] args) {
    3         System.exit(0);
//  4       Runtime system = Runtime.getRuntime();
//  5       system.exit(0);
    6     }
    7  }