问题标签 [jls]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - 并发代码中赋值运算符的返回值
给定以下课程:
并且给定多个线程在同一个实例上同时调用method1()
,对method1()的调用可以返回1以外的任何东西吗?method2()
Foo
java - 为什么在这种情况下为原始工作返回 null ?
这段丑陋的代码确实可以编译,但如果s == null
虽然这不是(如预期的那样):
我知道它们都明显是错误的,但是当我在我们的源代码中找到第一段代码时,我很惊讶它确实编译了。
编辑:这是 Java 7 中 JLS 的相关部分。我猜第一个语句会适用,但粗体的语句会适用。
15.25 条件运算符?:
[...]
条件表达式的类型确定如下:
[...]
- 如果第二个和第三个操作数之一是原始类型 T,而另一个的类型是对 T 应用装箱转换(第 5.1.7 节)的结果,则条件表达式的类型是 T。
[...]
- 否则,第二个和第三个操作数分别是 S1 和 S2 类型。令 T1 为对 S1 应用装箱转换产生的类型,令 T2 为对 S2 应用装箱转换产生的类型。条件表达式的类型是将捕获转换 (§5.1.10) 应用于 lub(T1, T2) (§15.12.2.7) 的结果。
java - 对 volatile 的写入是 Java 中的内存屏障吗
我最近在一次演讲中听说,对 volatile 的写入会触发线程写入的每个变量的内存屏障。这真的正确吗?从 JLS 来看,似乎只有相关变量被清除,而其他变量则没有。有人知道什么是正确的吗?可以指出我在 JLS 中的具体位置吗?
java - 调用返回相同类型的变量和类型本身的相同名称的静态方法时,“变量 xxx 可能尚未初始化”
为什么它会失败并出现如下所示的错误?我不确定在 JLS 中的哪个位置寻找限制来做这样的事情。
编译时出错
java - JLS 是否允许此指令重新排序?
根据 Java 语言规范(示例 17.4-1),以下代码段(从 开始A == B == 0
)...
... 可能导致r2 == 2
和r1 == 1
。这是因为执行的结果B = 1;
不取决于是否r2 = A
已经执行,因此JVM可以自由地交换这两条指令的执行顺序。换句话说,规范允许以下交织:
这显然导致r2 == 1
和r1 == 1
。
我的问题:
假设我们稍微调整一下这个例子:
whereobj
是线程之间共享的引用。
r2 = A
重新排序是否B = 1
仍然允许?
JLS 说……
但是,允许编译器对任一线程中的指令重新排序,只要这不会影响该线程的单独执行。
...这表明指令仍可能被交换。另一方面,以下声明
监视器上的解锁发生在该监视器上的每个后续锁定之前。
表明在某些调度下,我们可能在两个线程中的语句之间存在发生前的关系,这可能不允许指令重新排序。
java - 易失性 jls 示例
对于 volatile 的每个 JLS 示例,以下代码是否应该在 windows 7 x86 jdk 7(打开 -ea)上抛出 AssertionError ?
java - 是否有工具可以确定程序是否按照 JLS 中的定义“正确同步”?
Java 语言规范 7 (JLS7-17.4.5) 定义了一个“正确同步”的程序,如下所示:“当且仅当所有顺序一致的执行都没有数据竞争时,程序才能正确同步”。
JLS7-17.4.5 还指出:
如果没有正确的同步,可能会出现非常奇怪、令人困惑和违反直觉的行为。
因此,从程序员的角度来看,拥有一个工具来根据上述定义确定程序是否“正确同步”将非常有用。
有这样的工具吗?我用谷歌搜索找不到任何东西。如果没有这样的工具,是否有可能制作一个?
java - Java静态初始化块上的奇怪代码
在浏览 JLS 8.3.2.3时,我无法理解以下代码。
代码导致错误Cannot reference a field before it is defined
但是如果我将代码更改为
代码正在编译。但在这两种情况下,变量定义都在初始化块之后。这背后的奥秘是什么?
java - 关于在对象的构造函数完成之前对对象的引用
你们每个人都知道JMM的这个特性,有时对对象的引用可以在该对象的构造函数完成之前接收值。
在JLS7 中,p。17.5 final 字段语义我们还可以阅读:
字段的使用模型
final
很简单:final
在对象的构造函数中设置对象的字段;并且不要在对象的构造函数完成之前在另一个线程可以看到它的地方写对正在构造的对象的引用。如果遵循这一点,那么当另一个线程看到该对象时,该线程将始终看到该对象final
字段的正确构造版本。(1)
紧随其后的是 JLS 中的示例,该示例演示了如何不保证初始化 非最终(2)
字段(1Example 17.5-1.1) :
此外,在这个问答中,格雷先生写道:
如果将字段标记为,
final
则保证构造函数作为构造函数的一部分完成初始化。否则,您必须在使用锁之前对其进行同步。(3)
所以,问题是:
1)根据语句(1)我们应该避免在构造函数完成之前共享对不可变对象的引用
2) 根据 JLS 给出的示例 (2) 和结论 (3),我们似乎可以在其构造函数完成之前安全地共享对不可变对象的引用,即当它的所有字段都是.final
是不是有些矛盾?
EDIT-1:我的意思是什么。如果我们以这种方式修改示例中的类,该字段y
也将是final
(2):
因此在reader()
方法中可以保证:
如果是这样,为什么我们应该避免在它的构造函数完成之前写入对对象的引用f
(根据(1)),当所有字段f
都是最终的?