标签: jls

注释属性必须是类文字?为什么?常数也应该没问题

有人可以解释为什么String和Class注释参数的预期不同吗?为什么编译器需要Classes的文字,wherby也接受字符串的常量?

使用Spring的@RequestMapping的工作示例:

public class MyController {
    public static final String REQUEST_MAPPING = "/index.html";
    @RequestMapping(MyController.REQUEST_MAPPING) // ALL OK!
    ...
}
Run Code Online (Sandbox Code Playgroud)

使用TestNG的@Test的WTF示例:

public class MyControllerTest {
    public static final Class TEST_EXCEPTION = RuntimeException.class;
    @Test(expectedExceptions = MyControllerTest.TEST_EXCEPTION) // compilation error, WTF:
    // The value for annotation attribute Test.expectedExceptions must be a class literal
    ...
}
Run Code Online (Sandbox Code Playgroud)

什么工作当然是@Test(expectedExceptions = RuntimeException.class).但为什么?我看到的注释参数的唯一区别是它的类型:String vs Class.为什么Java编译器也接受String常量,但只接受类文字?

java testng jls

10
推荐指数
1
解决办法
8768
查看次数

JLS中f1()+ f2()* f3()表达式的执行顺序和运算符优先级

给定一个f1() + f2()*f3()带有3个方法调用的表达式,java首先计算加法运算(的操作数):

int result = f1() + f2()*f3();

f1 working
f2 working
f3 working
Run Code Online (Sandbox Code Playgroud)

我(错误地)期望f2()首先被呼叫,然后被呼叫f3(),最后被呼叫f1()。因为乘法应在加法之前求值。

所以,我在这里不了解JLS-我想念什么?

15.7.3。评估尊重括号和优先权

Java编程语言遵守 由括号显式表示由运算符优先级隐式表示的评估顺序

在此示例中,如何精确地遵守运算符优先级?

JLS在15.7.5中提到了一些例外其他表达式(方法调用表达式(§15.12.4),方法引用表达式(§15.13.3))的评估顺序,但是我不能将这些异常中的任何一个应用于我的示例。

我知道JLS保证二进制运算的操作数从左到右求值。但是在我的示例中,为了了解方法调用顺序,有必要了解首先考虑哪个操作(及其两个操作数!)。我在这里错了-为什么?

更多示例:

int result = f1() + f2()*f3() + f4() + f5()*f6() + (f7()+f8());
Run Code Online (Sandbox Code Playgroud)

自豪地生产:

f1 working
f2 working
f3 working
f4 working …
Run Code Online (Sandbox Code Playgroud)

java evaluation expression-evaluation operator-precedence jls

10
推荐指数
2
解决办法
297
查看次数

为什么这会超过Java构造函数和静态初始化程序中的65,535字节限制?

免责声明:我意识到我可以在运行时用Java生成这个,这是一个非常特殊的情况下需要的,同时性能测试一些代码.我发现了一种不同的方法,所以现在这只是一种好奇心而不是任何实际的东西.

我已经尝试了以下作为静态字段,作为实例字段,并直接在构造函数中初始化.每次eclipse通知我"构造函数TestData()的代码超过65535字节限制"或"静态初始化程序的代码超过65535字节限制".

有10,000个整数.如果每个int是4个字节(32位),那么那不是40,000个字节吗?除了仅构建数组的数据之外,还有更多的25,0000字节的开销吗?

使用这一小段python生成数据:

#!/usr/bin/python

import random;
print "public final int[] RANDOM_INTEGERS = new int[] {";
for i in range(1,10000):
    print str(int(random.uniform(0,0x7fffffff))) + ",";
print "};";
Run Code Online (Sandbox Code Playgroud)

这是一个小样本:

