public class Test2
{
public static void changeStr(String str){
str = "welcome";
}
public static void main(String args[]){
String str = "1234";
changeStr(str);
System.out.println(str);
}
}
这段代码的输出结果是:1234.可是我不明白,为什么调用了changeStr这个方法后,没有改变?本人小菜一个,大家多看看.谢谢
{
public static void changeStr(String str){
str = "welcome";
}
public static void main(String args[]){
String str = "1234";
changeStr(str);
System.out.println(str);
}
}你如果想通过changStr()方法改变输出,就不能在main里面搞输出啊,main里面看到的总是自己的str
str = "welcome";
}
public static void main(String args[]){
String str = "1234";
changeStr(str);
System.out.println(str);
}
传递的参数是一个引用类型的时候,修改的并不是该引用的指向对象,修改的是指向对象中的属性的值,而String对象的值是不可改变的,当在changeStr中执行str="welcome"时是在string常量池中新建了一个"welcome"对象,修改了str指向的对象,所以在main方法中对str的修改是不起作用的。 在java中String是一个特殊的类,要了解其内部的原理才可以灵活运用
public class Test2
{
public void changeStr(String str){
str.toCharArray()[2] = 'w';
}
public static void main(String args[]){
String str = "1234";
new Test2().changeStr(str);
System.out.println(str);
}
}真正的原因在于String被设计成不可变(immutable)类,在一个方法中,只要没有两次对一个string变量赋值,则这个string变量代表的对象永远不会改变.如果希望一个string变量可变值,则需要stringbuffer类,它能够避免产生过多的string对象,因此能够极大的提高程序效率.
{
public void changeStr(String str){
str.toCharArray()[2] = 'w';// 3
}
public static void main(String args[]){
String str = "1234";// 1
new Test2().changeStr(str);// 2
System.out.println(str);//4
}
}
1,main.str->1234
2,changStr.str->main.str->1234
3,changStr.str->w
4,sysout:main.str->1234
java是传地址的拷贝的,简单点说就是传值
{
public static String changeStr(String str){
str = "890";
return str;
}
public static void main(String args[]){
String str = "1234";
String i=changeStr(str);
System.out.println(i);
}
}
比如 ,你要把 public void changeStr(String str)改为 public void changeStr(),那么运行的结果就不一样了 。 public void changeStr(String str)中的STR是属于局部变量 ,而main函数里面使用的是全局变量STR,这两个是放在不同的内存位置,一个是全局数据区 ,一个是栈里面,所以main函数里面的调用的是全局的而不是局部的。
另外,java里面的参数传递是按照值传递的,传递的是值,而不是地址,如果是不含参数的方法,则str表示还是全局的变量,所以输出的结果为890.
String是个类,str是个引用变量,"1234"此时是对象内容。
Java是值传递,此时值传递要分两种:1--加入你传的primirive类型的,就会把值直接传进去,而多于reference的,就会传对象的首地址的值,就是一个引用。
你是把str 这个引用传进去了,相当于copy个str进changeStr()方法,进入这个方法后,你把"welcome"复制给str,此时的str是你传进来的对象的首地址即是相当于你把"welcome"赋值给个str的副本,你在main()方法里打印的str不是copy的str实际上是:str.toString() , str通过toString()方法找到对象内容"1234",你打印的就是"1234".
加入你把public static void changeStr(String str)改成public static changeStr(String str);
str = "welcome";改成return str = "welcome";打印结果仍然是"1234"。changeStr(str);改成str = changeStr(str);
那么打印结果就不一样了
2、这种调用属于传值.
3、两个变量在内存中,分配的是两个不同的内存地址.
个人觉得最简单的理解就是:所以传过来的对象值本身不能修改--即对应的内存堆栈地址是不变的所以就分三种了:
1、传过来是对象直接在内存堆栈里的值:int, long之类的,就不能改变
2、String之类的,String很特殊的,改变值时用到了享元模式(Flyweight Pattern),copy on write技术实现,所以,改变不了堆栈指针所引用内存地址在值
3、一般的对象,不能改变地址,即想把引用变成别的对象引用地址,不成的,但可以改变引用 地址所指向内存地址的值
public class Test2
{
public void changeStr(String str){
str = "welcome";
}
public static void main(String args[]){
String str = "1234";
new Test2().changeStr(str);
System.out.println(str);
}
}
2.跟String的不可改变和StringBuffer也没有一点关系,下面结果还是一样!public class Test2 {
public void changeStr(StringBuffer str){
str = new StringBuffer("welcome");
}
public static void main(String args[]){
StringBuffer str = new StringBuffer("1234");
new Test2().changeStr(str);
System.out.println(str);
} }3.只是JAVA中传参的小问题,用下面这个例子分析:
package org.leno;public class Student {
private String username;public Student(String username) {
super();
this.username = username;
}public String getUsername() {
return username;
}public void setUsername(String username) {
this.username = username;
}
}public class Test2 {
public void changeStr(Student str2){
str2 = new Student("welcome");
}
public static void main(String args[]){
Student str = new Student("1234");
new Test2().changeStr(str);
System.out.println(str.getUsername());
}
}
虽然传参的时候str和str2指向同一个学生对象,但在方法里面我们将str2变量指向了其它对象,而这时候的str
还是指向原来的学生对象,所以打印出来的依然是原来学生的名字。浅显点说就是和下面的情况差不多:
Student str = new Student("1234");
Student str2 = str;
str2 = new Student("welcome");
System.out.println(str.getUsername());
打个比方就是两根线都栓着同一个宠物,而后来一根线栓向另一个宠物去了,(虽然这根线很快就消失了,
没有任何意义,局部变量嘛!),但原先的线栓的宠物是没有任何改变的!
更多JAVA知识就去我的博客上看看,希望您能有收获!
http://blog.csdn.net/lenotang