Java NullPointerException

Java NullPointerException,java,arraylist,nullpointerexception,Java,Arraylist,Nullpointerexception,我尝试了printStackTrace,我已经将所有内容都转换为静态(我想)。。。但是,第17行和第38行是问题所在。。。由于此错误: You picked up: Pickaxe java.lang.NullPointerException at item.addInv(item.java:38) at item.main(item.java:17) Description: Can be used to mine with. Press any key to

我尝试了printStackTrace,我已经将所有内容都转换为静态(我想)。。。但是,第17行和第38行是问题所在。。。由于此错误:

You picked up: Pickaxe
java.lang.NullPointerException
        at item.addInv(item.java:38)
        at item.main(item.java:17)
Description: Can be used to mine with.
Press any key to continue . . .
第17行:
anItem.addInv(1)

第38行:
arr.add(“Dan”)

这是我的代码:

import java.io.*;
import java.util.*;
import javax.swing.*;

public class item
{
    public static int attack, defense;
    public static ArrayList<String> arr;
    public static String name, desc, typeOf, attackAdd, defenseAdd, canSell, canEat,earnedCoins,canEquip;

    String stats[];

    public static void main(String args[])
    {
        item anItem = new item();
        ArrayList<String> arr = new ArrayList<String>();
        anItem.addInv(1);
    }

    public static void addInv(int e) {
        String iname = getItem(1)[0];
        String idesc = getItem(1)[1];
        int itypeOf = Integer.parseInt(getItem(1)[2]);
        int iattackAdd = Integer.parseInt(getItem(1)[3]);
        int idefenseAdd = Integer.parseInt(getItem(1)[4]);
        boolean icanSell = Boolean.parseBoolean(getItem(1)[5]);
        boolean icanEat = Boolean.parseBoolean(getItem(1)[6]);
        int iearnedCoins = Integer.parseInt(getItem(1)[7]);

        attack = attack + iattackAdd;
        defense = defense + idefenseAdd;
        System.out.println("You picked up: " + iname);
        try {
            arr.add("Dan");
        } catch(NullPointerException ex) {
            ex.printStackTrace();
        }

        System.out.println("Description: " + idesc);
    }

    public static String[] getItem(int e) {

        String[] stats = new String[7];

        String name = "Null";
        String desc = "None";
        String typeOf = "0";
        String attackAdd = "0";
        String defenseAdd = "0";
        String canSell = "true";
        String canEat = "false";
        String earnedCoins = "0";

        if (e == 1) {
            name = "Pickaxe";
            desc = "Can be used to mine with.";
            typeOf = "2";
            attackAdd = "2";
            earnedCoins = "5";
        }

        return new String[] { name, desc, typeOf, attackAdd, defenseAdd, canSell, canEat, earnedCoins};
    }
}
import java.io.*;
导入java.util.*;
导入javax.swing.*;
公共类项目
{
公共静态int攻击、防御;
公共静态数组列表arr;
公共静态字符串名称,desc,typeOf,attackAdd,defenseAdd,canSell,canEat,earnedCoins,canEquip;
字符串统计[];
公共静态void main(字符串参数[])
{
item anItem=新项();
ArrayList arr=新的ArrayList();
补充条款(1);
}
公共静态无效添加(int e){
字符串iname=getItem(1)[0];
字符串idesc=getItem(1)[1];
int-itypeOf=Integer.parseInt(getItem(1)[2]);
int-iattackAdd=Integer.parseInt(getItem(1)[3]);
int-idefenseAdd=Integer.parseInt(getItem(1)[4]);
boolean=boolean.parseBoolean(getItem(1)[5]);
boolean icanat=boolean.parseBoolean(getItem(1)[6]);
int iArnedCoins=Integer.parseInt(getItem(1)[7]);
攻击=攻击+添加;
防御=防御+idefenseAdd;
System.out.println(“您拾取:+iname”);
试一试{
协议添加(“Dan”);
}捕获(NullPointerException ex){
例如printStackTrace();
}
System.out.println(“说明:“+idesc”);
}
公共静态字符串[]getItem(int e){
String[]stats=新字符串[7];
String name=“Null”;
字符串desc=“无”;
字符串typeOf=“0”;
字符串attackAdd=“0”;
字符串add=“0”;
字符串canSell=“true”;
字符串canEat=“false”;
字符串挣得的硬币=“0”;
如果(e==1){
name=“鹤嘴锄”;
desc=“可用于采矿。”;
typeOf=“2”;
attackAdd=“2”;
挣硬币=“5”;
}
返回新字符串[]{name,desc,typeOf,attackAdd,defenseAdd,canSell,canEat,earnedCoins};
}
}
正如你所看到的,是那些台词,我不知道该怎么办…:\

字符串canEat=“false”为什么要在字符串之间转换

你似乎把
物品
分类成了
库存
分类

也许Enum会更好:

public enum InventoryItem
{
    PICKAXE("Pickaxe", "Can be used to mine with", ItemType.Tool,
            5, 2, 0)

