我在我正在处理的代码库中遇到以下代码:
public final class ConfigurationService {
private static final ConfigurationService INSTANCE = new ConfigurationService();
private List providers;
private ConfigurationService() {
providers = new ArrayList();
}
public static void addProvider(ConfigurationProvider provider) {
INSTANCE.providers.add(provider);
}
...
Run Code Online (Sandbox Code Playgroud)
INSTANCE被宣布为final.为什么可以添加对象INSTANCE?不应该使final的使用无效.(它没有).
我假设答案必须用指针和内存做一些事情,但我想肯定知道.
最终在下面的代码之间有什么不同.将参数声明为final是否有任何优势.
public String changeTimezone( Timestamp stamp, Timezone fTz, Timezone toTz){
return ....
}
public String changeTimezone(final Timestamp stamp, final Timezone fTz,
final Timezone toTz){
return ....
}
Run Code Online (Sandbox Code Playgroud) public class A
{
private static final int x;
public A()
{
x = 5;
}
}
Run Code Online (Sandbox Code Playgroud)
final 表示变量只能分配一次(在构造函数中).static 意味着它是一个类实例.我不明白为什么这是禁止的.这些关键字在哪里相互干扰?
在ArrayBlockingQueue,所有需要锁的方法final在调用之前将其复制到局部变量lock().
public boolean offer(E e) {
if (e == null) throw new NullPointerException();
final ReentrantLock lock = this.lock;
lock.lock();
try {
if (count == items.length)
return false;
else {
insert(e);
return true;
}
} finally {
lock.unlock();
}
}
Run Code Online (Sandbox Code Playgroud)
当字段是什么时,有没有理由复制this.lock到局部变量?lockthis.lockfinal
此外,它还在使用E[]之前使用本地副本:
private E extract() {
final E[] items = this.items;
E x = items[takeIndex];
items[takeIndex] = null;
takeIndex = inc(takeIndex);
--count;
notFull.signal();
return x;
}
Run Code Online (Sandbox Code Playgroud)
有没有理由将最终字段复制到本地最终变量?
我有一个这样的程序:
class Test {
final int x;
{
printX();
}
Test() {
System.out.println("const called");
}
void printX() {
System.out.println("Here x is " + x);
}
public static void main(String[] args) {
Test t = new Test();
}
}
Run Code Online (Sandbox Code Playgroud)
如果我尝试执行它,我收到编译器错误:variable x might not have been initialized基于java默认值我应该得到以下输出权?
"Here x is 0".
Run Code Online (Sandbox Code Playgroud)
最终变量是否具有dafault值?
如果我改变我的代码,
class Test {
final int x;
{
printX();
x = 7;
printX();
}
Test() {
System.out.println("const called");
}
void printX() {
System.out.println("Here x is " + x); …Run Code Online (Sandbox Code Playgroud) 在我们的团队中,我们发现了一些奇怪的行为,我们使用了两者static和final限定词 这是我们的测试类:
public class Test {
public static final Test me = new Test();
public static final Integer I = 4;
public static final String S = "abc";
public Test() {
System.out.println(I);
System.out.println(S);
}
public static Test getInstance() { return me; }
public static void main(String[] args) {
Test.getInstance();
}
}
Run Code Online (Sandbox Code Playgroud)
当我们运行该main方法时,我们得到一个结果:
null
abc
Run Code Online (Sandbox Code Playgroud)
我会理解它是否null两次写入值,因为静态类成员的代码是从上到下执行的.
任何人都可以解释为什么会发生这种行为?
System.out被宣布为public static final PrintStream out.
但你可以打电话System.setOut()重新分配它.
咦?这怎么可能呢final?
(同一点适用于System.in和System.err)
更重要的是,如果你可以改变公共静态最终字段,那么这对于final给你的保证(如果有的话)意味着什么呢?(我从未意识到也没有预料到System.in/out/err表现为final变量)
请考虑以下Java类声明:
public class Test {
private final int defaultValue = 10;
private int var;
public Test() {
this(defaultValue); // <-- Compiler error: cannot reference defaultValue before supertype constructor has been called.
}
public Test(int i) {
var = i;
}
}
Run Code Online (Sandbox Code Playgroud)
代码将无法编译,编译器抱怨我上面突出显示的行.为什么会发生此错误以及最佳解决方法是什么?
在lambda中,局部变量需要是final,但实例变量不需要.为什么这样?
final ×10
java ×10
constructor ×2
arguments ×1
immutability ×1
java-8 ×1
lambda ×1
methods ×1
optimization ×1
static ×1
supertype ×1