java中
        List list =new ArrayList();
        list.add("a");
        list.add("b");
        System.out.println(list);上面的代码中,list应该是指向new ArrayList();的地址吗,那我输出list时,应该会输出一个地址值 呀,
为什么会输出 [a b]出来呢,thanks

解决方案 »

  1.   

    因为容器类的toString()方法被重写了,只要重写一个类的toString()方法打印一个该类的对象时就按照你重写的方式打印了,Java的只要是new出来的对象都创建在堆中。
      

  2.   

    java中所有的类都是继承object类,在object类中有toString方法,ArrayList中重写了toString方法,所以会输入里面的元素的值而不是地址。java很多包中的类都重写的toString方法!
      

  3.   


    2楼的回答是正确的  重写了toString方法  直接输出对象的时候都是调用toString()方法返回的字符串。
    依据可以看jdk的源码  ArrayList的toString方法继承自java.util.AbstractCollection;源码如下:public String toString() {
            Iterator<E> i = iterator();
    if (! i.hasNext())
        return "[]"; StringBuilder sb = new StringBuilder();
    sb.append('[');
    for (;;) {
        E e = i.next();
        sb.append(e == this ? "(this Collection)" : e);
        if (! i.hasNext())
    return sb.append(']').toString();
        sb.append(", ");
    }
        }
    至于new出来的对象 肯定是放在堆里面的。list这个变量是放在栈里面,new出来的东西是在堆里面划分的空间,关于栈和堆的区别可以参考下面的文章
    http://blog.csdn.net/hongkiton/article/details/7457864
      

  4.   

    list 这个变量(一个List类型的引用)在栈中,它所指向的对象在堆中,栈中肯定存放的是一个地址,至于这个地址是不是直接指向堆中那个对象的地址,不同的jvm有不同的做法,有的是先指向java堆中的句柄池中的某个地址,然后该地址再指向对象实例;有的是直接指向堆中的对象实例
    当用System.out.println 一个变量时,是调用变量的对象的toString方法,如果你定义的类没有重写toString方法,那就用Object类的toString方法,Object的toString方法是用c/c++代码实现的ArrayList 继承自AbstractList,AbstractList继承自AbstractCollection
    AbstractCollection中的toString方法如下:public String toString() {
            Iterator<E> i = iterator();
    if (! i.hasNext())
        return "[]"; StringBuilder sb = new StringBuilder();
    sb.append('[');
    for (;;) {
        E e = i.next();
        sb.append(e == this ? "(this Collection)" : e);
        if (! i.hasNext())
    return sb.append(']').toString();
        sb.append(", ");
    }
        }