Cannot make a static reference to the non-static field players - java

I'm making a program in java to register players and add them in an arraylist. My method for adding players is this:
void registerNewPlayer() {
System.out.print("Name?> ");
String name = input.nextLine();
System.out.print("Game?> ");
String game = input.nextLine();
System.out.print("Age?> ");
int age = input.nextInt();
Player player = new Player(name, game, age);
players.add(player);
}
my problem is that i don't know where to put
ArrayList<Player> players = new ArrayList<>();
if i have it in main, the method doesn't know what players is, but if i have it in the class i get a "Cannot make a static reference to the non-static field players" exception, when i try to print it from main. What's the best way of solving this.
Update: thanks for the help, i realized that since my command loop is already running on an instanced version of my class there is actually no problem, there was only a problem when i tried to test my method outside the instanced command loop.

If you'd like to have it at the class level, escape the static context.
public class YourClass {
ArrayList<Player> players = new ArrayList<>();
public static void main(String[] args) {
new YourClass(); // or YourClass yourClass = new YourClass();
}
// Create an instance of YourClass to leave the static context
public YourClass() {
registerNewPlayer();
}
public void registerNewPlayer() {
System.out.print("Name?> ");
String name = input.nextLine();
System.out.print("Game?> ");
String game = input.nextLine();
System.out.print("Age?> ");
int age = input.nextInt();
System.out.print("Weight?> ");
int weight = input.nextInt();
Player player = new Player(name, game, age, weight);
players.add(player);
}
}

I thinik this is the best solution for your problem. I hope it helps :)
Your Player class:
public class Player {
private static ArrayList<Player> _players = new ArrayList<Player>();
private String name;
private String game;
private int age;
private int weight;
public Player(String name, String game, int age, int weight){
this.name = name;
this.game = game;
this.age = age;
this.weight = weight;
}
public static void AddPlayer(Player player){
_players.add(player);
}
public static ArrayList<Player> getPlayers(){
return _players;
}
}
Now you can create some players and get them as follow:
... main ...
.
.
.
Player p1 = new Player("Name1", "Game1", 20, 70);
Player p2 = new Player("Name2", "Game2", 30, 80);
Player p3 = new Player("Name2", "Game3", 25, 73);
Player.AddPlayer(p1);
Player.AddPlayer(p2);
Player.AddPlayer(p3);
ArrayList<Player> allPlayers = Player.getPlayers();
.
.
.
Let me know if it is working for you !

The error you get is because you are trying to access a non-static variable (i.e. a value or object that exists only in instances of that class) from outside of such an instance. What you can do is to create an object of that class to be able to access the players through it:
public class Demo {
private List<Player> players = new ArrayList<>();
public static void main(String[] args) {
Demo demo = new Demo();
demo.registerNewPlayer();
System.out.println(demo.players);
}
private void registerNewPlayer() {
System.out.print("Name?> ");
String name = input.nextLine();
System.out.print("Game?> ");
String game = input.nextLine();
System.out.print("Age?> ");
int age = input.nextInt();
Player player = new Player(name, game, age);
players.add(player);
}
}
By creating an object of the class and executing the method as well as access the variable through it, allows you to do what you want (if I understood correctly that is).
Further reading material:
Java: when to use static methods
Type List vs type ArrayList in Java (you may have noticed that I changed the type of players to List<Player> from ArrayList<Player>)
What is the difference between public, protected, package-private and private in Java? (you may have noticed the private keyword on the list and the method)

Globally declare the list.
ArrayList<Player> players = new ArrayList<>();

Related

Illegal Self Reference in creation of class

