我是从其他语言转向 Java 的,所以如果这是显而易见的,请原谅我,但我遇到了一个非常奇怪的行为。
我正在编写一个简单的 Pig UDF。我返回一个 Tuple 对象,它是使用 TupleFactory 单例创建的。在以下两个代码示例中,第一个示例有效,而第二个示例在创建 newTuple 时抛出 NullPointerException;
public class MyUDF {
public Tuple func(Tuple input) {
return TupleFactory.getInstance().newTuple(Arrays.asList(o1, o2, o3));
}
}
public class MyUDF {
...
TupleFactory _factory;
public Tuple func(Tuple input) {
_factory.getInstance();
return _factory.newTuple(Arrays.asList(o1, o2, o3));
}
}
最佳答案
您的第一个代码 TupleFactory.getInstance()
正在调用类本身的静态类方法,正如单例模式实现所期望的那样。
在没有实例的情况下调用实例方法
你的第二个代码_factory.getInstance()
正在调用一个实例变量,一个已定义但尚未实例化的类成员。您不能对不存在的对象调用对象方法。
Enum
作为单例
最后,在 Java 中实现单例模式的最安全、最简单的方法是通过枚举。搜索 Stack Overflow 和/或搜索引擎,查找诸如以下单词的搜索引擎:Java singleton enum Joshua Bloch“Effective Java”。
public enum TupleFactory {
INSTANCE;
// Add private constructor if needed.
public Tuple makeTuple( … ) {
…
return tuple ;
}
}
使用起来很简单。
Tuple t = TupleFactory.INSTANCE.makeTuple( … ) ;
谨防滥用 Singleton
最后,我将添加一个强制性警告,单例通常是一种“代码味道”,这是由于缺乏对面向对象编程的理解而导致的糟糕设计的症状。
关于Java Singleton 有时会抛出 NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40354813/