简体   繁体   English

创建对象后只能分配非空值的字段怎么办(Java)

[英]What to do with fields that can only be assigned non-null values after the object is created (Java)

Suppose I'm making a game: 假设我正在做一个游戏:

public class Game {

    Board board;
    public ArrayDeque<Player> players;

    //Players can have 'knights' and the one with the largest number
    //is referenced by the game.
    public Player playerWithLargestArmy;

    ...

}

At the beginning, when a game like this is initialised, no player can have the largest army (a player only has an 'army' once they have a certain number of knights). 在一开始,像这样的游戏初始化时,没有玩家可以拥有最大的军队(玩家只有一定数量的骑士后,才拥有“军队”)。 I want to assign the playerWithLargestArmy a value, but I'm not sure what. 我想为playerWithLargestArmy分配一个值,但是我不确定。 I also don't want to use null since I could just leave the implicit assignment to do that (and using null is bad practice anyway). 我也不想使用null因为我可以留下隐式赋值来做到这一点(而且无论如何,使用null都是不好的做法)。

I am looking for someone to explain to me how I can resolve this issue. 我正在寻找可以向我解释如何解决此问题的人。 I looked up factories and builders but I'm not sure they handle this kind of delayed assignment. 我查找了工厂和建筑商,但不确定他们是否会处理这种延迟的任务。 For context, each player has an int field specifying how many knights they have. 对于上下文,每个玩家都有一个int字段,用于指定他们拥有多少个骑士。

I could resolve this with a boolean for each player saying whether or not they have the largest army, but then you'd need to iterate through the players to find that player, which isn't ideal. 我可以用一个布尔值来解决这个问题,每个布尔值都说明他们是否拥有最大的军队,但随后您需要遍历这些球员以找到该球员,这并不理想。 Even if, in my case, that isn't a huge sacrifice, I'd still like to know for future reference. 就我而言,即使这不是一个巨大的牺牲,我仍然想知道以供将来参考。

There is java.util.Optional<T> class for such case. 对于这种情况,有java.util.Optional<T>类。

It have isPresent() and get() (and several other) methods which give you ability to check that object is present and get instance of underlying object. 它具有isPresent()get() (以及其他几种方法),使您能够检查对象是否存在并获取基础对象的实例。

Examples 例子

Declaration 宣言

 Optional<Player> playerWithLargestArmy = Optional.empty();

Assignment of value 价值分配

playerWithLargestArmy = Optional.of(newValue);

Usage of value 价值用途

if(playerWithLargestArmy.isPresent()) {
    Player p = playerWithLargestArmy.get();
}

or even better 甚至更好

playerWithLargestArmy.map(p -> doSomethingWithIt(p));

which will invoke doSomethingWithIt only if value is present. 仅在存在值的情况下才会调用doSomethingWithIt

Null Object Pattern https://en.wikipedia.org/wiki/Null_Object_pattern 空对象模式https://en.wikipedia.org/wiki/Null_Object_pattern

public class Army {
    public static final Army NullArmy = new Army(0);
    private int size;

    public Army(int size) {
        this.size = size;
    }
}

Now when you create a new Army, just set the initial value to Army.NullArmy. 现在,当您创建新的Army时,只需将初始值设置为Army.NullArmy。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM