我这里有一个将单例与自定义侦听器一起使用的不同简单示例。 我在使用其他一些代码时遇到了类似的问题,并决定制作此示例。 它显示了与其他更复杂的代码相同的空指针问题。
空指针位于以下行:
listener.onPass(sendString);
知道如何解决问题,以及为什么会发生这种情况?
这里显示的三个类,StartSelector.java用于启动另一个类,Singleton.java类有一个侦听器接口和一个Singleton,它向另一个类Singleton2.java发送一条短文本消息,这个其他类实现回调方法并接收文本消息String。
启动单例类
public class StartSelector {
public static void main(String args[]) {
Singleton.getInstance();
} // end main
}
使用自定义侦听器发送字符串消息
public class Singleton {
private OnPassStringListener listener;
private static Singleton instance;
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
}
}
return instance;
}
private Singleton(){
doIt();
}
private void doIt(){
transmitString("test string from singleton class");
}
public void transmitString(String sendString) {
listener.onPass(sendString); <-- NULL POINTER EXCEPTION HERE
}
public interface OnPassStringListener {
public void onPass(String stringSend);
}
} // end class Singleton
从其他类接收字符串消息并实现接口的回调方法
public class Singleton2 implements Singleton.OnPassStringListener {
public Singleton2() {
System.out.println("singleton2 class started");
}
@Override
public void onPass(String stringSend) {
System.out.println("message received: " + stringSend);
}
} // end class singleton2
您尚未在该代码中初始化侦听器。NullPointerException 仅表示您尝试使用的对象不指向有效对象。在定义值时初始化值,或者在类构造函数中初始化值。
private OnPassStringListener listener = new Singleton2();
或
private Singleton() {
listener = new Singleton2();
doIt();
}
public static Singleton getInstance(){
if(instance == null){
instance = new Singleton();
instance.setListener(new Singleton2());
}
}
return instance;
}
您的侦听器为空。更改此行
private OnPassStringListener listener;
自
private OnPassStringListener listener = new Singleton2();
两个选项。要么侦听器为 null,要么 NullPointerException 由某些代码 INSIDE onPass() 抛出。需要查看堆栈转储才能知道它是哪一个。(编辑。没关系,我错过了Singleton2的文本。所以是的,它绝对是前者。您在第一个单一实例上的listener
永远不会初始化。你想要初始化它,和/或检查空。
从技术上讲,将 Singleton 和 Singleton2 解耦可能是一种很好的编程风格。在观察者模式("侦听者"一词暗示)中,被监听者不知道它的听众(除了它知道它有一个侦听器的非常普遍的事实)。因此,如果您直接从 Singleton1 引用 Singleton2,则可以将其称为 Listener 以外的其他名称。