    EPIC_PICKAXE("Super mega awesome Pickaxe", "Can be used to mine with, but epically", ItemType.Tool,
            1000000, 100, 0)


    public static enum ItemType {
        TOOL,
        WEAPON
    }

    public final String name, description;
    public final ItemType type;
    public final boolean canSell, canEat, canEquip;
    public final int earnedCoins, attackAdd, defenseAdd;

    private InventoryItem(String name, String description, ItemType type
                          int earnedCoins, int attackAdd, int defenseAdd,
                          boolean canSell, boolean canEat, boolean canEquip)
    {
        this.name        = name;
        this.description = description;
        this.type        = type
        this.canSell     = canSell;
        this.canEat      = canEat;
        this.canEquip    = canEquip;
        this.earnedCoins = earnedCoins;
    }

    private InventoryItem(String name, String description, ItemType type
                          int earnedCoins, int attackAdd, int defenseAdd)
    {
        this(name, description, type,
             earnedCoins, attackAdd, defenseAdd,
             true, false, true);
    }
}
然后,您可以在播放器的类中设置
List inventory=new ArrayList()
,并直接与之交互。

String canEat=“false”为什么要在字符串之间转换

你似乎把
物品
分类成了
库存
分类

也许Enum会更好:

public enum InventoryItem
{
    PICKAXE("Pickaxe", "Can be used to mine with", ItemType.Tool,
            5, 2, 0)

    EPIC_PICKAXE("Super mega awesome Pickaxe", "Can be used to mine with, but epically", ItemType.Tool,
            1000000, 100, 0)


    public static enum ItemType {
        TOOL,
        WEAPON
    }

    public final String name, description;
    public final ItemType type;
    public final boolean canSell, canEat, canEquip;
    public final int earnedCoins, attackAdd, defenseAdd;

    private InventoryItem(String name, String description, ItemType type
                          int earnedCoins, int attackAdd, int defenseAdd,
                          boolean canSell, boolean canEat, boolean canEquip)
    {
        this.name        = name;
        this.description = description;
        this.type        = type
        this.canSell     = canSell;
        this.canEat      = canEat;
        this.canEquip    = canEquip;
        this.earnedCoins = earnedCoins;
    }

    private InventoryItem(String name, String description, ItemType type
                          int earnedCoins, int attackAdd, int defenseAdd)
    {
        this(name, description, type,
             earnedCoins, attackAdd, defenseAdd,
             true, false, true);
    }
}

然后您可以在播放器的类中设置
List inventory=new ArrayList()
,并直接与之交互。

变量arr未初始化

main()中的变量arr与函数addInv()中的变量arr不同


只需在addInv中对其进行初始化即可修复。

变量arr未初始化

main()中的变量arr与函数addInv()中的变量arr不同

只需在addInv中初始化它就可以修复它。

在arr上调用add()方法时,它还没有初始化,因此出现了NullPointerException

因为您可能也会在其他方法中使用ArrayList,所以应该在构造函数中初始化它;即:

public item() {
   arr = new ArrayList<String>();
}
公共项目(){
arr=新的ArrayList();
}
在arr上调用add()方法时,该方法尚未初始化,因此出现NullPointerException

因为您可能也会在其他方法中使用ArrayList,所以应该在构造函数中初始化它;即:

public item() {
   arr = new ArrayList<String>();
}
公共项目(){
arr=新的ArrayList();
}
一些技巧(可以直接解决问题的技巧):

1) 尽可能将变量声明为私有的,或者最多声明为受保护的。我个人从不使用“默认值”,即包级访问(同一个包中的任何东西都可以看到它)

2) 仅对不可变值使用public。不可变的值是不能更改的(所有成员都是final是确保在构造对象且变量都是私有的之后,没有方法修改任何值的最佳方法)

3) 只要可能,始终将变量声明为最终变量(类变量、实例变量、参数、局部变量)

这里有一个直接帮助你的技巧是#3。因为您从未为“arr”赋值,所以它是空的。如果您将其声明为final,编译器将强制您实际为其赋值,否则代码将无法编译

当你开始编程时,做这件小事可以节省你几个小时的时间。在我的例子中,我做了一些类似的事情,但并不完全相同(实际上,我在某种程度上违反了#2),这花费了我大约一周的时间。我已经用Java编程超过15年了。。。如果我可以因为这样的事情浪费一周的时间,想想你可以浪费多少时间:-)

一些技巧(可以直接解决问题的技巧):

1) 尽可能将变量声明为私有的,或者最多声明为受保护的。我个人从不使用“默认值”,即包级访问(同一个包中的任何东西都可以看到它)

2) 仅对不可变值使用public。不可变的值是不能更改的(所有成员都是final是确保在构造对象且变量都是私有的之后,没有方法修改任何值的最佳方法)

3) 只要可能,始终将变量声明为最终变量(类变量、实例变量、参数、局部变量)

这里有一个直接帮助你的技巧是#3。因为您从未为“arr”赋值,所以它是空的。如果您将其声明为final,编译器将强制您实际为其赋值,如果