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