Java 8 通过 JSR308 引入了类型注释。根据Java语言规范
类型注释可以用在任何使用类型的地方,例如声明、泛型参数、强制转换等。
我对Java比较陌生,Java 8是我使用的第一个java版本,所以我不熟悉非“类型注释”,即声明注释。
声明注释与类型注释有何不同?我想知道,因为我不断在手册中听到它们,并且看起来“类型注释”是“声明注释”的超集。
有多个代码示例假定以下指令(1)和(2)不能重新排序:
int value;
volatile boolean ready;
// ...
value = 1; // (1)
ready = true; // (2)
Run Code Online (Sandbox Code Playgroud)
后一个 Stack Overflow 答案是指 JLS §17.4.5:
如果 x 和 y 是同一线程的动作,并且 x 在程序顺序中排在 y 之前,则 hb(x, y)。
但是我不明白为什么这应该适用于这里,因为 JLS示例 17.4-1还指出:
[...] 允许编译器重新排序任一线程中的指令,前提是这不会影响该线程的单独执行。
这显然是这里的情况。
JLS 中特定于的所有其他定义volatile仅针对相同的 volatile 变量,而不针对其他操作:
对 volatile 字段(第 8.3.1.4 节)的写入发生在该字段的每次后续读取之前。
在人们看到 volatile (读或写)的使用可能不会重新排序的保证时,我感到困惑。
您能否将您的解释基于 JLS 或基于 JLS 的其他来源。
考虑JLS \xc2\xa718.1.3 - 边界中的以下文章
\n在这里,当我们尝试识别推理变量的边界集时,我们会遇到以下情况之一:
\n\n\n...
\n\n
\n- throws \xce\xb1:推理变量 \xce\xb1 出现在 throws 子句中。
\n...
\nthrows \xce\xb1 形式的界限纯粹是信息性的:它指示解析优化 \xce\xb1 的实例化,以便在可能的情况下,它不是受检查的异常类型。
\n
我认为这个说法是不正确的:
\n我的理解正确还是我错过了什么?
\n重载的功能compute1(),compute2()以及compute5()导致编译错误,如果您尝试使用以下这些:
package com.example.test.reflect;
class JLS15Test2
{
int compute1(Object o1, Integer i, Integer j) { return 1; }
int compute1(String s1, Integer i, int j) { return 2; }
int compute2(Object o1, Integer i, int j) { return 3; }
int compute2(String s1, Integer i, Integer j) { return 4; }
int compute3(Object o1, Integer i, int j) { return 5; }
int compute3(String s1, Integer i, int j) { return 6; }
int compute4(Object …Run Code Online (Sandbox Code Playgroud) 我正在寻找Java语言规范(JLS)的相关部分,它描述了调用变量arity(vararg)方法时的行为.
考虑方法:
public static void printVarArgs(String... args) {
System.out.println(Arrays.toString(args));
}
Run Code Online (Sandbox Code Playgroud)
如果我像这样调用方法:
printVarArgs();
Run Code Online (Sandbox Code Playgroud)
输出将如下所示:[]因为args在调用站点中的省略已在方法中转换为空数组printVarArgs.
我正在寻找定义此行为的JLS的观点.我找到的最接近的是15.12.4.2评估参数,但它没有给出这个例子,我不确定这种情况是否实际涵盖在正式/数学描述中.
当省略vararg时,JLS的哪一部分描述了自动创建空数组?
以下文字来自jls http://docs.oracle.com/javase/specs/jls/se7/html/jls-17.html#jls-17.5.3
Even then, there are a number of complications. If a final field is
initialized to a compile-time constant expression (§15.28) in the field
declaration, changes to the final field may not be observed, since uses of that
final field are replaced at compile time with the value of the constant
expression.
Run Code Online (Sandbox Code Playgroud)
任何人都可以给我更好的解释.我无法理解这一说法changes to the final field may not be observed.可以借助例子.
提前致谢
包由许多编译单元组成(第7.3节).编译单元自动访问其包中声明的所有类型,并自动导入预定义包java.lang中声明的所有公共类型.
让我们假设以下代码:
package com.example.p1;
public class MyClass { }
Run Code Online (Sandbox Code Playgroud)
package com.example;
public class MyClass { }
Run Code Online (Sandbox Code Playgroud)
package com.example;
public class String { }
Run Code Online (Sandbox Code Playgroud)
package com.example;
import com.example.p1.*;
public class MainNameClash {
private String s; // No Error, even though ambiguous with java.lang.String!
private MyClass m; // No error, even though ambiguous with com.example.p1.MyClass!
}
Run Code Online (Sandbox Code Playgroud)
如果我MyClass从中com.example移入com.example.p2并导入它import com.example.p2.*,我会到达Error: the type MyClass is ambigious使用它的地方.
似乎包中的类型总是优先于任何其他导入的类型,无论是自动显示java.lang还是显式地使用通配符导入,并且编译器不会发出任何警告或错误.
题: …
我正在浏览类的源代码,java.util.HashMap并注意到显式的no-arg构造函数需要两个常量:
/**
* Constructs an empty <tt>HashMap</tt> with the default initial capacity
* (16) and the default load factor (0.75).
*/
public HashMap() {
this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
}
Run Code Online (Sandbox Code Playgroud)
但是当我查看DEFAULT_INITIAL_CAPACITY常量时,我发现它的定义如下:
/**
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
Run Code Online (Sandbox Code Playgroud)
我从未见过我使用过的任何产品中使用的这种类型的构造,并且在Java语言规范或谷歌搜索中找不到任何结果.所以我查看了字节代码,但我发现使用16vs 1 << 4提供了相同的输出,这意味着(至少在我的极简主义情况下)编译器会将后者转换为十进制表示法.两个版本的字节码包括以下定义:
javap -c -verbose /---/myClass.class
----
public static final int i;
flags: ACC_PUBLIC, ACC_STATIC, ACC_FINAL …Run Code Online (Sandbox Code Playgroud) 我对JLS第3版和推理机制有疑问.第15.12.2.7节规定:
如果F = U [],其中类型U涉及Tj,那么如果A是数组类型V [],或者类型变量的上限是数组类型V []
我尝试创建一个数组类型上限的类型变量,但编译器似乎不接受这一点.就像是:
public class MyClass<T extends String []> {
}
Run Code Online (Sandbox Code Playgroud)
我的问题是:这个片段中的JLS是错误的,还是我错过了什么?句子的最后一部分似乎对我不满意.
谢谢