您好我想在它的构造函数中初始化内部类的最终变量,但是编译器强制我在声明时初始化它为什么有任何想法?
我该如何处理这种情况?
public MainActivity extends Activity {
private class AcceptThread extends Thread {
private final BluetoothServerSocket mBluetoothServerSocket;
public AcceptThread() {
try {
mBluetoothServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord("BT_SERVER", UUID.fromString("a60f35f0-b93a-11de-8a39-08002009c666"));
} catch (IOException e) { }
}
// Here methods
}
}
Run Code Online (Sandbox Code Playgroud)
看到这里回答我的问题在这里看起来很奇怪



问题不是你试图在构造函数中初始化字段,而是你没有在catch块中初始化它.编译器必须确保在退出构造函数之前始终初始化该字段.
不幸的是,简单地在catch块中分配一个回退值是行不通的,因为当编译器看到这样的代码时:
try {
...
someFinalField = ...
...
} catch {
...
someFinalField = ...
...
}
Run Code Online (Sandbox Code Playgroud)
...然后它看到该字段初始化两次的可能性(一次在try块中,第二次在catch块中),这对于final字段是非法的.在您的简单情况下,我们清楚地看到这是不可能的,因为在块中初始化字段之前将始终抛出异常try,但不幸的是编译器不够聪明,无法理解.
您可以通过从catch块中抛出异常来满足编译器,这可能是您案例中的首选选项:
catch (IOException e) {
throw new RuntimeException(e);
}
Run Code Online (Sandbox Code Playgroud)
或者,使用非常流行的番石榴图书馆
catch (IOException e) {
throw Throwables.propagate(e);
}
Run Code Online (Sandbox Code Playgroud)
如果你真的想要吞下异常,那么 - 为了确保字段总是只被初始化一次,你必须在try-catch块之外移动初始化:
private class AcceptThread extends Thread {
private final BluetoothServerSocket mBluetoothServerSocket;
public AcceptThread() {
BluetoothServerSocket localBluetoothServerSocket;
try {
localBluetoothServerSocket = ...
} catch (IOException e) {
localBluetoothServerSocket = ...
}
mBluetoothServerSocket = localBluetoothServerSocket;
}
}
Run Code Online (Sandbox Code Playgroud)