1、问题描述
java方法传String类型的参数时,为啥方法对值的修改没有在方法之外生效?假设是其他类型的对象,那么方法对对象的数据的修改是会在方法之外生效的啊,可是String类型也是对象类型啊,为啥就没有在方法之外生效呢?
2、代码示例
//示例1:对象类型
public class PassReferByValue
{
String a = "123";
public static void test(PassReferByValue test)
{
test.a = "abc";
}
public static void main(String[] args)
{
PassReferByValue test = new PassReferByValue();
System.out.println("对象的数据的初始值是:" + test.a); //123
test(test);
System.out.println("通过调用test方法修改对象的数据的值之后:" + test.a); //abc
}
}
总结:因为是对象类型,所以方法每次修改对象的数据的值之后,都在方法之外生效了,也就是说,在方法之外和在方法之内访问到的对象的数据的值是一致的。
//示例2:String类型
public class Test
{
public static void test(String str)
{
str = "word";
}
public static void main(String[] args)
{
String string = "hello";
System.out.println("对象的数据的初始值是:" + string); //hello
test(string);
System.out.println("通过调用test方法修改对象的值之后还是以前的值:" + string); //hello
}
}
总结:如果方法的参数是String类型,虽然方法修改了它的值,但是并没有在方法之外生效,也就是说,在方法之外和在方法之内的访问到的值不一样!!!这是为什么???
3、网上的解释
String等immutable类型因为没有提供自身修改的函数,每次操作都是新生成一个对象,所以要特殊对待。
http://blog.csdn.net/fbysss/article/details/3082949
这样的解释太肤浅了,完全是基于文字的描述,有没有基于代码层面的解释,或者其他的更深层次的解释呢?
Mengikut pemahaman anda
Contoh 1 memang benar
对象的数据的修改
, tetapi contoh 2 adalah benar参数本身的修改
Sama ada ia melalui nilai atau lulus melalui rujukan, ia pada asasnya sama dengan
.值传递
Apabila kaedah dipanggil, nilai parameter dikira dan salinan diberikan kepada parameter yang sepadanHanya untuk jenis objek, nilai rujukan (atau difahami sebagai penunjuk, alamat) objek dihantar Walaupun parameter mendapat rujukan yang disalin, ia menunjuk ke objek yang sama dengan rujukan asal, jadi menurut rujukan ini, anda boleh Mengendalikan data objek asal
Dalam contoh kedua anda, apabila memanggil kaedah, hitung nilai parameter
string
(yang boleh difahami sebagai alamat objek rentetanhello
dalam ingatan) dan salin ke parameterstr
, walaupun parameterstr
Mendapat rujukan kepada objek rentetanhello
asal (iaitu, nilaistr
adalah sama dengan nilaistring
, iaitu alamathello
), tetapi serta-merta menetapkan semula parameter ini. Pada masa ini, parameterstr
telah diikuti oleh rentetanhello
tiada kaitan antara satu sama lainstr
tidak lagi menunjuk kehello
, tetapi sebaliknya, dalam proses ini, alamatworld
itu sendiri danhello
dalam ingatan tidak berubah sama sekali, di luar kaedah Pembolehubahhello
sentiasa menunjuk ke objek rentetanstring
tanpa sebarang perubahanhello
.Untuk meringkaskan dalam tiga ayat:
1
对象
ialah传引用
2
原始类型
ialah传值
3. Fungsi pengubahsuaian, setiap operasi menjana objek baru, jadi ia mesti dirawat secara khusus. Ia boleh dianggap sebagai lulus mengikut nilai.
String,Integer, Double
Integer adalah sama dengan String. Pembolehubah kelas yang memegang nilai ialah sifat Akhir dan tidak boleh diubah suai Ia hanya boleh ditugaskan semula/menjana objek baharu. Apabila Integer dihantar ke dalam kaedah sebagai parameter kaedah, tugasan kepadanya akan menyebabkan rujukan Integer asal dihalakan ke alamat tindanan dalam kaedah, kehilangan penunjuk ke alamat pembolehubah kelas asal. Sebarang operasi yang dilakukan pada objek Integer yang ditetapkan tidak akan menjejaskan objek asal.Perihalan pautan
test1.a = "567"
, perkara yang anda ubah di sini ialah atributtest1
objek yang dirujuk olehstr = "word"
Perkara yang anda ubah di sini ialah objek yang ditunjuk oleh pembolehubah rujukanstr
.Ringkasnya, ada dua, Xiao Ming dan Xiao Hong Jika anda menggantikan tangan Xiao Ming dengan tangan robot, tangan Xiao Ming benar-benar akan ditukar, tetapi jika anda menukar nama Xiao Hong kepada Xiao Ming... Xiao Hong sendiri masih tidak berubah.
Deeper, Xiao Ming dan Xiao Hong akan menyertai acara ini tidak memerlukan anda mengetahui nama sebenar anda, jadi mereka diberikan nama kod A dan B. Pada masa ini, A telah cedera semasa melakukan aktiviti dan pemegangnya digantikan dengan yang mekanikal Akibatnya, selepas aktiviti itu, tangan Xiao Ming sememangnya telah digantikan dengan yang mekanikal. Tetapi B baru sahaja menukar tanda nama kepada C. Selepas keluar, Xiao Hong masih lagi Xiao Hong dan belum menjadi orang yang sepadan dengan C.
Di sini, aktiviti ialah kaedah, dan kod yang ditetapkan ialah parameter formal Penetapan langsung nilai kepada parameter formal tidak akan menjejaskan parameter sebenar, tetapi memberikan nilai kepada sifat objek yang dirujuk oleh. parameter formal sebenarnya telah mempengaruhi sifat objek.
Saya akan menambah sekeping kod dengan ulasan untuk melihat sama ada ia boleh membantu anda memahami. Jika anda ingin memahami bahawa proses sebenar panggilan kaedah juga melibatkan pengetahuan seperti timbunan, ia tidak begitu rumit. Kod ini tidak mempunyai output Anda boleh cuba menambah beberapa output selepas memahaminya untuk mengesahkan sama ada pemahaman anda betul.
Lulus mengikut nilai, lulus dengan rujukan
Kecuali untuk String, Objek lain dalam Java diluluskan melalui rujukan.
Saya menyebut perkara pengetahuan yang berkaitan pada permulaan salah satu lajur saya memandangkan anda agak keliru, saya ingin mengesyorkannya kepada anda.
Rentetan ialah jenis tidak berubah, yang bermaksud nilainya tidak berubah. Contohnya,
String a = "abc"
, dalam ingatan, rujukan a menghala ke blok memori "abc". Apabila menggunakana = "bcd"
, nilai blok memori di mana "abc" terletak tidak ditukar kepada "bcd", tetapi rentetan lain dihasilkan "bcd", dan kemudian arahkan a ke "bcd", jadi rujukan di luar kaedah masih menunjuk ke memori "abc".Jenis pembolehubah secara langsung akan mengubah suai nilai memori di mana "abc" terletak Dengan cara ini, rujukan di luar kaedah masih menghala ke alamat memori asal, jadi nilai yang diubah suai boleh diakses di luar kaedah.
Rentetan yang terkandung dalam objek String tidak boleh diubah suai Apabila pembolehubah jenis String ditetapkan semula, rujukannya juga akan berubah dan menjadi objek baharu.