我知道当将对象作为参数传递时,我实际上是在传递此对象的副本,但在这种情况下会发生什么:
public Base myMethod ()
{
Derived d = new Derived();
return (Base) d;
}
Base b = myMethod();
b
对象是Base类型的新对象,还是指向myMethod
堆中分配的下载Derived对象的指针?
答案 0 :(得分:2)
首先,你错了:在Java中,当一个对象作为参数传递时,你实际上传递了一个引用的副本,(比如在C或C ++中传递一个指针),所以对象本身永远不会被复制。复制确实发生在原始类型中,例如int或boolean。
在您的示例中,只分配了一个对象:d,并且假设Derived继承自Base,该对象将被提升为Base类型。实际上,转换是多余的,因为在Java中隐含了向上转换。
根据经验,只需查找new
关键字:如果存在,则表示您正在创建新对象。否则,您只是引用现有对象。
答案 1 :(得分:1)
我是后者。它只是指向Derived
类型对象的指针。
答案 2 :(得分:1)
将对象作为参数传递时,会将引用的副本传递给对象。
因此,在这种情况下,您将返回指向Derived
类型对象的引用副本。
请注意,由于垃圾收集,只要有一个句柄,你的对象就会保持安全,但是在C ++中,如果你返回一个指向堆栈上的东西的指针,你会留下未定义的行为。叫功能!
答案 3 :(得分:0)
“我知道当传递对象作为参数时,我实际上是传递了这个对象的副本”
这是不正确的。您正在传递对象的引用副本。
准确地说,b
不是一个对象。它是一个变量,Java中的变量永远不是一个对象。它可以是原始引用或对象引用(您可以将其视为有效的指针)。因此b
是(静态)类型Base
的引用,它引用/指向(动态/运行时)类型Derived
的对象。
答案 4 :(得分:0)
java中的对象总是由new
创建的对象,而不依赖于像C ++这样的转换。
答案 5 :(得分:0)
好的,我知道的是:
将对象作为参数传递,实际上是传递了对象的引用。因此,您需要使用.clone()来传递对象的副本。
在您的示例中,您的Base b实际上指向位于堆中的派生类型。
public void name(Derived d)
{
d.setName("hello");
}
//...
public static void main(String[] params)
{
Derived demon = new Demon();
name(demon);
System.out.println(demon.getName()); // will print hello
}
因为您刚刚传递了引用变量的副本。它仍然引用位于堆中的实际对象。