创建在其外部类的构造函数中使用的类的实例

时间:2015-07-06 15:52:06

标签: java constructor inner-classes nested-class outer-classes

我正在尝试创建一个在其外部类的构造函数中使用的类的实例。参考下面的代码,我需要一个UserData对象,但我还需要一个TimeOnlineInfo对象来创建它,我没有看到获取TimeOnlineInfo对象的方法UserData的实例,因为TimeOnlineInfo不是静态的。我不能让它静态,因为它需要从它的外部类访问一个方法。无论如何,我可以让这个工作或获得最相似的效果?我确实意识到我可以让这些类保持静态而不是直接在addTime方法中保存数据但我已经在这个问题的中途了,我很想知道是否有办法这样做。

以下是我的代码的简化版本:

class UserData {
    TimeOnlineInfo timeOnline;

    public UserData(Object data1, Object data2, Object data3, Object data4, Object data5, TimeOnlineInfo timeOnlineInfo){
        this.timeOnlineInfo = timeOnlineInfo;
    }

    public class TimeOnlineInfo {
        private int time;

        public TimeOnlineInfo(int time){
           this.time = time;
        }

        public void addTime(int time){
            this.time += time;
            UserData.this.saveData();
        }
    }
}


UserData userData = new UserData(new UserData.TimeOnlineInfo());//Doesn't work because PlayInfo is not a static class
UserData userData = new UserData(userData.new TimeOnlineInfo());//This is just a stupid because i'm using the uncreated object in its own constructor

3 个答案:

答案 0 :(得分:2)

你对一些事情有一些普遍的困惑。让我们从头开始。

首先,这不是构造函数。

public void UserData(TimeOnlineInfo timeOnlineInfo){
    this.timeOnlineInfo = timeOnlineInfo;
}

您打算放弃void声明。

public UserData(TimeOnlineInfo timeOnlineInfo){
    this.timeOnlineInfo = timeOnlineInfo;
}

其次,使用内部类的实例来实例化外部类没有结构意义,因为获取 内部类的实例的唯一方法是使用外部类开头。

例如,您必须使用new UserData().new TimeOnlineInfo(int)作为TimeOnlineInfo的实例,但这只是:

  • 如果您选择为UserData
  • 创建无参数构造函数
  • 如果你真的不关心UserData你回来的实例

如果确实希望保留此设计,请考虑将int传入您的construtor,以便将其提供给TimeOnlineInfo的实例。

class UserData {
    TimeOnlineInfo timeOnlineInfo;

    public void saveData() {
        // stub
    }

    public UserData(int value) {
        this.timeOnlineInfo = new TimeOnlineInfo(value);
    }


    public class TimeOnlineInfo {
        private int time;

        public TimeOnlineInfo(int time){
            this.time = time;
        }

        public void addTime(int time){
            this.time += time;
            UserData.this.saveData();
        }
    }
}

答案 1 :(得分:1)

首先,您的UserData构造函数不是一个。

您已将其声明为void方法,因此不会编译UserData构造函数,使用TimeOnlineInfo实例进行参数化。

但这可能只是一个错字。

然后,如果你可以在现有的UserData之上实现UserData ud = new UserData(new UserData().new TimeOnlineInfo(42)); 的无参数构造函数,你可以使用以下习语:

UserData

然而,这似乎表明您的设计中存在更普遍的问题,因为您基本上必须初始化TimeOnlineInfo两次才能获得可用的实例。

这里的想法是,您要么在构造函数中注入TimeOnlineInfo,在这种情况下UserData可能会被更广泛的范围使用,而不仅仅是TimeOnlineInfo,或者您只使用{{}在UserData中的1}},在这种情况下,为UserData使用空构造函数并初始化其中的内部TimeOnlineInfo

答案 2 :(得分:0)

您可以将构造函数更改为:

public void UserData(int time){
    this.timeOnlineInfo = new TimeOnlineInfo(time);
}

您还可以将TimeOnlineInfo构造函数设为私有,以阻止其他人实例化恶意TimeOnlineInfo个实例。

但根据您发布的代码段,我可能完全摆脱TimeOnlineInfo

我已经被警告说,我认为构造函数不是一个。首先,永远不会创建与类同名的常规方法

其余的仍然存在,这种安排的问题是任何人都可以创建一个TimeOnlineInfo对象,即使{{1}未引用UserData.this.saveData()也会触发UserData它是用。创建的。

所以:

  1. 使TimeOnlineInfo实例化成为UserData的作业。
  2. 摆脱TimeOnlineInfo。 (如果你的班级已经很大,那就不可行了,但如果你的班级那么大,你可能还需要做其他事情。)
  3. 使您的内部类静态并明确管理连接:

    public void setTimeOnlineInfo(TimeOnlineInfo timeOnlineInfo){
    if (timeOnlineInfo.userData != null) {
        throw new IllegalArgumentException( "TOI already belongs to other UserData" );
    }
     if (this.timeOnlineInfo != null) {
         this.timeOnlineInfo.userData = null;
     }
     timeOnlineInfo.userData = this;
     this.timeOnlineInfo = timeOnlineInfo;
    

    }

    public static class TimeOnlineInfo {      私人时间;      private UserData userData;

     public TimeOnlineInfo(int time){
        this.time = time;
     }
    
     public void addTime(int time){
         this.time += time;
         userData.saveData();
     }
    

    }

  4. 远非理想,但它也会解决其他一些问题。