我有一个代码片段,我在其中使用静态代码块来初始化变量。
public static class JoinMap extends
Mapper<IntWritable, MbrWritable, LongWritable, IntWritable> {
.......
public static RTree rt = null;
static {
String rtreeFileName = "R.rtree";
rt = new RTree(rtreeFileName);
}
public void map(IntWritable key, MbrWritable mbr,Context context)
throws IOException, InterruptedException {
.........
List elements = rt.overlaps(mbr.getRect());
.......
}
}
我的问题是上面代码片段中的变量 rt 没有初始化。任何人都可以提出修复或替代方法来初始化变量。我不想在我的map函数中初始化它,因为这会减慢整个过程。
答案 0 :(得分:2)
除非Java本身被破坏,否则这是不可能的。静态初始值设定项总是在类加载时触发。
也许您正在观察的任何内容都有其他解释,例如,某些内容正在将rt
设置回null
。或者,您是否正在观察上面其他静态初始化表达式中的rt
?在null
的初始化完成之前,它会看到rt
。
但是,尽管如此,我认为覆盖setup()
方法(旧API中的configure()
)并在那里进行初始化更为温和。它会发生一次。
答案 1 :(得分:1)
public static class JoinMap extends
Mapper<IntWritable, MbrWritable, LongWritable, IntWritable> {
.......
public RTree rt = null; //note that i removed static modifier
@Override
public void setup(Context context) throws IOException {
//this will be executed once on each mapper before first map(..) call
String rtreeFileName = "R.rtree";
rt = new RTree(rtreeFileName);
}
public void map(IntWritable key, MbrWritable mbr,Context context)
throws IOException, InterruptedException {
.........
}
}
答案 2 :(得分:0)
有什么理由你不想像这样初始化rt?:
public static RTree rt = new RTree("R.rtree");
答案 3 :(得分:0)
我不是Java专家,但看起来你对变量rt有两个“静态”赋值: 你有:
public static RTree rt = null ;
AND
rt = new RTree(rtreeFileName);
这些分配的顺序是什么?
尝试这一点,看看是否有帮助
public static final RTree rt = new RTree("R.rtree");
就我的Java知识而言,这确保您只能进行单一任务。
答案 4 :(得分:0)
如果我们不声明静态块并且只是写,那该怎么办。
public static RTree rt = new RTree(rtreeFileName);
因为变量是静态的,所以当类在内存中加载时它会被初始化一次吗?
答案 5 :(得分:0)
你可以覆盖mapper类的setup()方法来初始化与map函数有关的任何东西。这个setup()方法只在每个映射器的开头调用一次,因此,它不会减慢映射器进程的速度