[英]Role of new keyword in Java
我不确定new
关键字在Java中的表现如何。 是否可以确保每次使用new
关键字时,都会在堆上创建一个新的Object?
当我在学习以下示例时,我对此产生了怀疑
class Mixer {
Mixer() { }
Mixer(Mixer m) { m1 = m; }
Mixer m1;
public static void main(String[] args) {
Mixer m2 = new Mixer();
Mixer m3 = new Mixer(m2); // Does it create any new mixer object?
m3.go();
Mixer m4 = m3.m1; m4.go();
Mixer m5 = m2.m1; m5.go();
}
void go() { System.out.print("hi "); }
}
线Mixer m3 = new Mixer(m2);
调用不创建任何新对象的构造函数。 那么,是不是没有创建新对象?
另外,哪个变量引用程序末尾的哪个对象,即直到我们得到变量m5
NullPointerExcetion
。
是 - 每次使用new
(作为关键字)时,都会创建一个新对象。 在这种情况下:
Mixer m3 = new Mixer(m2);
线混合器m3 =新混合器(m2); 调用不创建任何新对象的构造函数。
你的推理是完全错误的。 正在使用m2
作为参数创建新的Mixer
。 通常这表示一个复制构造函数 - 创建一个具有与旧属性相同的属性的新混合器(但它始终是一个新的,不同的对象,并且在技术上不必复制传入的对象的属性。)
new总是创建一个新实例(所以总是保留堆内存等)。
这应该说明一下。 请注意,实例上的==将告诉您它是相同的实例(对象)还是不同的实例。 (这就是为什么你应该总是使用equals,除非这是你想要做的)
我添加了一个有趣的事情发生在字符串。 “abc”不会创建新实例,但会重用现有实例。 但是当你在String类上调用new时它会这样做。
public class Test {
private String value;
public String getValue() {
return value;
}
public Test() {
value = "default";
}
public Test(Test t) {
this.value = t.getValue();
}
public Test(String value) {
this.value = value;
}
public static void main(String[] argv) {
Test t1 = new Test();
Test t2 = new Test(t1);
if (t1 == t2) {
System.out.println("t1 == t2. should not happen");
} else {
System.out.println("t1 is a different instance from t2");
}
String s1 = "test";
String s2 = "test";
if (s1 == s2) {
System.out.println("s1 == s2. strings initialized with quotes don't always get a new instance.");
} else {
System.out.println("s1 is a different instance from s2. should not happen");
}
String s3 = new String("test");
String s4 = new String(s3);
if (s3 == s4) {
System.out.println("s3 == s4. should not happen.");
} else {
System.out.println("s3 is a different instance from s4, as they were newed.");
}
}
}
从程序员的角度来看, new
会导致创建一个新对象。
但是,编译器可以执行转义分析以确定是否确实需要在运行时在堆上创建对象。
对于您的上一个问题,您的代码会创建两个对象。 一个由m2,m3.m1和m4引用,另一个由m3引用。
首先,忘记堆栈/堆的区别 - 这是编译器或运行时的实现细节(取决于所讨论的语言)。 如果您使用C或汇编进行系统编程,那么它可能会有所不同,但是当您在垃圾收集语言和Java或.NET等环境中工作时,它可能会有所不同。
并回答你的问题: new
实际上在大多数(?)(所有?)语言中都有两个具有这种运算符的语言。 它首先在某处分配内存以容纳该类型的实例,然后调用构造函数来初始化该新分配的内存中的该类型的实例。 然后构造函数链接可能会导致调用其他构造函数(在相同类型,类型的基类/超类或类型的构造函数需要执行其工作的任何内容上)。
正如@ berry120所指出的,构造函数采用与构造函数类型相同类型的参数通常表示复制构造函数。 实现相同结果的另一种方法是对clone()
方法进行显式调用,该方法返回调用它的对象的副本。
它确实创建了一个新对象,并且它的构造函数传递了对您已经创建的另一个对象m2
的引用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.