来自C和C++背景,我一直认为Java中的解除引用是通过其引用访问对象的过程.
例如,"ref"是一个引用,当用于访问它引用的Integer对象时,它将被解引用:
Integer ref = new Integer(7);
// Dereference "ref" to access the object it refers to.
System.out.println(ref.toString());
Run Code Online (Sandbox Code Playgroud)
当解除引用过程失败时,会发生NullPointerExceptions:
Integer ref = null;
// Dereferencing "ref" causes an exception.
System.out.println(ref.toString());
Run Code Online (Sandbox Code Playgroud)
但是,我的解释与Oracle新的Java SE 8 Programmer I考试(测试版)上测试的主题之一相冲突:
解释对象的生命周期(创建," 通过重新分配取消引用 "和垃圾收集)
因此,根据创建Java 8考试的人,在Java中取消引用是重新分配引用的行为,而不是评估引用的行为:
例如:
// Create an Integer object, and a reference to it.
Integer ref = new Integer(7);
ref = null;
// Now (according to Oracle?):
// - The reassignment means ref has been "dereferenced".
// - The dereferenced object is now eligible for Garbage Collection.
Run Code Online (Sandbox Code Playgroud)
用谷歌搜索这个问题表明甲骨文的定义被更广泛地使用,但这并不意味着它是正确的,并且谷歌对于"重新分配取消引用"的唯一打击就是针对新的Java 8考试!无论如何,JLS并没有真正解决问题.
关于解除引用在Java中的真正含义,是否有任何正式或权威的定义(而不是个人意见)?(即它与评估或重新分配有关吗?)
两个完全不同的定义设法共存似乎很奇怪.
小智 6
Java 变量在Oracle 的术语中要么是“原始类型”,要么是“引用类型” (当然,除了特殊类型 null 之外)。我从 C++ 背景来到 Java,总是发现最容易想到像指针这样的引用类型,因为这使得最容易理解它们是如何工作的(尽管存在重要的差异),但是因为所有非原始变量都是这样的,所以没有求值的概念(不等同于 C++ 的指针取消引用)。
所以,在你的例子中:
Run Code Online (Sandbox Code Playgroud)Integer ref = new Integer(7); ref = null;
第一行在堆上创建一个对象,并引用它。第二行 ref 更改为引用 null。堆上不再有对该对象的引用,因此它将有资格进行垃圾收集,但在垃圾收集器这样做之前,它实际上仍然存在(排除这个简单示例的任何巧妙的 JVM 优化!)。
AFAIK Java 中没有“取消引用”的官方定义。因为评估和分配之间没有区别,所以它确实有意义,尽管我认为这不是一个被广泛使用的术语。
尽管没有正式定义,但在某些Java错误语句中使用了“取消引用”一词。
例如,如果您编写以下代码:
char ch = 'A';
if (ch.isLetter()) { }
Run Code Online (Sandbox Code Playgroud)
您得到错误: char cannot be dereferenced
因此,可以说在.操作员的帮助下使用对象的引用来访问对象的状态或行为就是取消引用。
\n\nJava 中 \xe2\x80\x9cdereferencing\xe2\x80\x9d 是否有正式或权威的定义?
\n
不。
\n您可以在 JLS 或 JVMS 中找到“取消引用”的正式定义。我看了看,没有找到。
\n我的直觉理解是,取消引用是从引用(松散地)引用“指向”的事物的一个组件的过程。
\n这里有些例子:
\nx = a.b; // dereferences the value of \'a\' to get the value of field \'b\'\na.b(); // dereferences the value of \'a\' to get the method \'b\'\nx = a[1]; // dereferences the value of \'a\' to an array and then subscripts it\na[1] = 2; // dereferences the value of \'a\' to an array, subscripts it\n // then assigns to the cell\n\n// dereferences the value of \'l\' to an object and acquires the\n// object\'s primitive lock\nsynchronized (l) {\nRun Code Online (Sandbox Code Playgroud)\n简而言之,每当您执行可能引发 NPE 的原始操作时,都会涉及取消引用。
\n请注意,这不是“分配引用”或(准确地说)“评估引用”。例如:
\nboolean truth = ...\nString s = truth ? "yes" : null;\nRun Code Online (Sandbox Code Playgroud)\n涉及评估三个引用值表达式并分配引用,但不取消引用。不会抛出 NPE...
\n好的,那么我对 Java 规范中“取消引用”的解释有任何支持吗?我声称有。
\nJLS 第 17 章包含我在最新版本的 JLS 中可以找到的术语“取消引用”的唯一用法。在 JLS 17.5.1 中, 的语义final被描述为“受解引用链影响”,其定义如下:
\n\n“取消引用链:如果一个操作是由未初始化的线程
\na读取或写入对象的字段或元素,则必须存在一些由看到该地址的线程进行的读取。”otortor dereferences(r, a)
如果你取消它实际上所说的内容(在其上下文中),我声称他们正在使用术语取消引用方式与我的第一个示例一致。
\n这也与C和C++中解引用运算符( )的含义一致;参见维基百科。我还可以在其他 Oracle 文档中找到以这种方式使用取消引用的示例;例如,对象关系模型的主要功能 > 取消引用 REF。*
| 归档时间: |
|
| 查看次数: |
10154 次 |
| 最近记录: |