- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我有以下代码:
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class NullDereference {
private static final ConcurrentMap<Integer, Object> MAP = new ConcurrentHashMap<>();
public static void main(String[] args) {
Object object = getObject(1);
if (object == null) {
Lock lock = new ReentrantLock();
lock.lock();
try {
lock.newCondition().await(1, TimeUnit.SECONDS);
object = new Object();
object = addObject(object); // [3]
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
} finally { // [1]
lock.unlock(); // [1]
}
}
System.out.println("class: " + object.getClass()); // [2]
}
private static Object getObject(int hashCode) {
return MAP.get(hashCode);
}
private static Object addObject(Object newObject) {
Object oldObject = MAP.putIfAbsent(newObject.hashCode(), newObject);
if (oldObject != null) {
return oldObject;
}
return newObject;
}
}
NetBeans 在行 [2] 中显示关于“取消引用可能的空指针”的警告。我不确定为什么。我以为那是因为第 [3] 行,但是当我注释掉第 [3] 行时,警告仍然存在。当我在行 [2] 之前明确检查空值时,或者当我注释掉整个 finally
语句(由 [1] 注释的行)时,警告消失。
我分析了代码并认为这是误报。我说得对吗?
我不想对空指针做额外的检查。这段代码有什么问题?我可以更改某些内容以在没有警告的情况下获取代码吗?
最佳答案
我可以重现这个。简而言之:你是对的,它看起来像 NetBeans 错误。 Eclipse 和 IDEA 在这里没有显示警告。
Long:发出“可能的空取消引用”警告并不是非常简单的静态分析,因为它需要仔细遍历所有可能的控制流路径(我实际上正在编写类似的分析器,所以我知道这有多难)。有finally
使事情变得更加困难,因为在每个代码路径之后执行 finally 部分,然后将控件返回到原始代码。正确的控制流图必须复制多个 finally block ,添加多个传入和传出边是不够的。我可以推测 NetBeans 做错了这部分。
这是不正确的控制流图草图:
[ try { lock.newCondition().await(...) ...} ]
/ | \
/ | \
/ | \
Successful InterruptedException other exception
Execution | /
\ | /
\ | /
\ | /
[ finally { lock.unlock; } ]
/ | \
/ | \
/ | \
| | |
[System.out] [throw RuntimeEx] [throw the original exception]
看到沿着这个图的边缘你可以访问最终的 System.out
InterruptedException
之后的声明或其他一些异常(exception)。正确的图必须复制 finally block 的三个副本:
[ try { lock.newCondition().await(...) ...} ]
/ | \
/ | \
/ | \
Successful InterruptedException other exception
Execution | |
| | |
[finally_copy1] [finally_copy2] [finally_copy3]
| | |
| | |
[System.out] [throw RuntimeEx] [throw the original exception]
这样你可以到达System.out
成功后才声明try
object
时执行肯定是赋值的。
关于java - 为什么 NetBeans 在这里显示有关空指针取消引用的警告?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38764607/
我刚接触 C 语言几周,所以对它还很陌生。 我见过这样的事情 * (variable-name) = -* (variable-name) 在讲义中,但它到底会做什么?它会否定所指向的值吗? 最佳答案
我有一个指向内存地址的void 指针。然后,我做 int 指针 = void 指针 float 指针 = void 指针 然后,取消引用它们以获取值。 { int x = 25; vo
我正在与计算机控制的泵进行一些串行端口通信,我用来通信的 createfile 函数需要将 com 端口名称解析为 wchar_t 指针。 我也在使用 QT 创建一个表单并获取 com 端口名称作为
#include "stdio.h" #include "malloc.h" int main() { char*x=(char*)malloc(1024); *(x+2)=3; --
#include #include main() { int an_int; void *void_pointer = &an_int; double *double_ptr = void
对于每个时间步长,我都有一个二维矩阵 a[ix][iz],ix 从 0 到 nx-1 和 iz 从 0 到 nz-1。 为了组装所有时间步长的矩阵,我定义了一个长度为 nx*nz*nt 的 3D 指针
我有一个函数,它接受一个指向 char ** 的指针并用字符串填充它(我猜是一个字符串数组)。 *list_of_strings* 在函数内部分配内存。 char * *list_of_strings
我试图了解当涉及到字符和字符串时,内存分配是如何工作的。 我知道声明的数组的名称就像指向数组第一个元素的指针,但该数组将驻留在内存的堆栈中。 另一方面,当我们想要使用内存堆时,我们使用 malloc,
我有一个 C 语言的 .DLL 文件。该 DLL 中所有函数所需的主要结构具有以下形式。 typedef struct { char *snsAccessID; char *
我得到了以下数组: let arr = [ { children: [ { children: [], current: tru
#include int main(void) { int i; int *ptr = (int *) malloc(5 * sizeof(int)); for (i=0;
我正在编写一个程序,它接受一个三位数整数并将其分成两个整数。 224 将变为 220 和 4。 114 将变为 110 和 4。 基本上,您可以使用模数来完成。我写了我认为应该工作的东西,编译器一直说
好吧,我对 C++ 很陌生,我确定这个问题已经在某个地方得到了回答,而且也很简单,但我似乎找不到答案.... 我有一个自定义数组类,我将其用作练习来尝试了解其工作原理,其定义如下: 标题: class
1) this 指针与其他指针有何不同?据我了解,指针指向堆中的内存。如果有指向它们的指针,这是否意味着对象总是在堆中构造? 2)我们可以在 move 构造函数或 move 赋值中窃取this指针吗?
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: C : pointer to struct in the struct definition 在我的初学者类
我有两个指向指针的结构指针 typedef struct Square { ... ... }Square; Square **s1; //Representing 2D array of say,
变量在内存中是如何定位的?我有这个代码 int w=1; int x=1; int y=1; int z=1; int main(int argc, char** argv) { printf
#include #include main() { char *q[]={"black","white","red"}; printf("%s",*q+3); getch()
我在“C”类中有以下函数 class C { template void Func1(int x); template void Func2(int x); }; template void
我在64位linux下使用c++,编译器(g++)也是64位的。当我打印某个变量的地址时,例如一个整数,它应该打印一个 64 位整数,但实际上它打印了一个 48 位整数。 int i; cout <<
我是一名优秀的程序员,十分优秀!