JAva Stringパラメータ伝達値とアドレス

3564 ワード

今日erlangを見て、1つの最も基本的な問題を見て、方法の呼び出しあるいは関数の呼び出しの時、パラメータの伝達の方式、みんなはすべてJavaの中で知っていて、基本的なタイプは値によって伝達する方式を通じて、パラメータの伝達を実現して、オブジェクトのタイプは引用の住所によって伝達して、しかしこの中に1つのJavaの中で基本的なタイプのオブジェクトとして、string、他の言語では、c++、erlangなどのStringの基本タイプは基本的にないので、JavaではStringというオブジェクトが特殊で、パラメータを渡すときも特殊です.
        次の例を示します.
       
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, 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:
     * 

     *      TC_STRING (utf String)
     * 
* The String is written by method DataOutput.writeUTF .
* 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の タイプと の タイプが うところなので、ネットでいろいろな を って、ソースコードを てみるとなぜか かります.
   オペレータ「+」によってstringオブジェクトの が されます.これは しc++の いオペレータの ロードを します.コンパイルするとき、Stringの には があります.この は、 プールに じstringがあれば、この のアドレスを え、なければnewでchar[]を します.また、concatのような2つのstringに するすべての は、new Stringによって しいStringオブジェクトを します.