在Java中,可以在类的构造函数内部使用"new"来调用另一个构造函数吗?

12

我知道this(...)用于从一个构造函数调用另一个构造函数。但是我们能否使用new来达到相同的效果?

更明确地说,第二行代码是否有效?如果它是有效的(因为编译器没有抱怨),那么为什么输出是null而不是Hello

class Test0 {
    String name;

    public Test0(String str) {
        this.name= str;
    }

    public Test0() {
        //this("Hello");    // Line-1
        new Test0("Hello"){}; // Line-2
    }

    String getName(){
        return name;
    }
}

public class Test{
    public static void main(String ags[]){
        Test0 t = new Test0();
        System.out.println(t.getName());
    }
}

1
你为什么想要这样做? - user1907906
1
@Lutz Horn,我在某个地方看到了这样的代码,我想了解其中的基本原理。 - Dexter
3
你确定这是和你的代码同义的代码吗?这段代码可以编译,但像这样没有任何意义。 - user1907906
1
看起来像是一个糟糕的拼图。 - AdamSkywalker
@Lutz 是的,它编译没有错误。我使用的是带有JDK 6的Eclipse IDE。 - Dexter
7个回答

25

它是有效的,但它在构造函数内创建了一个完全独立的Test0实例(更具体地说,是Test0的一个匿名子类的实例),并且它没有被任何地方使用。当前实例仍然将字段name设置为null

public Test0() {
    // this creates a different instance in addition to the current instance
    new Test0("Hello"){};
}
请注意,如果您使用无参数构造函数调用new操作符,则会出现StackOverflowError错误。

9
实际上,它并不是创建 Test0 类的一个实例本身,而是创建了一个匿名子类的实例。在这种情况下,这并不会改变什么,因为对象最终还是被丢弃掉了。 - Paŭlo Ebermann

6
您试图完成的任务可以通过您注释掉的代码来实现:

您试图完成的任务可以通过您注释掉的代码来实现:

public Test0()
{
    this("Hello");
}

5

第二行是有效语句。这就是为什么编译器没有显示任何错误的原因。但你创建了一个匿名对象。一旦你从构造函数中退出,它将很快消失。因此,这个值仍然是null,因为没有给它分配任何值。

new Test0("Hello"){};

上面这行代码将创建一个Test0类的匿名实例,并将Hello的值赋给name变量。但由于您没有引用创建的匿名实例,它会在该行之后立即消失。因此,您仍然没有为调用特定代码段的实例的name变量分配值。因此,name是null。
在内存中,它就像下图所示:

3
因为您创建了一个名为“hello”的新Test0实例,但从未使用过它。
public Test() {

    new Test0("hello") // nothing is referencing this new object
}

你只是在另一个构造函数中创建了一个对象,但它对第一个构造函数调用创建的实例没有影响。


3

变量Name是实例变量。实例变量是对象特定的。

使用new Test0("Hello");创建Test0的一个新实例。

如果您想让t.getName()返回"Hello"[我的意思是独立于对象的字段值],请将name字段更改为静态:

static String name;

1
那是一个糟糕的建议 - 没有理由从构造函数中操作静态变量。(此外,这意味着所有实例共享相同的值。) - Paŭlo Ebermann
1
很抱歉,我不会提供任何建议。这是一个测试程序,旨在突出实例和静态差异化。 - Rajesh

3

你可以这样做,但是这种使用new的结果将在构造函数结束时消失。特别是,t.name将变为null

使用this("Hello")


0

您可以通过以下代码使用 new 关键字显示输出。由于您在此处使用了 public Test0(){new Test("Hello){};",因此 {} 大括号不重要。因此,当调用 test0() 构造函数时,在此构造函数内部将调用 test0(args);,但在第一个构造函数中,您没有显示输出。那么您的 "Hello" 将在哪里显示?只需进行编辑即可。

`

public test0(String str)
{
 this.name=str;
System.out.println(str);
}`

你将会得到你想要的输出结果。请看下面的代码:

class test01{
public test01(String str)
{System.out.println(str);
   }
public test01(){

    new test01("Print");
}
}public class Const {
public static void main(String args[])
{test01 t = new test01();

    //System.out.println(t.getName());
    }}

这段代码的输出将会给你所需的字符串。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接