Java数据传递实验

来源:互联网 发布:西服 马甲 知乎 编辑:程序博客网 时间:2024/04/27 01:48


本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处!

在开发过程中,我们经常会遇到对象传递的问题,有时仅仅传递数据,有时却要实现数据同步;这时,就要分清两者间的区别。

public class DelegentDemo {public void changStr(String str) {str = "cde";}public void addStr(String str) {String bString = new String("cde");str += bString;}public void contactStr(String str) {String bString = new String("cde");str.concat(bString);}public void changeInt(int a) {a = 2;}public void addInt(int a) {a += 2;a++;}/** * @param stringBuffer */private void changStringBuffer(StringBuffer stringBuffer) {// TODO Auto-generated method stubstringBuffer.append("db");}/** * @param list */private void newList(List<String> list) {// TODO Auto-generated method stublist = new ArrayList<String>();}/** * @param list */private void changeList(List<String> list) {// TODO Auto-generated method stublist.add("cdf");}public static void main(String[] args) {DelegentDemo delegent = new DelegentDemo();String str1 = new String("abc");delegent.changStr(str1);System.out.println("abc传递常量重新赋值cde后:" + str1);delegent.addStr(str1);System.out.println("abc传递常量加值cde后:" + str1);delegent.contactStr(str1);System.out.println("abc传递常量contact值cde后:" + str1);int a = 3;delegent.changeInt(a);System.out.println("3传递常量重新赋值2后:" + a);delegent.addInt(a);System.out.println("3传递常量加值2后:" + a);List<String> list = new ArrayList<String>();list.add("abc");delegent.changeList(list);System.out.println("List size=1对象传递加值cdf后的大小:" + list.size());delegent.newList(list);System.out.println("List size=1 对象置空后的大小:" + list.size());StringBuffer stringBuffer = new StringBuffer("adb");delegent.changStringBuffer(stringBuffer);System.out.println("adb传递加值db后"+stringBuffer.toString());}}


结果如下:

abc传递常量重新赋值cde后:abc
abc传递常量加值cde后:abc
abc传递常量contact值cde后:abc
3传递常量重新赋值2后:3
3传递常量加值2后:3
List size=1对象传递加值cdf后的大小:2
List size=1 对象置空后的大小:2
adb传递加值db后adbdb


结论:

1、传递的String常量值改变(包含赋值和加值)后,等于产生一个新的变量,此引用指向新变量,而原引用仍然指向原变量,所以打印原引用,当然值不会发生改变。

例:

    public String trim() {        int start = offset, last = offset + count - 1;        int end = last;        while ((start <= end) && (value[start] <= ' ')) {            start++;        }        while ((end >= start) && (value[end] <= ' ')) {            end--;        }        if (start == offset && end == last) {            return this;        }        return new String(start, end - start + 1, value);    }
不论trim还是contact方法,均如此,这时String被当成基本数据常量来处理

常量都存储在栈,Int也是同样原理。

至于容器和对象,如List和StringBuffer,它们是存储在堆里面的,传递引用过去,操作后会改变值。

例:

    /**     * Adds the specified object at the end of this {@code ArrayList}.     *     * @param object     *            the object to add.     * @return always true     */    @Override public boolean add(E object) {        Object[] a = array;        int s = size;        if (s == a.length) {            Object[] newArray = new Object[s +                    (s < (MIN_CAPACITY_INCREMENT / 2) ?                     MIN_CAPACITY_INCREMENT : s >> 1)];            System.arraycopy(a, 0, newArray, 0, s);            array = a = newArray;        }        a[s] = object;        size = s + 1;        modCount++;        return true;    }
size被加1,
    /**     * Returns the number of elements in this {@code ArrayList}.     *     * @return the number of elements in this {@code ArrayList}.     */    @Override public int size() {        return size;    }
因此取size方法时,会增加

    /**     * Constructs a new {@code ArrayList} instance with zero initial capacity.     */    public ArrayList() {        array = EmptyArray.OBJECT;    }
而第二个对list进行操作,只是初始化了list对象,只是改变它的值,没改变全局变量的size,而调用clear方法有效

    /**     * Removes all elements from this {@code ArrayList}, leaving it empty.     *     * @see #isEmpty     * @see #size     */    @Override public void clear() {        if (size != 0) {            Arrays.fill(array, 0, size, null);            size = 0;            modCount++;        }    }


再看StringBuffer

    /**     * Adds the character array to the end of this buffer.     *     * @param chars     *            the character array to append.     * @return this StringBuffer.     * @throws NullPointerException     *            if {@code chars} is {@code null}.     */    public synchronized StringBuffer append(char[] chars) {        append0(chars);        return this;    }
    final void append0(String string) {        if (string == null) {            appendNull();            return;        }        int length = string.length();        int newCount = count + length;        if (newCount > value.length) {            enlargeBuffer(newCount);        }        string._getChars(0, length, value, count);        count = newCount;    }
变量变化时会调用底层,相当于把栈的值改变,而引用仍指向这个对象,当然会它的值会变了


1 0
原创粉丝点击