• Java数据传递实验



    本文来自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 stub
    		stringBuffer.append("db");
    	}
    
    	/**
    	 * @param list
    	 */
    	private void newList(List<String> list) {
    		// TODO Auto-generated method stub
    		list = new ArrayList<String>();
    	}
    
    	/**
    	 * @param list
    	 */
    	private void changeList(List<String> list) {
    		// TODO Auto-generated method stub
    		list.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;
        }
    变量变化时会调用底层,相当于把栈的值改变,而引用仍指向这个对象,当然会它的值会变了


  • 相关阅读:
    杭电ACM 1197
    杭电ACM 1196
    杭电ACM题目分类
    杭电ACM 1178
    指针转化(二重)
    怎么查看一个类的内存分布
    how find out what is causing Visual Studio to think each project is out of date
    MSB8013
    File mapping
    SHFileOperation 解决double-null terminated
  • 原文地址:https://www.cnblogs.com/hehehaha/p/6147352.html
Copyright © 2020-2023  润新知