Java hoe en waar de variabele te initialiseren met NullPointerException

Ik ondervind een probleem waarbij ik deze foutmelding krijg:

Uitzondering in thread "main" java.lang.NullPointerException

     
    

op com.noxia.Main.startCombat (Main.java:101)

         

bij com.noxia.Area1.createArea1Enemy (Area1.java:43)

         

op com.noxia.Main.main (Main.java:30)

  

Ik weet dat ik de variabelen moet initialiseren omdat ze nul zijn, maar ik kan er niet achter komen wat ik moet zetten. Ik heb de code geminimaliseerd om alleen de relevante delen te laten zien, omdat er veel andere variabelen en methoden zijn weggelaten, maar dit lijkt op het probleem betrekking te hebben. Alle hulp wordt enorm op prijs gesteld =)

public class Main {
    Player p;
    Enemy e;
    Area1 a1;        

    public static void main(String[] args) {
        Main main = new Main();
        main.a1 = new Area1();            
        main.p = new Player(100);
        //the line directly below this is line 30 where the error occurs
        main.a1.createArea1Enemy(10);
    }

    public void startCombat()
    {
        //the line directly below this is line 101 where the error occurs       
        while (p.getCurrentLife() > 0 & a1.e.getLife() > 0)
        {
            p.playerAttack();
            if (p.getCurrentLife() > 0 & a1.e.getLife() > 0)
            {
                e.enemyAttack();
            }
        }   
    }


public class Player extends Main {
    private int currentLife;

    public int getCurrentLife()
    {
        return currentLife;
    }
    public void setCurrentLife(int cl)
    {
        currentLife = cl;
    }

    public Player(int cl)
    {
        currentLife = cl;
    }


public class Enemy extends Main {
    private int life;

    public int getLife()
    {
        return life;
    }
    public void setLife(int lf)
    {
        life = lf;
    }

    public Enemy (inf lf)
    {
        life = lf;
    }


public class Area1 extends Main {

    public void createArea1Enemy(int enemyCounter)
    {
        while (enemyCounter > 0)
        {
            String[] enemyList = {"Enemy1", "Enemy2"} //code for Enemy2 left out below
            int enemyListLength = enemyList.length; 
            int randomEnemy = (int) (Math.random() * enemyListLength);

            if (enemyList[randomEnemy].equals("Enemy1"))
            {
                Enemy enemy1 = new Enemy("Enemy1", 100);
                //the line directly below this is line 43 where the error occurs
                startCombat();
            }
        enemyCounter--;
        }
    }
}
0
Dit is waar het leren van een stap debugger in een IDE te gebruiken van onschatbare waarde is.
toegevoegd de auteur feeling unwelcome, de bron
Dit is een verschrikkelijk ontwerp dat elke klasse erven van Main het maakt het bijna onmogelijk om erachter te komen wat het beoogde gedrag is.
toegevoegd de auteur feeling unwelcome, de bron
Het lijkt erop dat als u vijand vijand1 = vervangt door e = , u geen NPE zou zien. Het is echter moeilijk om te zeggen wat er gaande is.
toegevoegd de auteur dasblinkenlight, de bron

3 antwoord

Het simpele antwoord is dat je e op een vijand moet instellen voordat je startCombat aanroept.

Maar een betere manier om dit te doen zou zijn om e te verwijderen, en het vijandelijke object door te geven aan startCombat met behulp van een methodeparameter. Het veld e is conceptueel verkeerd. Om het verkeerde te begrijpen, probeert u een samenhangende verklaring te vinden van wat het betekent in termen van de status van een Hoofd -object.


Dit is duidelijk een beginnerscode ... en er zijn een aantal slechte dingen over wat je hebt geschreven:

  • De velden van een klasse moeten voor de objectstatus zijn en niet voor het doorgeven van parameterwaarden aan methoden.
  • Vermijd het schrijven van code die toegang geeft tot de binnenkant van een klasse ... zoals uw hoofdmethode.
  • De beste methode is om velden privé en gedefinieerde methoden voor getter en/of setter (zoals vereist) te maken voor externe klassen om deze te openen/wijzigen.
  • U moet leren constructors te schrijven met parameters.
  • U moet uw code correct ontwerpen. Alles wat zich uitstrekt Hoofd betekent dat er geen rationeel model zal zijn van wat de objecten "betekenen". En het probleem is dat elke instantie van Enemy en Area1 hun eigen kopieën van de p , e heeft, en a1 velden, en een hele reeks ongepaste methoden.
3
toegevoegd

Het grootste probleem is dat je nooit Enemy e; initialiseert. U maakt een vijand maar wijst deze nooit toe aan this.e .

Verander deze regel:

Enemy enemy1 = new Enemy("Enemy1", 100);

Hiernaar:

this.e = new Enemy("Enemy1", 100);

Er zijn ook veel andere problemen met uw code.

2
toegevoegd

Leer hoe je een constructor op de juiste manier schrijft. Deze code is verkeerd .

Ik zie geen enkele reden waarom een ​​ Play , Area1 en Enemy Main zou moeten uitbreiden.

1
toegevoegd