这可能表明我对Java缺乏理解,但我想知道为什么在大多数MapReduce程序中,mapper和reducer类被声明为静态?
当将mapper和reducer类声明为另一个类的内部类时,它们必须声明为静态的,这样它们就不依赖于父类。
Hadoop使用反射为每个运行的map或reduce任务创建一个类实例。创建的新实例需要一个零参数构造函数(否则它怎么知道要传递什么)。
通过在不使用static关键字的情况下声明内部mapper或reduce类,java编译实际上创建了一个构造函数,该构造函数期望在构造时传入父类的实例。
您应该能够通过对生成的类文件运行javap命令来看到这一点
此外,static关键字在父类声明中使用时是无效的(这就是为什么您永远不会在顶级中看到它,而只在子类中看到它)
我能想到两个原因:
- 执行map reduce方法时,不需要状态,该状态必须保留在对象中。因此,所有必要的信息都被传递给该方法,而不需要在对象中存储额外的数据。如果对象的生命周期不会超过一个方法调用,那么您为什么要为实例化而挣扎呢
- 拥有一个以上的对象是没有意义的,这与实现Singleton模式的原因类似