Java 此代码中是否存在任何额外的NullPointerException风险?
我有一个匿名类,创建时需要使用自引用。我的业务代码可以简化为以下代码,我知道此代码:Java 此代码中是否存在任何额外的NullPointerException风险?,java,inner-classes,Java,Inner Classes,我有一个匿名类,创建时需要使用自引用。我的业务代码可以简化为以下代码,我知道此代码: final Runnable runnable=new Runnable() { @Override public void run() { if(Math.random()>0.5){ runnable.run(); } } }; runnable.run(); 无法编译,因为在整个语句完成之前捕获了内部类中runnabl
final Runnable runnable=new Runnable() {
@Override
public void run() {
if(Math.random()>0.5){
runnable.run();
}
}
};
runnable.run();
无法编译,因为在整个语句完成之前捕获了内部类中runnable的值。我不想使用static或class属性来保持runnable,因为我不想忘记在删除这个部分时删除不必要的变量。所以我修改成这样:
final Runnable[] runnable={null};
runnable[0]=new Runnable() {
@Override
public void run() {
if(Math.random()>0.5){
runnable[0].run();
}
}
};
runnable[0].run();
与这样的正常对象创建相比,是否存在任何额外的NullPointerException风险:
Runnable runnable=new Runnable(){
@Override
public void run() {
}
};
runnable.run();
public class Main {
final static Runnable runnable = new Runnable() {
@Override
public void run() {
if(Math.random()>0.5){
runnable.run();
}
}
};
public static void main(String[] args) {
runnable.run();
}
}
?您试图捕获的行为几乎肯定应该使用while循环来完成。如果您想将其放在一个方法中,它不是有效的Java,因为您将在初始化它之前访问
runnable
。所以这不会编译:
public class Main {
public static void main(String[] args) {
final Runnable runnable = new Runnable() {
@Override
public void run() {
if(Math.random() > 0.5) {
runnable.run(); // <-- compilation error here
}
}
};
runnable.run();
}
}
然后它将编译,并且永远不会抛出NullPointerException
,因为捕获的不是引用的值,而是实际字段(字节码每次都将访问this.runnable.run()
)
尽管如此,正如其他人指出的,这可以通过
while
循环来完成。仅供参考,您还可以用Lambda表达式替换内部类
Runnable runnable = ()->{
if(Math.random()>.5) {
//TODO Code
}
};
你想完成什么?如果您只想从runnable()
上调用的实例内方法调用runnable.run()
,那么只需调用run()
。不过,这个代码很奇怪。每次调用基本上都有50/50的机会接近堆栈溢出,并且它不会完成任何其他事情。但是这种行为是确定性的,你可以试试看它是否有效。