0

我正在尝试创建一个在其外部类的构造函数中使用的类的实例。参考下面的代码,我需要一个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
4

3 回答 3

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 传递给您的构造函数,以便将其提供给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();
        }
    }
}
于 2015-07-06T16:03:04.470 回答
1

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

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

但这可能只是一个错字。

UserData然后,如果您可以在现有构造函数之上实现无参数构造函数,则可以使用以下成语:

UserData ud = new UserData(new UserData().new TimeOnlineInfo(42));

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

这里的想法是,你要么注入TimeOnlineInfo一个构造函数,在这种情况下TimeOnlineInfo,可能会被更广泛的范围使用,而不是 just UserData,或者你只使用TimeOnlineInfowithin UserData,在这种情况下,使用一个空的构造函数UserData并在其中初始化你的 internal TimeOnlineInfo

于 2015-07-06T15:59:58.917 回答
0

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

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

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

但是根据您发布的片段,我可能会TimeOnlineInfo完全摆脱。


我被警告过,我认为的构造函数不是构造函数。所以首先,永远不要创建与 class 同名的常规方法

其余的仍然存在,这种安排的问题是任何人都可以创建一个对象,即使它没有被创建它的对象引用TimeOnlineInfo,它也会触发。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;
    

    }

    公共静态类 TimeOnlineInfo { 私有 int 时间;私人用户数据用户数据;

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

    }

远非理想,但它也可以解决其他几个问题。

于 2015-07-06T15:58:05.487 回答