java拾遗:由反转数组想到System.out的实现机制

2015-01-21

环境:jdk 1.7。

如何反转数组


package hellojava;

public class HelloJava {

    public void reverseCharArray(char[] arr) {
        int left = 0;
        int right = arr.length-1;  // length是属性,而非方法
        char temp;
        while(left < right) {
            temp = arr[right];
            arr[right] = arr[left]; 
            arr[left] = temp;
            left ++;
            right --;
        } 
    }

    public static void main(String[] args) {
        HelloJava hj = new HelloJava();
        char[] ca = {'a', 'b', 'c', 'd', 'e'};
        System.out.println("原始:"+new String(ca));  // 原始结果
        hj.reverseCharArray(ca); // 反转之
        System.out.println("反转后:"+new String(ca));  // 反转后的结果
    }

}

运行结果:

原始:abcde
反转后:edcba

注意,不要把System.out.println("原始:"+new String(ca));写成System.out.println("原始:"+ca);,否则,输出有问题。如果是这样的main函数:

public static void main(String[] args) throws UnsupportedEncodingException {
    char[] ca = {'a', 'b', 'c', 'd', 'e'};
    System.out.println(ca); 
    System.out.println(""+ca);
}

运行结果是:

abcde
[C@11da5362

那么System.out.println?


原因很简单,System.out.println(ca);使用的是System.out.println(char[] x)这个方法,该方法是依次输出char数组中每个元素。注意,没有System.out.println(double[] x)等方法,如果是在println方法中放入了一个int数组,那么是在调用System.out.println(Object x)这个方法。参考java.io.PrintStream源码,其背后是将Object x传给了这个方法:

public void print(Object obj) {
    write(String.valueOf(obj));
}

然后,看一下java.lang.String类的源码,其String valueOf(Object obj)方法原型是:

public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
}

好吧,继续找,看一下java.lang.Object类的源码,其toString方法的源码是:

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

好吧,其实数组也是一个类,数组变量是一个对象,这个可以参考Is an array an object in java其中一个答案:

An object is a class instance or an array.

下面的代码片段:

public static void main(String[] args) throws UnsupportedEncodingException {
    double[] da = {1.0, 2.0, 3.0};
    System.out.println(da);
    System.out.println(da.toString());
}

输出的两个结果是相同的:

[D@11da5362
[D@11da5362

所以,对于

public static void main(String[] args) throws UnsupportedEncodingException {
    char[] ca = {'a', 'b', 'c', 'd', 'e'};
    System.out.println(ca); 
    System.out.println(""+ca);
}

由于有System.out.println(String x)这个方法,System.out.println(""+ca)可以看作System.out.println(""+ca.toString()),所以结果是看起来很奇怪的[C@11da5362其实,在java内部[代表array-ofC代表着char

在看一下这个:

public static void main(String[] args) throws UnsupportedEncodingException {
    Object obj = new Object();
    System.out.println(obj);
}

输出结果为:

java.lang.Object@11da5362