java String 参数传递 按值与地址_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > java String 参数传递 按值与地址

java String 参数传递 按值与地址

 2016/8/4 5:32:40  墙头上一根草  程序员俱乐部  我要评论(0)
  • 摘要:今天看erlang,看到一个最基本的问题,就是方法调用或函数调用时,参数传递的方式,大家都知道在Java中,基本类型是通过按值传递的方式,来实现参数传递,而对象类型则是通过按引用地址传递的,但是这个里面有一个Java里面被作为基本类型的对象,就是string,在其他语言中,基本上是没有String基本类型的,比如c++,erlang等,所以Java中,String这个对象比较特殊,他传递参数时候也比较特殊。下面一个例子:publicclassStringTest
  • 标签:Java

? ? ? ? ? ?今天看erlang,看到一个最基本的问题,就是方法调用或函数调用时,参数传递的方式,大家都知道在Java中,基本类型是通过按值传递的方式,来实现参数传递,而对象类型则是通过按引用地址传递的,但是这个里面有一个Java里面被作为基本类型的对象,就是string,在其他语言中,基本上是没有String基本类型的,比如c++,erlang等,所以Java中,String这个对象比较特殊,他传递参数时候也比较特殊。

? ? ? ? 下面一个例子

? ? ? ?

class="java" name="code">public class StringTest {

	public static void main(String[] args) {
		String value = "Hello World";
		String newValue = new String("Hello World2");
		System.out.println("change before value is:"+value);
		System.out.println("change before new value is:"+newValue);
		change(value);
		change(newValue);
		System.out.println("====================================");
		System.out.println("change after value is:"+value);
		System.out.println("change after new value is:"+newValue);
	}
	
	
	public static void change(String value){
		value = value+" change";
	}
}

? ? ? 上面的程序运行结果为:

? ? ? ? ?change before value is:Hello World

? ? ? ? ?change before new value is:value

? ? ? ? ?====================================

? ? ? ? change after value is:Hello World

? ? ? ? change after new value is:value

?

? ? ?从上面的运行结果可以看出来,不管string是直接通过 “=”赋值,或者是通过new的方式赋值,方法调用之后,他的值都没有改变,也就是说,不管这个string是在常量池中或者堆内存中,他的值都不会改变,这样string的参数传递就和其他的基本类型不一样了,虽然Java中string类型是基本类型。

? ? 为什么会有上面的结果呢,网上有人说,string的值是在常量池中,所以不会改变,但是我们用new的方式,他也是没有改变呢。其实解释这个原因很简单,简单到看一下源码就行了。以下是string的源码:

? ? ? ?

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence
{
    /** The value is used for character storage. */
    private final char value[];

    /** The offset is the first index of the storage that is used. */
    private final int offset;

    /** The count is the number of characters in the String. */
    private final int count;

    /** Cache the hash code for the string */
    private int hash; // Default to 0

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -6849794470754667710L;

    /**
     * Class String is special cased within the Serialization Stream Protocol.
     *
     * A String instance is written initially into an ObjectOutputStream in the
     * following format:
     * <pre>
     *      <code>TC_STRING</code> (utf String)
     * </pre>
     * The String is written by method <code>DataOutput.writeUTF</code>.
     * A new handle is generated to  refer to all future references to the
     * string instance within the stream.
     */
    private static final ObjectStreamField[] serialPersistentFields =
        new ObjectStreamField[0];

    /**
     * Initializes a newly created {@code String} object so that it represents
     * an empty character sequence.  Note that use of this constructor is
     * unnecessary since Strings are immutable.
     */
    public String() {
	this.offset = 0;
	this.count = 0;
	this.value = new char[0];
    }

? ? 从源码中可以知道,string的实现是通过char[] 数组的形式,之所以String对象不管怎么整都不会改变是因为,String对象是一个final对象,就是不变的对象,里面的属性也是不变的对象,所以不管你怎么弄他都是不变的,这个就是String基本类型和其他基本类型不一样的地方,所以网上说各种原因的,看一下源码就知道为什么了。

? ?通过caozuofu.html" target="_blank">操作符 “+”,来实现string对象的相加,这个就是有点c++重的操作符重载的意思了,编译的时候,String的相加会有优化,这个优化就是如果常量池中有同样的string就会给他赋为这个变量的地址,如果没有就会通过new的方式创建一个char[],还有string中的所有有关两个string的操作比如concat这种方法,都是通过new String的方式返回新的String对象。

发表评论
用户名: 匿名