首先,一个难题:下面的代码打印什么?
public class RecursiveStatic {
public static void main(String[] args) {
System.out.println(scale(5));
}
private static final long X = scale(10);
private static long scale(long value) {
return X * value;
}
}
静态修饰符与最终修饰符结合使用也用于定义常量。最后一个修饰符指示此字段的值不能更改。
来源:https://docs.oracle.com/javase/tutorial/java/javaoo/classvars.html[加重点]
我的问题是:这是一个bug吗?final
定义不清吗?
public class RecursiveStatic {
public static void main(String[] args) {
System.out.println(scale(5));
}
private static final long X = scale(10) + 3;
private static long scale(long value) {
System.out.println("X = " + X);
return X * value;
}
}
a=5
a=5
一个非常有趣的发现。为了理解它,我们需要深入研究Java语言规范(JLS)。
原因是final
只允许一次赋值。但是,默认值是不赋值。事实上,每一个这样的变量(类变量、实例变量、数组组件)在赋值之前从一开始就指向它的默认值。然后第一个赋值更改引用。
看一下下面的例子:
private static Object x;
public static void main(String[] args) {
System.out.println(x); // Prints 'null'
}
public static void main(String[] args) {
Object x;
System.out.println(x);
// Compile-time error:
// variable x might not have been initialized
}
局部变量(§14.4,§14.14)在使用之前必须通过初始化(§14.4)或赋值(§15.26),以一种可以使用明确赋值规则(§16(明确赋值))来验证的方式显式地给出一个值。
现在我们来看看§4.12.4final
:
最终变量
public static void main(String[] args) {
System.out.println("After: " + X);
}
private static final long X = assign();
private static long assign() {
// Access the value before first assignment
System.out.println("Before: " + X);
return X + 1;
}
Before: 0
After: 1
private static long assign() {
// Assign X
X = 1;
// Second assign after method will crash
return X + 1;
}
多亏了@Andrew,我找到了一个JLS段落,正好涵盖了这个场景,它还演示了这个场景。
但首先让我们来看看
private static final long X = X + 1;
// Compile-time error:
// self-reference in initializer
为什么这是不允许的,而来自方法的访问是允许的?请看§8.3.3,它讨论了如果字段尚未初始化,对字段的访问何时受到限制。
>
引用出现在C
的类变量初始化器中,或者出现在C
的静态初始化器中(§8.7);和
引用可以出现在F
自己的声明符的初始值设定项中,也可以出现在F
声明符的左侧;和
引用不在赋值表达式的左手边(§15.26);和
class Z {
static int peek() { return j; }
static int i = peek();
static int j = 1;
}
class Test {
public static void main(String[] args) {
System.out.println(Z.i);
}
}
产生输出:
0
因为i
的变量初始化器使用类方法peek在j
被其变量初始化器初始化之前访问变量j
的值,此时它仍然具有默认值(§4.12.5)。
问题内容: 首先,一个难题:以下代码显示什么? 回答: 0 扰流板如下。 如果您打印的规模(长),并重新定义,印刷品会那么。这意味着暂时设置为,后来又设置为。这是违反! 静态修饰符与最终修饰符结合使用,还可以定义常量。最后的修饰符指示 此字段 的值 不能更改 。 来源:https : //docs.oracle.com/javase/tutorial/java/javaOO/classvars.h
从现在起,在退出后,每当重新进入 Chroot 环境,请使用下面修改过的 chroot 命令: chroot "$LFS" /usr/bin/env -i \ HOME=/root TERM="$TERM" PS1='\u:\w\$ ' \ PATH=/bin:/usr/bin:/sbin:/usr/sbin \ /bin/bash --login 这样做的理由是起初在
问题内容: 从http://docs.oracle.com/javase/6/docs/api/java/lang/String.html中我可以读到: 从某种意义上说该属性是多余的,这是否意味着a 在Java中实际上没有意义? 问题答案: 该对象是不可变的,但实际上是对可以更改的对象的引用。 例如: 您可以重新分配此变量保存的值(以使其引用其他字符串): 但是,这样做: 然后,上述重新分配将是不
到目前为止,我认为有效的final和final或多或少是等价的,如果在实际行为中不完全相同,JLS会将它们视为相似的。然后我发现了这个人为的场景: 显然,JLS在这两者之间产生了重要的区别,我不知道为什么。 我阅读其他线程,如 最终和有效最终之间的差异 有效的最终变量vs最终变量 变量“有效最终”是什么意思 但他们并没有详细说明。毕竟,在更广泛的层面上,它们似乎几乎相当。但深入研究,他们显然有所不
问题内容: 我想在UITextField上创建自定义清除按钮,即使用rightView并将图像放在此处,问题是将原始的清除按钮事件附加到该自定义rightView上。 在Objective-C中,我可以这样做: 现在如何将其转换为Swift?或任何解决方法? 问题答案: 您可以将自定义按钮添加为类似这样的右视图
在Java中,重写方法会受到很大的批评,尽管我不明白这是为什么。像这样的类使用它来确保在Java8和Java10中调用。然而,Java9引入了,它使用PhantomReference机制而不是GC终结。一开始,我认为这只是一种向第三方类添加终结的方法。但是,它的javadoc中给出的示例显示了一个可以很容易地用终结器重写的用例。 我是否应该用清洁器重写所有的方法?(当然,我没有很多。只有一些使用O