public final int[] RANDOM_INTEGERS = new int[] {
    963056418, 460816633, 1426956928, 1836901854, 334443802, 721185237, 488810483,
    1734703787, 1858674527, 112552804, 1467830977, 1533524842, 1140643114, 1452361499,
    716999590, 652029167, 1448309605, 1111915190, 1032718128, 1194366355, 112834025,
    419247979, 944166634, 205228045, 1920916263, 1102820742, 1504720637, 757008315,
    67604636, 1686232265, 597601176, 1090143513, 205960256, 1611222388, 1997832237,
    1429883982, 1693885243, 1987916675, 159802771, 1092244159, 1224816153, 1675311441,
    1873372604, 1787757434, 1347615328, …
Run Code Online (Sandbox Code Playgroud)

java jls

9
推荐指数
2
解决办法
8675
查看次数

为什么Java中的try/catch或synchronized需要语句块?

Java允许某些关键字后跟语句或语句块.例如:

if (true)
    System.out.println("true");

do
    System.out.println("true");
while (true);
Run Code Online (Sandbox Code Playgroud)

编译以及

if(true) {
    System.out.println("true");
}

do {
   System.out.println("true");
} while (true);
Run Code Online (Sandbox Code Playgroud)

这也适用于像关键字for,while等等.

但是,有些关键字不允许这样做.synchronized需要一个块语句.相同try ... catch ... finally,这需要在关键字后面至少有两个块语句.例如:

try {
    System.out.println("try");
} finally {
    System.out.println("finally");
}

synchronized(this) {
    System.out.println("synchronized");
}
Run Code Online (Sandbox Code Playgroud)

有效,但以下内容无法编译:

try
    System.out.println("try");
finally
    System.out.println("finally");

synchronized (this)
    System.out.println("synchronized");
Run Code Online (Sandbox Code Playgroud)

那么为什么Java中的某些关键字需要块语句,而其他关键字允许块语句以及单个语句?这是语言设计的不一致,还是有某种原因?

java jls

9
推荐指数
1
解决办法
507
查看次数

表达式包含"最多一个副作用,作为其最外层的操作"是什么意思?

Java Language Spex 15.7中:

当每个表达式最多包含一个副作用时,代码通常更清晰,作为其最外层的操作

这是什么意思?

java jls

9
推荐指数
2
解决办法
418
查看次数

Java语言规范中是否存在"重大变化"?

有了'assert'关键字引入的可能广为人知的例外,Java语言规范是否曾发生变化,导致旧代码不再与JDK的新源代码兼容?


总结到目前为止(非常感谢评论):

如果代码使用在Java语言规范(JLS)的更高版本中引入的关键字之一的声明,则"旧"Java代码在升级到更高版本时可能会导致编译错误:

  • 断言
  • 枚举
  • strictfp

java jls

9
推荐指数
1
解决办法
1328
查看次数

通过反射改变最终变量,为什么静态和非静态最终变量之间存在差异

请参考以下代码.当我运行代码时,我能够更改最终的非静态变量的值.但是,如果我尝试更改最终静态变量的值,那么它会抛出java.lang.IllegalAccessException.

我的问题是为什么它不会在非静态最终变量的情况下抛出异常,反之亦然.为什么不同?

import java.lang.reflect.Field;
import java.util.Random;

public class FinalReflection {

    final static int stmark =  computeRandom();
    final int inmark = computeRandom();

    public static void main(String[] args) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
        FinalReflection obj = new FinalReflection();
        System.out.println(FinalReflection.stmark);
        System.out.println(obj.inmark);
        Field staticFinalField  = FinalReflection.class.getDeclaredField("stmark");
        Field instanceFinalField  = FinalReflection.class.getDeclaredField("inmark");
        staticFinalField.setAccessible(true);
        instanceFinalField.setAccessible(true);

        instanceFinalField.set(obj, 100);
        System.out.println(obj.inmark);

        staticFinalField.set(FinalReflection.class, 101);
        System.out.println(FinalReflection.stmark);

    }

    private static int computeRandom() {
        return new Random().nextInt(5);
    }
}
Run Code Online (Sandbox Code Playgroud)

java reflection static final jls

9
推荐指数
1
解决办法
6797
查看次数

非法的静态接口方法调用

Java-8允许在接口内部定义静态方法,但仅通过接口名称限制它的调用:

9.4:接口可以声明静态方法,这些方法在不引用特定对象的情况下被调用.

例如:

interface X {
    static void y() {
    }
}

...

X x = new X() {};
x.y();
Run Code Online (Sandbox Code Playgroud)

导致错误:

error: illegal static interface method call
        x.y();
            ^
  the receiver expression should be replaced with the type qualifier 'X'
Run Code Online (Sandbox Code Playgroud)

通常在JLS中,这种禁令有一个解释.在这种情况下,我没有发现任何详细的信息.所以我正在寻找对此规则的全面或权威解释:为什么禁止通过特定对象引用调用静态方法?它打破了什么?

java jls java-8

9
推荐指数
1
解决办法
1168
查看次数

是否有常量的正式定义?

Java规范是否定义了常量的原理,还是留给了推荐角色?

如果在规范中定义,它的定义是什么?

具体而言,以下任何或所有例子都被视为常数吗?如果确实存在部分或全部,是否按照规范或任何其他官方建议进行了考虑?

public static final int ONE = 1;
public static final double TWO = 2.0d;
public static final String THREE = "three";
public static final ImmutableList<Integer> ONE_TWO_THREE = ImmutableList.of(1, 2, 3);
public static final Logger logger = LogManager.getLogManager().getLogger(ThisClass.class);
Run Code Online (Sandbox Code Playgroud)

java jls

9
推荐指数
1
解决办法
1155
查看次数

getVolatile 和 getAcquire 有什么区别?

使用例如AtomicIntegergetVolatile时与getAcquire有什么区别?

\n\n

PS:这些都与

\n\n
\n

a\xc2\xa0synchronizes-with\xc2\xa0edge 的源称为\xc2\xa0release,目标称为\xc2\xa0acquire。

\n
\n\n

来自https://docs.oracle.com/javase/specs/jls/se8/html/jls-17.html#jls-17.3

\n

java jls

9
推荐指数
1
解决办法
3551
查看次数