从一个应该是很简单的问题说起

2016-03-20  本文已影响0人  herenoone

首先看个简单的例子。

package myexample;

public class Dog {

    public static void main(String[] args) {
        Dog d = new Dog();
        System.out.println(d);
    }
}

输出的结果是:一个包名+类名@一串莫名的数字和字母

myexample.Dog@6fd7bd04

为什么打印一个对象会出现这个结果,一开始也没去深究。
这个一直被我忽略的问题让我意识到了阅读源码的重要性,很多以前不是那么清楚的,阅读完源码之后渐渐有了一些清晰的认识。

package myexample;

public class Dog {
    
    private String s;
    
    public Dog(String s){
        this.s = s;
    }
    //重写了toString()方法
    public String toString(){
        return getClass().getName() + "------名字叫" + s;
    }

    public static void main(String[] args) {
        Dog d = new Dog("小黄");
        System.out.println(d);
    }
}

输出的结果变成了:

myexample.Dog------名字叫小黄

我才明白System.out.println(d);这个语句中使用了d.toString();的方法,让对象变成了一个字符串。
当我们重写了toString()的方法之后,打印的结果自然就不同了。

为了弄明白其中的缘由,我就试着去找找它们的源代码

首先找一下System的源码:

package java.lang;

* @see     java.io.PrintStream#println(java.lang.Object)
//返回的是PrintStream
    public final static PrintStream out = null;

之后看一下println(java.lang.Object)

    public void println(Object x) {
//原来是使用了该方法
        String s = String.valueOf(x);
        synchronized (this) {
            print(s);
            newLine();
        }
    }

再找一下String.valueOf(x):

    public static String valueOf(Object obj) {
//确实是使用了obj.toString()的这个方法
        return (obj == null) ? "null" : obj.toString();
    }

那么obj.toString()到底是怎么一回事

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

myexample.Dog@6fd7bd04

跟我们原先的结果一致
如果我们重写了toString()方法,那么System.out.println(d),自然会去使用我们重写了的方法

public String toString(){ return getClass().getName() + "------名字叫" + s; }

继续往下深究,在Integer.java中

package java.lang;
    public static String toHexString(int i) {
        return toUnsignedString(i, 4);//注意传入的参数
    }


    /**
     * Convert the integer to an unsigned number.
     */
    private static String toUnsignedString(int i, int shift) {
        char[] buf = new char[32];//创建字符数组
        int charPos = 32;
        int radix = 1 << shift;//对toHexString(int i)而言,左移4位
        int mask = radix - 1;
        do {
            buf[--charPos] = digits[i & mask];
            i >>>= shift;//无符号右移运算,忽略了符号位扩展,0补最高位
        } while (i != 0);
//把字符数组变成字符串
        return new String(buf, charPos, (32 - charPos));
    }

    /**
     * All possible chars for representing a number as a String
     */
    final static char[] digits = {
        '0' , '1' , '2' , '3' , '4' , '5' ,
        '6' , '7' , '8' , '9' , 'a' , 'b' ,
        'c' , 'd' , 'e' , 'f' , 'g' , 'h' ,
        'i' , 'j' , 'k' , 'l' , 'm' , 'n' ,
        'o' , 'p' , 'q' , 'r' , 's' , 't' ,
        'u' , 'v' , 'w' , 'x' , 'y' , 'z'
    };


针对hashCode(),在Object.java中

package java.lang;
    public native int hashCode();

之后再对hashCode进行学习。。。

上一篇 下一篇

猜你喜欢

热点阅读