java跟踪NullPointerException的最佳方法是什么?
我现在遇到了一些例外情况,我一直在努力解决它们,因此任何关于如何修复它们的指导或建议都将是非常好的,而不必依赖其他人的帮助。 目前,我有一个关于如何解决它的建议,我们将不胜感激,但从长远来看,关于如何追踪问题原因的一般建议会更好
class Egg extends Bee{
protected void anotherDay() {
eat();
if(age>=3)
{
HashMap<String, Hive> thisHive = Garden.GARDEN.getHiveMap();
Larvae larvae = new Larvae(this.health, this.age);
thisHive.get("a").bees.set(thisHive.get("a").beeIndex, larvae); //-------LINE 27
//thisHive.get("a").replaceBee(larvae) Line 27 was origionally this throwing the same exception
}
age++;
System.out.println("Egg" + " age " + this.age + " health " + this.health);
}
}
import java.util.ArrayList;
class Hive {
protected int honey;
protected int royalJelly;
protected int pollen;
public int beeIndex; // used to know what the index of bee you are in is
public boolean holdAdd;
ArrayList<Bee> bees = new ArrayList<Bee>();
protected Hive(int honeyStart, int royalJellyStart, int pollenStart)
{
bees = new ArrayList<Bee>();
this.setHoney(honeyStart);
this.setRoyalJelly(royalJellyStart);
this.setPollen(pollenStart);
System.out.println("hive made");
System.out.println(honey + " honey");
System.out.println(royalJelly + " royalJelly");
System.out.println(pollen + " pollen");
holdAdd = false;
}
//code removed ...
public void replaceBee(Bee addBee) {
bees.set(beeIndex, addBee);
}
// code removed
protected void anotherDay() {
int i = 0;
for(int k = 0; k < bees.size(); k++)
{
i++;
Bee bee = bees.get(k);
bee.anotherDay(); // ----------------LINE 144
beeIndex = i;
}
// code removed
}
}
public class Garden {
static HashMap<String, Hive> HiveMap = new HashMap<String, Hive>();
public static final Garden GARDEN = new Garden();
public static void main(String[] args) {
GARDEN.anotherDay(); //------------------LINE 21
}
}
//CODE REMOVED
public HashMap<String, Hive> getHiveMap()
{
return Garden.HiveMap;
}
// CODE REMOVED
protected void anotherDay() {
//CODE REMOVED
//should find all Hives and call anotherday() on them each
for(Hive currentHive : HiveMap.values()){
currentHive.anotherDay(); //------------LINE 56
}
}
//CODE REMOVED
}
# 1 楼答案
我的建议是保持线路短,不要打太多嵌套的内联电话。如果在下面这样的一行中出现错误,则很难找出哪个对象为空
# 2 楼答案
NullPointerException是代码中试图访问/修改尚未初始化的对象的情况
因此,理想情况下,您不应该修复NPE,而是需要确保您没有对空对象进行操作/调用
我们如何安全处理
1。更好的编码实践
例1:改进编码风格
eg2:不要将
Null
作为对象的返回类型返回,比如如果您想返回List,可以尝试Collections.emptyList()
而不是返回null2。提供足够的测试覆盖率
NPE是RunTimeException,您应该能够从测试类中捕获大部分RTE
3。不鼓励传递空参数
但是有些地方你必须支持NPE
# 3 楼答案
如果你有stacktrace,NullPointerException通常很容易通过一些实践发现:它来自于调用一个方法或引用一个空对象上的属性。因此,请查看报告的行,并查看引用了哪些对象。在你的例子中:
thisHive
可以为空吗?返回什么?它可以是空的吗?(可以,因为如果找不到键,映射将返回null)。bees
可以为空吗?等等。你通常只需看代码就可以发现它,但调试器使它变得更容易。在该行上设置一个断点,看看什么是空的。然后反向工作以理解它为什么为空需要注意的一件事是自动装箱:如果您将一个变量声明为包装类(
Long
、Integer
、Boolean
,等等),并将其作为原语引用,您将得到一个NPE:# 4 楼答案
您可以在调试器中为NPE设置一个断点,这样当它们显示堆栈帧内容(涉及的字段和对象)时,NPE将始终停止。以下是使用Idea的方法: