作者:幸运幸福一家人1314_332_887 | 来源:互联网 | 2022-12-27 19:29
publicclassTestString{publicstaticvoidmain(String[]args){TestStringmyTsnewTestString();
public class TestString{
public static void main(String[] args){
TestString myTs=new TestString();
myTs.run();
}
private void run(){
String ts=null;
Integer i=new Integer(0);
System.out.println("Before the change ts and i respectively equals "+ts+","+i.intValue());
changeTs(ts,i);
System.out.println("After the change ts and i respectively equals "+ts+","+i.intValue());
}
private void changeTs(String ts,Integer i){
ts="Something";
i=new Integer(1);
System.out.println("During the changing process ts and i respectively equals "+ts+","+i.intValue());
}
}
20 个解决方案
在java里面只要是对象就应该是引用传递,除此之外的int,float,double等类型是值传递,但是我的例子中String和Integer不是引用传递,在方法里面改变了它们的值,但是方法调用完后,它们的值依然没有变。
private void run(){
String ts=null; //这里ts为null,它没有指向任何内存,怎么会变呢??
Integer i=new Integer(0);
System.out.println("Before the change ts and i respectively equals "+ts+","+i.intValue());
changeTs(ts,i);
System.out.println("After the change ts and i respectively equals "+ts+","+i.intValue());
}
private void changeTs(String ts,Integer i){
ts="Something"; //要知道这里的ts和上面的ts是两个指针,这个指向了一个内存,但原先的ts指向的是null,也就没有改变一说了...
i=new Integer(1); //这里你给i有新开辟了一块内存,这个i变了,但原来还是指向自己的地址..
System.out.println("During the changing process ts and i respectively equals "+ts+","+i.intValue());
}
修改后:
private void run(){
String ts="one";
Integer i=new Integer(0);
System.out.println("Before the change ts and i respectively equals "+ts+","+i.intValue());
changeTs(ts,i);
System.out.println("After the change ts and i respectively equals "+ts+","+i.intValue());
}
private void changeTs(String ts,Integer i){
ts="Something";
i= ... //你的例子太特殊,Integer没有改变的方法 :(
System.out.println("During the changing process ts and i respectively equals "+ts+","+i.intValue());
}
现在你看你的ts是否变化了??
------------------------------------------------------
我们还年轻牛奶会有的奶牛也会有的
可天天在 csdn 混这些会有吗 ??
楼主 首先说明一下在JAVA中所有的对象传递都是引用传递。
代码分析:
一.在run()方法调用changeTs(String ts,Integer i)时 String ts=null;注意ts=null字符 串ts并没有被实例化,所以ts只是一个没有指向任何内存地址的空指针。
二.方法changeTs(String ts,Integer i)中ts="Something"; i=new Integer(1);
首先"Something" 代表了一个在内存中分配了地址的字符串, 语句ts="Something"; 将ts空指针指向"Something",注意是将ts指针指向"Something" 而不是改变ts指针所指向内存地址的内容。
你可以试一下将String 该成Label 代码如下:
public class TestString{
public static void main(String[] args){
TestString myTs=new TestString();
myTs.run();
}
private void run(){
Label ts= new Label();
Integer i=new Integer(0);
System.out.println("Before the change ts and i respectively equals "+ts.getText()+","+i.intValue());
changeTs(ts,i);
System.out.println("After the change ts and i respectively equals "+ts.getText()+","+i.intValue());
}
private void changeTs(Label ts,Integer i){
ts.setText("Something");
i=new Integer(1);
System.out.println("During the changing process ts and i respectively equals "+ts.getText()+","+i.intValue());
}
}
to:zez(思恩 为老婆多挣钱 鹤清风)
试过了,你这样字符串的值还是没有改变的
changeTs(ts,i);
这里传进去的只是ts和i的一个副本!
除了数组、BufferString之类的都是值传递。
出了函数变会原来的值
JAVA中所有的对象传递都是引用传递
前提就是句柄只是对象的一个“别名”,
参见《java编程思想》
i=new Integer(1)
这种使用是采用了Integer包装类的技术,1是按值传递到Integer类中的
Integer类大概象:
class Integer
{
private int i;
Integer(int i)
{
this.i=i;
}
public int intValue()
{
return this.i;
}
........
}
java中只有String类的对象和基本数据类型是值传递,其他类的对象是引用传递。
public class TestString{
public static void main(String[] args){
TestString myTs=new TestString();
myTs.run();
}
private void run(){
object1 ts= new object1(1);
object2 i=new object2(1);
System.out.println("Before the change ts and i respectively equals "+ts.getText()+","+i.intValue());
changeTs(ts,i);
System.out.println("After the change ts and i respectively equals "+ts.getText()+","+i.intValue());
}
private void changeTs(Label ts,Integer i){
ts.a=2
i=new object(2)
System.out.println("During the changing process ts and i respectively equals "+ts.getText()+","+i.intValue());
}
}
object1,object2是一个对象有一个int的属性。
你会发现object1改变了,而object2没变!
这是因为在方法里面是局部变量,作用域在方法内部!
与外部的是两个不同的变量!开始的时候是同一个引用!
这个问题其实非常简单:
因为String类型的对象将数据存储在一块连续的存储空间中
如:
String s1="aaaa";//“aaaa”是连续存放的
所以每此给s1赋值的时候(为了保证字符串放在连续的存础空间中),都会重新为它分配存储空间,也就是说以前的存储空间就会丢掉
举个例子
String s1="aa";//假设s1的地址是"0000"
String s2;
s2=s1;//s2的地址是"0000";(s1将引用传给s2)
s1="bb";//重新为s1分配内存空间
System.out.println("s2");//打印出来的是"aa"
参见:
http://expert.csdn.net/Expert/topic/1760/1760533.xml?temp=.7156946
应该很明了的。
呵呵,我的一点疏忽...
String类是不变类,你的ts="aaa"相当于ts= new String("aaa"),也就是重新开辟一块内存,内容为aaa,ts指向它... 所以你的方法里给ts赋值,原来的ts还是原来的ts...
ts="one" 相当于 ts--->"one"
方法体引用ts,要知道,
方法体内的ts是原ts的副本,这时 原ts---->"one"
|
副ts-------| 即副ts也指向了"one"
好,现在执行方法,副ts="bbb"这时:
原ts---->"one"
副ts---->"bbb"
看到了吧,原ts根本没变 !!!
至于Integer,我没找到改变它的值的方法,好像也是不变类? 我不确定 :)
对于其他情况,比如 Class Test{
int i;
Test(i){this.i=i;}
} //只是示意 :)
这时的情况呢,把你原程序的String换成 Test.则
开始: Test ts = new Test(0); 即 ts-----> Test.i=1;
方法体引用ts,要知道,
方法体内的ts是原ts的副本,这时 原ts----> Test.i=1;
|
副ts-------| 即副ts也指向了同一个地址
好,现在执行方法ts.i=2; 这时:
原ts---->"one"
|
副ts-------|注意,修改的是副ts指向的内存的值!!也即原ts指向的地址 !!!
看到了吧,原ts现在变了...
------------------------------------------------------
我们还年轻牛奶会有的奶牛也会有的
可天天在 csdn 混这些会有吗 ??
好,现在执行方法ts.i=2; 这时:
原ts------>Test.i=2
|
副ts-------| 注意,修改的是副ts指向的内存的值!!也即原ts指向的地址 !!!
看到了吧,原ts现在变了...
------------------------------------------------------
我们还年轻牛奶会有的奶牛也会有的
可天天在 csdn 混这些会有吗 ??
总是看见有一撮人十分肯定的说java的对象是传引用的,不知道这些人的真实意图。
那个谁谁,不要再这里误导新手。建议大家去看官方文档。是英文的,看不懂就记住结论吧,java里面参数是传值的。
http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html
When the argument is of reference type, pass-by-value means that the method cannot change the object reference, but can invoke the object's methods and modify the accessible variables within the object.
当参数是引用类型时,你能通过调用该引用所指向的对象本身的方法来改变对象自身,但是,你并不能改变该引用。(你改变的只能是引用所指向的对象,而不是引用。所以,仍然是值传递。)