论坛首页 Java企业应用论坛

一个绝对害了不少人的Java技术问题!

浏览 92912 次
该帖已经被评为精华帖
作者 正文
   发表时间:2004-11-24  
真服了你们了。还讨论呢。

java中只有call-by-value。

但是研究call-by之前,要搞清楚的是java中变量的语义。

你是通过变量来操作原始类型和对象的。

java的变量有两种语义,原始类型的变量时值语义。(c#的value type就是原始值类型的扩展而已)
也就是说,你给一个原始类型变量赋值,就改变了这个数据值本身。
对象类型的变量是引用语义。
也就是说,给一个对象类型的变量赋值只是让它指向另一个对象,但不改变原来引用的那个对象的值。


然后看call-by, 对原始类型,变量的value就是这个整数/字符的值。没啥说的。
对对象类型,变量的value是个引用,所以call-by-value所拷贝的仍然是引用。
0 请登录后投票
   发表时间:2004-11-30  
引用
凤舞凰扬
技术的永远追随者
public void call(Test t) {
Test t2 = new Test();
t2.setName("cba');
t.setName("abc");
t = t2 ;
}

public static void main(String[] arg) {
Test obj = new Test();
call (obj) ;
System.out.println("obj"+obj.getName());
}

其实你的理解有误,java的对象传递还是通过引用的方式进行。
注意:当调用call的时候,相当于t=obj;
所以你上边的代码可以变成如下:
public static void main(String[] arg); { 
Test obj = new Test();; 
Test t=obj;
Test t2 = new Test();; 
t2.setName("cba');; 
t.setName("abc");; 
t = t2 ; 
System.out.println("obj"+obj.getName(););; 
} 

当调用了t.setName("abc")的时候,相当于是obj.setName("abc"),修改的是obj.name对应的地址上的值。
而t=t2时,只是把t的指向了新的对象了t2,但是原来的引用obj并没有变化,
所以自然obj.getName()是abc咯,哈哈哈
0 请登录后投票
   发表时间:2004-12-07  
这个问题和对象的初始化也有点关系
new xxx() 返回的应该是一个对象的引用,既这个对象的地址的值....
xxx x = new xxx() 把 xxxx 变量的地址指向了 xxx对象的地址
参数的传递也应该如此
因此可以说java只有值传递
个人见解
0 请登录后投票
   发表时间:2004-12-07  
感觉java的初始化是个很复杂的过程...
0 请登录后投票
   发表时间:2005-01-27  
pass by copy (reference or prototype)
0 请登录后投票
   发表时间:2005-02-10  
好细致的一个问题,看得有点头昏。
我的理解是:值传递。既然是传值,所以obj和t就不是同一个变量。不过直觉上总还是以为obj和t是同一个变量。
0 请登录后投票
   发表时间:2005-02-16  
实际上这问题要找好多的,比如说你在WEB开发中,有关中文转码问题,用oracle还好,可以用过滤器,如果用方法实现,别人不知道,我就有过第一次转成中文,第二个相同的STRING对象就转成了????
0 请登录后投票
   发表时间:2005-02-18  
我来发表一下我的看法!
我认为你们的所谓的拷贝论是不成立的.
0 请登录后投票
   发表时间:2005-02-18  
先引用两段代码:
public class Testit { 
private String name; 

public String getName(); { 
return name; 
} 

public void setName(String name); { 
this.name = name; 
} 

public static void main(String[] args); { 
Testit a = new Testit();; 
a.setName("a");; 
Testit b = new Testit();; 
b.setName("b");; 
System.out.println("before swap: " + "a=" + a + " name: " + a.getName(););; 
swap(a,b);; 
} 

private static void swap(Testit swap1, Testit swap2); { 
System.out.println("swaping: " + "a= " + swap1 + " name: " + swap1.getName(););; 
Testit temp; 
temp = swap1; 
swap1 = swap2; 
swap2 = temp; 
} 

} 


第二:
public class Testit { 
private String name; 

public String getName(); { 
return name; 
} 

public void setName(String name); { 
this.name = name; 
} 

public static void main(String[] args); { 
Testit a = new Testit();; 
a.setName("a");; 
Testit b = new Testit();; 
b.setName("b");; 
System.out.println("before swap: " + "a=" + a + " name: " + a.getName(););; 
swap(a,b);; 
System.out.println("after swap: " + "a=" + a + " name: " + a.getName(););; 
} 

private static void swap(Testit swap1, Testit swap2); { 
Testit temp; 
temp = swap1; 
swap1 = swap2; 
swap2 = temp; 
swap1.setName("a's name");; 
swap2.setName("b's name");; 
} 

} 



打印的结果大家都知道了,我来分析一下原因.
其实我认为:作为对象,传递的应该是句柄!
在这两种情况下,JVM里应该主要有这么几个对象句柄:
1.a
2.b
3.a.name
4,.b.name
第一种情况下,把a的句柄传进以后,对于a.name来说,并没有改变
第二种情况下,把a的句柄传进以后,做了setName(),也就相当与把a.name改变了
所以......
0 请登录后投票
   发表时间:2005-02-26  
For every parameter declared in a method declaration, a new parameter variable is created each time that method is invoked.The new varaible is initialized with the corresponding argument value from the method invocation.

按照JLS的描述,方法中的变量都是值传递,对于primitive类型,传递的是类型的实际数值,对于reference类型,传递的是reference本身的值(不是reference本身也不是reference指向的对象)
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics