标签: jls

是否可以为其他注释类型的注释字段指定默认值?

public @interface InnerAnnotation {
    String value() default "hello";
}

public @interface OuterAnnotation {
    InnerAnnotation value() default ???
}
Run Code Online (Sandbox Code Playgroud)

还有一种情况

public @interface AnotherOuterAnnotation {
    InnerAnnotation[] value() default ??? UPD: {} 
}
Run Code Online (Sandbox Code Playgroud)

java annotations jls

6
推荐指数
1
解决办法
1013
查看次数

什么(在规范中)保证'非短路逻辑运算符实际上不会短路?

这直接受到这个问题的启发.
有许多引用/声明,当应用于布尔运算符时,按位运算符不会短路.换句话说boolean a = f() & g(),where f()g()both都返回boolean,两者都将被评估.
但是,JLS只说:

15.22.2布尔逻辑运算符&,^和|
当两个操作数都是&,^或|时 operator的类型为boolean或Boolean,则按位运算符表达式的类型为boolean.在所有情况下,操作数都根据需要进行拆箱转换(第5.1.8节).

对于&,如果两个操作数值都为真,则结果值为true; 否则,结果是错误的.

对于^,如果操作数值不同,则结果值为true; 否则,结果是错误的.

对于|,如果两个操作数值都为false,则结果值为false; 否则,结果是真的.

这如何保证两个操作数都被实际评估?除此之外xor,如果其中一个参数(可能是第二个/右边首先被评估)违反条件,您仍然可以中断并返回结果.
例如.a & b只需要评估b为false就可以将表达式计算为false.

请注意:我不是问它是否以这种方式实现(不会短路) - 当然是.

我在问:

短路实施会违反语言标准吗?

java short-circuiting jls

6
推荐指数
1
解决办法
161
查看次数

线程中的最终字段语义

这是来自JLS 17.5:

最终字段的使用模型很简单.在该对象的构造函数中设置对象的最终字段.在对象的构造函数完成之前,不要在另一个线程可以看到的位置写入对正在构造的对象的引用.如果遵循此原因,那么当另一个线程看到该对象时,该线程将始终看到该对象的最终字段的正确构造版本.它还将看到那些最终字段引用的任何对象或数组的版本,这些字段至少与最终字段一样是最新的.

JLS 17.5中的讨论包括以下示例代码:

class FinalFieldExample {
    final int x;
    int y;
    static FinalFieldExample f;

    public FinalFieldExample() {
        x = 3;
        y = 4;
    }

    static void writer() {
        f = new FinalFieldExample();
    }

