import java.util.ArrayList;
public class Team {
private String name;
private ArrayList<Player> team;
public Team(String name) {
this.name = name;
//how come i have to initialize it here in the constructor to see the full list?
this.team = new ArrayList<Player>();
}
public void addPlayer(Player player) {
//why can't i initialize it here in the method, this gives me a list of only recent add?
//this.team = new ArrayList<Player>();
this.team.add(player);
}
public void printPlayers() {
for(Player players : this.team) {
System.out.println(players);
}
}
public String getName() { return this.name; }
}
- I'm trying to figure out why
this.team = new ArrayList<Player>()
have to be in the constructor?
- Why can't I have
this.team = new ArrayList<Player>()
initialized in the method?
- I know that when I run it with the code in the constructor it works as intended (it gives me the full list when things are added)
- BUT when it's initialized in the method it only list the last given addition to the list. Is it wrong to have it initialized in the method?
- Also what's the difference of having it initialized as
private ArrayList<Player> team = new ArrayList<Player>();
before the constructor?
You're creating a new ArrayList each time and assigning it to
this.team
. So each time you calladdPlayer
, you're replacingthis.team
with a new empty ArrayList and then adding a player withthis.team.add(player)
, so only the last added player is in the ArrayList at all times.What you could do if you really don't want to create the ArrayList in the constructor is check if
this.team
is null every time you add a player and if the ArrayList is not created or empty, simply create one.If you're wondering whether the private keyword changes anything, you should read the Java docs on access modifiers: https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
Other than that, initializing before the constructor changes nothing in this case.
Because of the fact that each constructor invocation will result in a new distinct object the line
this.team = new ArrayList<Player>();
within the constructor will only be called once per instance so thus you'll only ever have oneArrayList
instance per object in this specific case.On the other hand, the
addPlayer
method can be called as many times as you want on a given object thusthis.team = new ArrayList<Player>();
within the addPlayer method will replace (overwrite) the previous list on each method call.You can do this in that way (to prevent recreation of ArrayList on every addPlayer method call):
but it will be VERY weird code... Better practice is to initialize 'team' list inside constructor or inline in field declaration. Both of them do the same thing. I prefer to initialize fields inside constructor, but this is only my habit. Other programmers may prefer inline version and this is nothing wrong/bad.
It doesn't, it has to be initialized before it is used. You can initialize it anywhere you want as long as you don't call printPlayer() or addPlayer() before.
You actually can. See this example:
No, it's not wrong. It's typically referred to as "lazy initialization" or "on demand" if you do it in the way of the example above.
Not much, the difference lies in when it is initialized.
Answering just the question:
Nothing, aside from the fact that
team
would be initialized beforename
.Field initializers are syntactic sugar for instance initializers. So this:
is identical to this:
and instance initializers are gathered together and inserted into every constructor which invokes (implicitly or explicily)
super
, in between the call tosuper
and the rest of the constructor body. So this:is identical to: