具有单例的侦听器的简单示例上的空指针异常



我这里有一个将单例与自定义侦听器一起使用的不同简单示例。 我在使用其他一些代码时遇到了类似的问题,并决定制作此示例。 它显示了与其他更复杂的代码相同的空指针问题。

空指针位于以下行:

  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 以外的其他名称。

最新更新