Home > OS >  Can't access public Class's attributes after creating an instance of it in Main method
Can't access public Class's attributes after creating an instance of it in Main method

Time:03-28

I'm attempting to create a simple Dungeon Game to test my OOP skills, however, I ran into an issue where I can't display the Class's attributes. I'm mainly trying to give the user the option to see the "Hero's" stats so they can then pick whichever Hero they like best. After running my code and pressing 0 to try and get the Class Details, I get an "Exception in thread "main" java.lang.NullPointerException: Cannot invoke 'Warrior.getName()" because "warrior" is null at Main. main(Main.java:60)". I can't figure out what I need to do to fix this issue and if there is a better way to go about this please let me know. Thank you!

'''

import java.util.Scanner;
import java.util.Random;


public class Main 
{

    public static void main(String[] args) 
    {
        //Scanner for input, Random for random, Enemy initialized
        Scanner keyboard = new Scanner(System.in);
        Random rand = new Random();
        
        
        //Variables
        boolean running = true;
        int userChoice;
        
        
        
        
        while(running)  //while the game is running
        {
            Warrior warrior = null;         //Giving it a heads up that "Hey we will have a warrior. This also allows us to access it outside the scope.
            Mage mage = null;
            
            System.out.println("WELCOME TO MY DUNGEON GAME!\n"  
                    "SELECT YOUR CHARACTER: "   "\nSelect 1 for: Warrior \nSelect 2 for Mage: \nSelect 0 for Class Details: ");
            
            
            userChoice = keyboard.nextInt();
            
            while(userChoice < 0 || userChoice >=2)
            {

                System.out.println("Sorry enter either 1");
                userChoice = keyboard.nextInt();
            }
            
            if(userChoice == 1)
            {
                System.out.println("You selected 1, Warrior Created: Here are the Class details:\n");
                warrior = new Warrior("Warrior", 100, 10, "Sword");
                System.out.println("Class: "   warrior.getName());
                System.out.println("Health: "   warrior.getHealth());
                System.out.println("Damage: "  warrior.getDamage());
                System.out.println("Weapon: "  warrior.getDamage());
                
            }
            else if(userChoice ==2)
            {
                System.out.println("You selected 2, Mage Created: ");
                mage = new Mage("Mage", 100, 20, "Wand");
                
            }
            else if(userChoice == 0)
            {
                System.out.println("-----------------------------------");
                System.out.println("Warrior Class Details: \n");
                System.out.println("Class: "   warrior.getName());
                System.out.println("Health: "   warrior.getHealth());
                System.out.println("Damage: "  warrior.getDamage());
                System.out.println("Weapon: "  warrior.getDamage());
                
            }
            running = false;
            
            
        }
    }
}

public class Warrior extends Hero 
{
    
    
    //Attributes
    private String weapon;
    
    //We use super so we can set the super class's attributes instead of doing one by one
    //if we have any specific attributes we can then do so afterwards
    
    //Constructor
    public Warrior(String name, int health, int damage, String weapon) 
    {
        super(name, health, damage);
        this.weapon = weapon;
    }

    //Getters and Setters
    public String getWeapon() 
    {
        return weapon;
    }

    public void setWeapon(String weapon)
    {
        this.weapon = weapon;
    }
}


public class Hero 
{
    //Attributes
    
        private String name;
        private int health;
        private int damage;
        
        //Constructor
        
        public Hero(String name, int health, int damage)
        {
            this.name = name;
            this.health = health;
            this.damage = damage;
        }

        //Getters and Setters
        public String getName() 
        {
            return name;
        }
        public void setName(String name) 
        {
            this.name = name;
        }
        public int getHealth() 
        {
            return health;
        }
        public void setHealth(int health) 
        {
            this.health = health;
        }
        public int getDamage() 
        {
            return damage;
        }
        public void setDamage(int damage) 
        {
            this.damage = damage;
        }
}

'''

CodePudding user response:

in this below block of code you will always get java.lang.NullpointerException because warrior is always null you need to assign a value like you are ssigning above.

else if(userChoice == 0)
            {
                System.out.println("-----------------------------------");
                System.out.println("Warrior Class Details: \n");
                System.out.println("Class: "   warrior.getName());
                System.out.println("Health: "   warrior.getHealth());
                System.out.println("Damage: "  warrior.getDamage());
                System.out.println("Weapon: "  warrior.getDamage());
                
            }

CodePudding user response:

Hi and welcome to Stack Overflow. The problem is that you never initialized the Warrior variable in this case. You declare that you have a variable of type Warrior, and if the user presses 1 you actually initialize it with an instance of the class (new Warrior(...)). If, however, the user presses 0as their first choise, your variable will still point to null, hence the NullPointerException.

CodePudding user response:

If you want to call the attributes of your warrior before creating an instance of it, there are two possibilities:

  1. You create another static class of the mage and warrior attributes, which acts as template for your actual classes, that you instantiate when choosing one of the 2 classes. with this keyword set, the class must not be instantiated, but is available immediately for inspection.
public class HeroDefaults {

    public static String WarriorName = "Warrior";
    public static int WarriorHealth = 100;
    public static int WarriorDamage = 10;

    public static String MageName = "Warrior";
    public static int MageHealth = 100;
    public static int MageDamage = 10;
}

then you may use it like this:

while(running)  //while the game is running
{
    // your other code
    
    if(userChoice == 1)
    {
        System.out.println("You selected 1, Warrior Created: Here are the Class details:\n");
        warrior = new Warrior(
            HeroDefaults.WarriorName,
            HeroDefaults.WarriorHealth,
            HeroDefaults.WarriorDamage,
            HeroDefaults.WarriorWeapon);
        System.out.println("Class: "   warrior.getName());
        System.out.println("Health: "   warrior.getHealth());
        System.out.println("Damage: "  warrior.getDamage());
        System.out.println("Weapon: "  warrior.getDamage());
        
    }
    else if(userChoice == 0)
    {
        System.out.println("-----------------------------------");
        System.out.println("Warrior Class Details: \n");
        System.out.println("Class: "   HeroDefaults.WarriorName);
        System.out.println("Health: "   HeroDefaults.WarriorHealth);
        System.out.println("Damage: "   HeroDefaults.WarriorDamage);
        System.out.println("Weapon: "   HeroDefaults.WarriorWeapon);
        
    }
    running = false;
}
  1. You instantiate one of each hero type at the beginning of your program and after choosing one, you throw away the other unused ones.
while(running)  //while the game is running
{
    Warrior warrior = new Warrior("Warrior", 100, 10, "Sword");
    Mage mage = new Mage("Mage", 100, 20, "Wand");
    Hero myHero = null;
    
    // other code
    if(userChoice == 1)
    {
        System.out.println("You selected 1, Warrior Created: Here are the Class details:\n");
        myHero = warrior;
        System.out.println("Class: "   warrior.getName());
        System.out.println("Health: "   warrior.getHealth());
        System.out.println("Damage: "  warrior.getDamage());
        System.out.println("Weapon: "  warrior.getDamage());
        
    }
    else if(userChoice ==2)
    {
        System.out.println("You selected 2, Mage Created: ");
        myHero = mage;
        
    }
}
  • Related