这是我的第一个Hello.java类
public class Hello {
String name = "";
}
这是我的第二个Class Test1.java
public class Test1 {
public static void main(String[] args) {
Hello h = new Hello();
Test1 t = new Test1();
t.build(h);
System.out.println(h.name);
}
void build(Hello h){
h.name = "me";
}
}
当我运行Test1.java时,它会打印“我”。我想我理解,因为“参考转移”。
这是我的第三个Class Test2.java
public class Test2 {
public static void main(String[] args) {
Hello h = null;
Test2 t = new Test2();
t.build(h);
System.out.println(h == null);
}
void build(Hello h){
h = new Hello();
}
}
当我运行Test2.java时,它打印“true”,为什么?是不是“参考转移”?我很困惑。
答案 0 :(得分:7)
您可能知道,Java是按值调用的。 Wenn你传递了一个引用,该引用被复制了。确定:引用本身和不引用的目标被复制。
让我们看一下您的第一个示例:调用build()
时,将复制引用h
。由于h
(build()
中的副本)未被build()
中的某处覆盖,因此它始终指向原始h
的内存位置。因此,更改h.name
会影响原始h
。
示例2不同:参考h
也会被复制。但是h
会覆盖build()
。结果是h
中的原始h
和build()
指向不同的内存位置! h
中的build()
指向新生成的Hello
对象,在返回方法build()
后将对其进行垃圾回收。
答案 1 :(得分:3)
Java总是按值传递。当您有引用时,它只传递指向同一对象的引用的副本。在您的情况下,您只需将复制的引用重新路由到另一个对象。这就是为什么原来的一个没有改变的原因。
答案 2 :(得分:1)
您有两个不同的变量h
。第一个是main
的本地。第二个是build
的本地。
如果您将build
变量重命名为x
,那么h
中的main
不会受到影响的原因应该很明显。
编辑:
public class Test2 {
public static void main(String[] args) {
Hello h = null;
Test2 t = new Test2();
t.build(h);
System.out.println(((h == null)));
}
void build(Hello x){
x = new Hello();
}
}
您可以清楚地看到,x
以null
开头。然后x
成为新对象。然后x
死了。 h
对x
生活中发生的事情一无所知。
答案 3 :(得分:0)
h.name = "me"
更改h
引用的对象。从引用相同对象的任何其他位置可以看到此更改。 h = new Hello()
使h引用另一个(新)对象。此更改仅影响特定变量h - 而不影响先前引用同一对象的任何其他变量。
答案 4 :(得分:0)
答案 5 :(得分:0)
在Test1.java中,当您将Hello
对象h
传递给build()方法时,变量main().h
和build().h
指向内存中的同一对象。 / p>
即。 main().h = build().h => pointing same object
但是在Test2.java中,即使您将main().h
传递给build()方法,稍后在内部构建方法中,您也会将build().h
重新分配给新对象。但这不会影响main().h
即。 main().h != build().h
//他们都指出了不同的对象。
这就是main().h
仍包含null
并且您的程序打印为true的原因。
答案 6 :(得分:0)
首先,您需要了解Object和Reference之间的区别。
在第一种情况下,您直接访问对象(堆中的内存)并更改值,而在第二种情况下,引用将具有新的Object直到方法结束。之后它将无法再访问。
public static void main(String[] args){
String str = null;
System.out.println(getString(str)== null);
}
public static String getString(String s){
s = new String();
return s;
}
以上代码将打印 false
答案 7 :(得分:0)
说实话:
1)首先创建一个变量'h'并将其指向null
2)当你进入方法“void build(Hello h)”时,你创建一个新的variabel(也称为'h'),它被指向null(指向变量指向的指针是COPIED)。
3)当你执行'h = new Hello()'时,你将方法中的新'h'变量更改为指向Hello的新实例(new Hello())。
名为'h'的原始变量未更改。
简单如馅饼。
答案 8 :(得分:-1)
因为h等于null。