锁定老帖子 主题:一个绝对害了不少人的Java技术问题!
该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2004-11-24
真服了你们了。还讨论呢。
java中只有call-by-value。 但是研究call-by之前,要搞清楚的是java中变量的语义。 你是通过变量来操作原始类型和对象的。 java的变量有两种语义,原始类型的变量时值语义。(c#的value type就是原始值类型的扩展而已) 也就是说,你给一个原始类型变量赋值,就改变了这个数据值本身。 对象类型的变量是引用语义。 也就是说,给一个对象类型的变量赋值只是让它指向另一个对象,但不改变原来引用的那个对象的值。 然后看call-by, 对原始类型,变量的value就是这个整数/字符的值。没啥说的。 对对象类型,变量的value是个引用,所以call-by-value所拷贝的仍然是引用。 |
|
返回顶楼 | |
发表时间: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咯,哈哈哈 |
|
返回顶楼 | |
发表时间:2004-12-07
这个问题和对象的初始化也有点关系
new xxx() 返回的应该是一个对象的引用,既这个对象的地址的值.... xxx x = new xxx() 把 xxxx 变量的地址指向了 xxx对象的地址 参数的传递也应该如此 因此可以说java只有值传递 个人见解 |
|
返回顶楼 | |
发表时间:2004-12-07
感觉java的初始化是个很复杂的过程...
|
|
返回顶楼 | |
发表时间:2005-01-27
pass by copy (reference or prototype)
|
|
返回顶楼 | |
发表时间:2005-02-10
好细致的一个问题,看得有点头昏。
我的理解是:值传递。既然是传值,所以obj和t就不是同一个变量。不过直觉上总还是以为obj和t是同一个变量。 |
|
返回顶楼 | |
发表时间:2005-02-16
实际上这问题要找好多的,比如说你在WEB开发中,有关中文转码问题,用oracle还好,可以用过滤器,如果用方法实现,别人不知道,我就有过第一次转成中文,第二个相同的STRING对象就转成了????
|
|
返回顶楼 | |
发表时间:2005-02-18
我来发表一下我的看法!
我认为你们的所谓的拷贝论是不成立的. |
|
返回顶楼 | |
发表时间: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改变了 所以...... |
|
返回顶楼 | |
发表时间: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指向的对象) |
|
返回顶楼 | |