猿问

使用父对象创建子对象的字段实例

我有一个User(父母)和一个Task(孩子)。我需要每个任务中都有一个用户实例,并且希望该任务在用户中可用。


版本1和版本2有什么区别吗?


我应该更喜欢哪个版本?


版本1:


public class User {


// does this creates a new Task on each field access?

private Task task = new Task(this);


public void runTask() {

   task.run();

}


}

版本2:


public class User {


private Task task;


public getTask() {

   if(task == null) {

    task = new Task(this);

   }

   return task;

}


public void runTask() {

   task.run();

}

}

我想,第一个版本会进行急切的初始化,并且与执行此操作相同:


版本3


public class User {

    public User(){

       // I need the user instance to put into the task, but this is null here..

       this.task = new Task(this);

    } 

    private Task task;


}

我想要实现的是:


我有很多方法,User.java并且想将这些方法外包给一个新类Task.java(与其用户相关)。


慕少森
浏览 117回答 3
3回答

暮色呼如

 public class User {// does this creates a new Task on each field access?private Task task = new Task(this);回答其中的问题:每次创建新的用户对象时,该新用户的任务字段都会被初始化。只有那时。一次。如果您想确保它不会被重新分配,那么执行以下操作可能会有所帮助:private final Task task = new Task(this);但这里真正的问题是不同的:你在这里创建了一个非常奇怪的依赖关系。您已经说过您的 User 类有太多字段,现在您为其添加了另一个职责,即运行“任务”。因此,真正的答案是:退后一步。找一些更有经验的人来和你坐在一起。向他们解释您的需求,并让他们审查您的设计和代码库。这里没有单一的“做这个,而不是那个”答案。

达令说

版本 2 可能会导致NullPointerException,因为您始终必须getTask()先调用runTask(),否则NullPointerException会抛出异常。Task您可以在运行实例之前创建实例public class User {    private Task task;    public void runTask() {        if (task == null) {            task = new Task(this);        }        task.run();    }}

翻过高山走不出你

由于您的评论澄清了一些事情,因此您可能应该采取以下方法:public class User {    private Task task;    public User()    {    }    public void runTask()     {        if(task == null)         {            task = new Task();        }        task.run();    }}public class Task extends User {     public Task()     {    }    }这样,Task就会继承User的所有方法和属性。我不完全确定这会如何影响 User 的构造函数,这取决于类的其余部分到底是什么样子。现在,您可以使用与 User 相同的构造函数来调用 Task,也可以使用 User 构造函数的参数和其他参数(如果需要)在 Task 中定义自己的构造函数。
随时随地看视频慕课网APP

相关分类

Java
我要回答