I am pretty new to Java, my code is giving me the error "Illegal Self reference" in the lines below on Charmander/Squirtle/Bulbasaur.moveList
static Pokemon Charmander = new Pokemon("Fire", "Charmander", 25, Charmander.moveList);
static Pokemon Squirtle = new Pokemon("Water", "Squirtle", 25, Squirtle.moveList);
static Pokemon Bulbasaur = new Pokemon("Grass", "Bulbasaur ", 25, Bulbasaur.moveList);
Here is my code
public class Pokemon_Builder {
public static void main(String[] args) {
Move_Builder mb = new Move_Builder();
Charmander.moveList.add(mb.Ember);
Charmander.moveList.add(mb.Scratch);
Charmander.moveList.add(mb.Willowisp);
Charmander.moveList.add(mb.Recover);
Squirtle.moveList.add(mb.Bubble);
Squirtle.moveList.add(mb.Tackle);
Squirtle.moveList.add(mb.Powdersnow);
Squirtle.moveList.add(mb.Recover);
Bulbasaur.moveList.add(mb.Vinewhip);
Bulbasaur.moveList.add(mb.Poisonpowder);
Bulbasaur.moveList.add(mb.Tackle);
Bulbasaur.moveList.add(mb.Recover);
System.out.println(Charmander.moveList.size());
}
static Pokemon Charmander = new Pokemon("Fire", "Charmander", 25, Charmander.moveList);
static Pokemon Squirtle = new Pokemon("Water", "Squirtle", 25, Squirtle.moveList);
static Pokemon Bulbasaur = new Pokemon("Grass", "Bulbasaur ", 25, Bulbasaur.moveList);
}
And here is the code for the Pokemon Class:
import java.util.LinkedList;
import java.util.List;
public class Pokemon{
String type;
String name;
int health;
List<Move> moveList = new LinkedList<Move>();
public Pokemon(String type, String name, int health, LinkedList moveList) {
this.type = type;
this.name = name;
this.health = health;
this.moveList = moveList;
}
public void getInfo (){
System.out.println("Pokemon Name "+ this.name);
System.out.println("Your Pokemon's type "+ this.type);
System.out.println("Your Pokemon's health "+ this.health);
}
public void addMove(Move toAdd){
if (moveList.size() < 5){
moveList.add(toAdd);
}
else{System.out.println("Can't learn any more moves!");
}
}
}
Thanks in advance for the help
In your class Pokemon_builder you create 3 pokemon, while creating those pokemon you provide a moveList. Those movelists are created when the pokemon is created. Meaning what you now try to do is pass a field of a pokemon to the constructor for that pokemon.
As your Pokemon object is instantiating itself the the static member object creation runs before the constructors do. You are trying to create an object called Charmander and pass into Charmander's constructor a reference to a static "movelist" object within Charmander. You are doing this BEFORE Charmander has completed its object instantiation process. Thus you are trying to create an object that needs a reference within itself to "construct" itself.

Java: Array of Objects overwritten by last element [duplicate]

I have the following code:
public static void main(String[] args) {
Player players[] = new Player[2];
Scanner kb = new Scanner(System.in);
System.out.println("Enter Player 1's name");
players[0] = new Player(kb.nextLine());
System.out.println("Enter Player 2's name");
players[1] = new Player(kb.nextLine());
System.out.println("Welcome "+ players[0].getName() + " and " + players[1].getName());
}
It is meant to create a new player object and store the name of the player, while keeping all the objects in the array.
Here is the player class:
public class Player {
static String name;
public Player(String playerName) {
name = playerName;
}
public String getName(){
return name;
}
}
What actually happens is that it works when I just have 1 object, but when I have 2, each element in the array is the same as the second. When I have 3 objects in the array, each element is the same as the 3rd, etc.
I'm not sure why this is happening, or how to correct it, and it's been baffling me for hours :/
Its because of the static field. Statics are used across object instances. They are stored at class level.
Below code would work:
class Player
{
String name;
public Player(String playerName)
{
name = playerName;
}
public String getName()
{
return name;
}
}
Change static string name to private string name
Name field should not be static. Static means that the variable is actually global and shared across all class instances.
With the keyword static you have made name a class variable which is NOT an instance variable. A class variable is common to all the objects. Click for some more reading.

How to access object fields in a loop?

I can access the planetName, but not the Surfacematerial,Diameter etc because they are not in the array and in the object. How do I access the objects in a loop and their respective fields?
import java.util.Scanner;
public class Planet {
private String[] planetName;
private String SurfaceMaterial;
private double daysToOrbit;
private double diameter;
public Planet(){
planetName=new String[8];
SurfaceMaterial="";
daysToOrbit=0;
diameter=0;
}
public Planet(String[] planetName, String SurfaceMaterial,double daysToOrbit, double diameter){
this.planetName=planetName;
this.SurfaceMaterial=SurfaceMaterial;
this.daysToOrbit=daysToOrbit;
this.diameter=diameter;
}
public void setPlanetName(){
Scanner in=new Scanner(System.in);
Planet solar[]=new Planet[8];
for(int i=0;i<solar.length;i++){
solar[i]=new Planet(planetName,SurfaceMaterial,daysToOrbit,diameter);
System.out.println("Enter Planet Name::");
planetName[i]=in.next();
System.out.println("Enter Surface Material");
SurfaceMaterial=in.next();
System.out.println("Enter Days to Orbit");
daysToOrbit=in.nextDouble();
System.out.println("Enter Diameter");
diameter=in.nextDouble();
}
for(int i=0;i<solar.length;i++){
System.out.println(planetName[i]);
System.out.println(this.SurfaceMaterial); //This returns only one value that has been entered at the last
}
}
}
public static void main(String[] args) {
Planet planet=new Planet();
Scanner input=new Scanner(System.in);
planet.setPlanetName();
}
}
just access like following
object[index].member ... // or call getter setter
in your case say the first member name is name .. so call like
staff[0].name // this will return BOB
The staff array is declared as local in the Constructor: Or if it is declared in the class context, you are hiding it. So declare the staff array in the class context and then initialize in the constructor:
class Test
{
public Full_time [] Staff;
public Test()
{
Staff = new Full_time [4];
Staff [0] = new Full_time("BoB", 2000, 70000);
Staff [1] = new Full_time("Joe", 1345, 50000);
Staff [2] = new Full_time("Fan", 3000, 80000);
}
}
And then, in the main function:
public static void main(String[] args) {
Tester t = new Tester();
t.staff[i].name = "A Name";
}
However, instead of accessing member field directly it is suggested to use getter or setter function like: getStaff(i) and similar.