    static void reader() {
        if (f != null) {
            int i = f.x; // guaranteed to see 3
            int j = f.y; // could see 0
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试重用这段代码来复制上面的情况,这就是我所拥有的:

public class FinalFieldThread extends Thread {

    public static void main(String[] args) {
        ThreadA …
Run Code Online (Sandbox Code Playgroud)

java multithreading final thread-safety jls

6
推荐指数
1
解决办法
735
查看次数

为什么在Enum中hashCode()引用Object hashCode()实现,而不是ordinal()函数?

我一直以为enum hashCode在Java中引用了序数,因为序数似乎是hashCode的完美候选者,但事实证明它的枚举hashCode实际上是指默认的hashCode对象实现.

我明白,这并不与JLS相矛盾,但这让我感到惊讶,我想不出为什么会这样做.虽然我猜JVM,可能依赖于它以某种方式提供独特的保证,但这不再适用于64位JVM.

我已经检查过JDK 1.6和最新的JDK 7,这两种方式都是一样的.

有没有人知道原因,是这样做的?

使用序数作为hashCode是完全合理的,因为它满足了所需的所有凭证,而且从一个JVM开始到另一个JVM开始甚至是一致的,这不是必需的,但是很好.

java enums hashcode jls

6
推荐指数
1
解决办法
1403
查看次数

限定名称和字段访问表达式之间有什么区别?

受保护访问JLS详细信息:

设C是声明受保护成员的类.仅允许在C的子类S的主体内访问.

此外,如果Id表示实例字段或实例方法,则:

如果访问是通过限定名称Q.Id,其中Q是ExpressionName,则当且仅当表达式Q的类型是S或S的子类时才允许访问.

如果访问是通过字段访问表达式E.Id,其中E是主表达式,或通过方法调用表达式E.Id(...),其中E是主表达式,则允许访问当且仅当如果E的类型是S或S的子类.

限定名称字段访问表达式之间什么区别?

java jls

6
推荐指数
1
解决办法
937
查看次数

Java语言规范:符号的含义| S |

我将通过JLS 7来理解类型转换第5.5.1节.

它说:给定编译时引用类型S(源)和编译时引用类型T(目标),如果由于以下规则没有发生编译时错误,则从S到T存在转换转换.如果S是类类型:

  • 如果T是类类型,则为| S | <:| T |,或| T | <:| S | .否则,发生编译时错误.

他们说得很清楚,如果S和T有两种类型的第4.10节,然后

  • S:> T表示S是超类型的T.
  • S>Ť表示S被的T,这意味着一个适当的超类型S:>ŤS =Ť! .

我无法找到| S |的含义 .请帮助我理解| S |的含义 ?它是指属性的数量和类型还是其他东西.我试图在JLS中搜索它,但找不到它的含义.提前致谢.

java types casting type-conversion jls

6
推荐指数
1
解决办法
264
查看次数

何时将对象和基元与'=='运算符进行比较是合法的?

以下(Java)代码是否合法?

class Test {
  Object foo() {return "";}
  boolean bar() {return foo() == true;}
}
Run Code Online (Sandbox Code Playgroud)

它不会针对JDK 6编译,但在7+上似乎没问题.规格有变化吗?修复了一个错误吗?我一直在http://bugs.eclipse.org/bugs/show_bug.cgi?id=416950上讨论过这个问题.

java autoboxing operators jls

6
推荐指数
1
解决办法
711
查看次数

Java语言规范的示例8.1.2-1(相互递归类型变量边界)

我正在阅读jls 8,我被卡在例8.1.2-1上,Mutually Recursive Type Variable Bounds我搜索了stackoverflow,并发现了一个什么是相互递归类型的问题?但这不是Java方面的问题.

例8.1.2-1.相互递归类型变量边界

interface ConvertibleTo<T> {
    T convert();
}
class ReprChange<T extends ConvertibleTo<S>,
                 S extends ConvertibleTo<T>> { 
    T t; 
    void set(S s) { t = s.convert();    } 
    S get()       { return t.convert(); } 
}
Run Code Online (Sandbox Code Playgroud)

题:

  • 这是什么递归类型相互递归类型在Java中意味着什么?

  • T extends ConvertibleTo<S>, S extends ConvertibleTo<T>意味着什么?

  • 如果我只是用T extends ConvertibleTo<S>作为类型参数类ReprChange我收到编译时错误?

java recursion jls

6
推荐指数
1
解决办法
256
查看次数

原子比较和交换是否可以覆盖惰性写入而不会看到它?

JLS 的内存模型部分(17.4)以合理的细节描述了volatilevolatile读写的语义,以及与某些其他结构(如监视器进入和退出)的交互.

然而,这并不能完全解释的语义compareAndSwap,也不lazySet在java.util.concurrent.atomic中*类.因为compareAndSet,你有javadoc包中的blurb :

compareAndSet and all other read-and-update operations such as getAndIncrement 
have the memory effects of both reading and writing volatile variables. 
Run Code Online (Sandbox Code Playgroud)

lazySet 提供了一些更难以理解的模糊:

lazySet has the memory effects of writing (assigning) a volatile variable 
except that it permits reorderings with subsequent (but not previous)
memory actions that do not themselves impose reordering constraints with
ordinary non-volatile writes. Among other usage contexts, lazySet may …
Run Code Online (Sandbox Code Playgroud)

java concurrency java-memory-model jls

6
推荐指数
1
解决办法
153
查看次数

为什么Java编译器不能从约束Iterable &lt;推断出Iterable &lt;String&gt;?扩展CharSequence&gt;和()-&gt;(Iterator &lt;String&gt;)

背景:最近我写了一个答案,建议我编写以下代码:

Files.write(Paths.get("PostgradStudent.csv"),
        Arrays.stream(PGstudentArray).map(Object::toString).collect(Collectors.toList()),
        StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
Run Code Online (Sandbox Code Playgroud)

经过一番思考,我说:“我实际上不需要这里的列表,我只需要一个Iterable<? extends CharSequence>”。
就像Stream<T>一种方法一样Iterator<T> iterator(),然后我想到了,这很容易:

Iterable<? extends CharSequence> iterable = () -> Arrays.stream(arr).map(Object::toString).iterator();
Run Code Online (Sandbox Code Playgroud)

(针对这个问题,我将其提取到一个局部变量中,我想最后进行内联。)
不幸的是,如果没有其他类型提示,则无法编译该代码:

error: incompatible types: bad return type in lambda expression
Iterable<? extends CharSequence> iterable = () -> Arrays.stream(arr).map(Object::toString).iterator();
                                                                                                   ^
    Iterator<String> cannot be converted to Iterator<CharSequence>
Run Code Online (Sandbox Code Playgroud)

当然添加一些类型提示将使这项工作:

Iterable<? extends CharSequence> iterable2 = (Iterable<String>) () -> Arrays.stream(arr).map(Object::toString).iterator();
Iterable<? extends CharSequence> iterable3 = () -> Arrays.stream(arr).<CharSequence>map(Object::toString).iterator();
Run Code Online (Sandbox Code Playgroud)

以我的理解,Java编译器执行以下操作:

  1. 它查看表达式的目标类型,即Iterable<? extends CharSequence>
  2. 然后,它确定此接口的功能类型,() -> Iterator<? …

java lambda type-inference jls

6
推荐指数
1
解决办法
113
查看次数