Adding new objects to an ArrayList in constructor

I am trying to add newly created objects to an ArrayList in the constructor of a class. The new objects are being created in another class in the main method.
Main method:
public static void main(String[] args) {
// TODO code application logic here
Player p1 = new Player("Peter");
}
My Player class:
public class Player {
protected static int age;
protected static String name;
protected static ArrayList players = new ArrayList();
Player(String aName) {
name = aName;
age = 15;
players.add(new Player()); // i know this doesn't work but trying along these lines
}
}
You have to edit the line
players.add(new Player());
to
players.add(this);
Also, there is no need to make the age and name static
I suggest you should have the following code instead
import java.util.ArrayList;
public class Player {
protected int age; //static is removed
protected String name; // static is removed
protected static ArrayList<Player> players = new ArrayList<Player>(); //this is not a best practice to have a list of player inside player.
Player(String aName) {
name = aName;
age = 15;
players.add(this); // i know this doesn't work but trying along these lines
}
public static void main(String[] args) {
// TODO code application logic here
Player p1 = new Player("Peter");
}
}
It sounds like you're actually asking how to refer to the instance you're constructing.
That's what the this keyword does.
This post is old, but for someone with similiar needs I suggest doing it like this:
Main class:
public static void main(String[] args) {
//TODO code application logic here
java.util.List<Player> players = new java.util.ArrayList<>(); //list to hold all players
Player p1 = new Player("Peter"); //test player
players.add(p1); //adding test player to the list
players.add(new Player("Peter")); //also possible in this case to add test player without creating variable for it.
}
Player class:
public class Player {
private final int age = 15; //if you always going to use 15 as a age like in your case it could be final. if not then pass it to constructor and initialize the same way as the name.
private String name;
Player(String name) { //variable name can be the same as one in class, just add this prefix to indicated you are talking about the one which is global class variable.
this.name = name;
}
}
Generally you should avoid using static keyword on variables which supposed to be different in each instance of that class. Avoid having object of itself inside.

How do you pass in an array from the main method to another method in java?

I have an array of Person in my main method, and I have to pass in that array to PlayGame() method in the class Game. How do you do that?
public class RollOff {
public static void main(String[] args) throws IOException{
int numPeople;
int a;
System.out.println("How many people will play the game?");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String s = br.readLine();
numPeople = Integer.parseInt(s);
if ((numPeople >= 2) && (numPeople <= 10)) {
Person[] p = new Person[numPeople];
for (a = 0; a < numPeople; a++) {
p[0] = new Person(a);
}
}
}
}
public class Game extends RollOff{
int numPeople;
int a;
void PlayGame() {
}
}
You need to use parameters to do that:
void playGame(Person[] p){
...
}
Now simply call
public static void main(String[] args){
...
game.playGame(p);
}
Because playGame is not a static method, you'll either need to make it static and call Game.playGame(p) or you'll need to create an instance of Game: Game game = new Game() followed by a call of game, as shown in the example above.
public void play(Person[] person) {
// code
}
// The call
play(person);
You can simply add a Person array parameter to the PlayGame
void playGame(Person[] personArray){//logic of the method}
Then all you have to do is call the playGame method from the main method by creating a new instance of the class Game
Game game = new Game();
game.PlayGame(p);
here "p" is your persons array.
The main class should create an instance of Game, and pass the array of players to the constructor:
Game game = new Game(p);
game.playGame();
The Game class should thus have the following field and constructor:
private Person[] players;
public Game(Person[] players) {
this.players = players;
}
Note that methods should start with a lower-case letter to follow Java naming conventions, and that your loop has a bug: it always sets the first element of the array instead of initializing every element.
Finally, give meaningful names to variables: players is much more readable than p.

Categories