Java 中没有初始化和用法的字段声明
Declaration of field without initializations and usages in Java
我有一个问题涉及 java 编译器行为以及 android 的不同 API。
我有 class 表示蓝牙 LE 连接。我在这个 class 中检查了 API 的版本,以了解我必须使用哪些方法来扫描设备。这是:
public class BleConnector{
private MyScanCallback _scanCallback;
private LeScanHandle _leScanHndl;
private BluetoothAdapter _bluetoothAdapter;
/**
* Initializes new instance of BLE connector
*/
public BleConnector()
{
//Creating handle for device scan callback;
_leScanHndl = new LeScanHandle();
//Check version of android api
//If it is bigger of equal to 21
//create scan callback for higher versions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
_scanCallback = new ScanCallback(_leScanHndl);
}
}
public void startScan(Context context) throws PermissoinException
{
final BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
_bluetoothAdapter = bluetoothManager.getAdapter();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED)
{
_bluetoothAdapter.getBluetoothLeScanner().startScan(_scanCallback);
}
else
{
throw new PermissoinException("Location permission does not allowed");
}
}
else
{
_bluetoothAdapter.startLeScan(_leScanHndl);
}
//TODO notify
}
public void stopScan()
{
if (_bluetoothAdapter != null)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
_bluetoothAdapter.getBluetoothLeScanner().stopScan(_scanCallback);
} else
{
_bluetoothAdapter.stopLeScan(_leScanHndl);
}
}
//TODO notify
}
private void connectToDevice(BluetoothDevice device)
{
//TODO notify
//TODO connect gatt
}
Class MyScanCallback 标有@TargetAPI 21,当然,如果我的设备版本低于 21
,我不想使用它
如您所见,_scanCallback 的所有用法和初始化都在 if 语句中。所以我的问题是:
在 api<21 的设备上声明 private MyScanCallback _scanCallback;
会不会有任何问题,或者如果没有 _scanCallback[=33= 的初始化和用法,编译器将删除它]?
谢谢!
UDT
哦,我没有说 MyScanCallback 继承了 ScanCallback,它来自 21 API 级别 public class MyScanCallback extends ScanCallback
@TargetApi 21 只是为了防止使用任何新的 APIs 时出现任何编译错误。为了真正避免执行代码,它必须像您在几个地方所做的那样围绕构建版本检查进行包装。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
}
所以在这种情况下,肯定会创建一个 MyScanCallback 变量,但它不会在具有 api<21 的设备上实例化,因为您已将其包装在构造函数中的版本检查中。
正如您提到的,它使用的是 API 21 中引入的 ScanCallback,那么在旧版本中使用它肯定会出现问题。
要摆脱这种情况,我建议创建一个摘要 class,如下所示:
public abstract class BleConnector{
public abstract void startScan(Context context);
}
然后创建两个classes
public class BleConnectOldApi extends BleConnector{
public void startScan(Context context) throws PermissoinException {
//Your code here
}
}
和
@TargetApi(21)
public class BleConnect21Api extends BleConnector{
private MyScanCallback _scanCallback;
public void startScan(Context context) throws PermissoinException {
//Your code here
}
}
终于有了工厂class
public class BleConnectorFactory{
public static BleConnector getBleConnector() {
if (android.os.Build.VERSION.SDK_INT >= 21) {
return new BleConnect21Api();
}else{
return new BleConnectOldApi();
}
}
}
通过这种方式,您可以防止使用旧 API 版本中不存在的 class 时出现不必要的错误。
希望对您有所帮助。
我有一个问题涉及 java 编译器行为以及 android 的不同 API。
我有 class 表示蓝牙 LE 连接。我在这个 class 中检查了 API 的版本,以了解我必须使用哪些方法来扫描设备。这是:
public class BleConnector{
private MyScanCallback _scanCallback;
private LeScanHandle _leScanHndl;
private BluetoothAdapter _bluetoothAdapter;
/**
* Initializes new instance of BLE connector
*/
public BleConnector()
{
//Creating handle for device scan callback;
_leScanHndl = new LeScanHandle();
//Check version of android api
//If it is bigger of equal to 21
//create scan callback for higher versions
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
_scanCallback = new ScanCallback(_leScanHndl);
}
}
public void startScan(Context context) throws PermissoinException
{
final BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
_bluetoothAdapter = bluetoothManager.getAdapter();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
if (ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED)
{
_bluetoothAdapter.getBluetoothLeScanner().startScan(_scanCallback);
}
else
{
throw new PermissoinException("Location permission does not allowed");
}
}
else
{
_bluetoothAdapter.startLeScan(_leScanHndl);
}
//TODO notify
}
public void stopScan()
{
if (_bluetoothAdapter != null)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
_bluetoothAdapter.getBluetoothLeScanner().stopScan(_scanCallback);
} else
{
_bluetoothAdapter.stopLeScan(_leScanHndl);
}
}
//TODO notify
}
private void connectToDevice(BluetoothDevice device)
{
//TODO notify
//TODO connect gatt
}
Class MyScanCallback 标有@TargetAPI 21,当然,如果我的设备版本低于 21
,我不想使用它如您所见,_scanCallback 的所有用法和初始化都在 if 语句中。所以我的问题是:
在 api<21 的设备上声明 private MyScanCallback _scanCallback;
会不会有任何问题,或者如果没有 _scanCallback[=33= 的初始化和用法,编译器将删除它]?
谢谢!
UDT
哦,我没有说 MyScanCallback 继承了 ScanCallback,它来自 21 API 级别 public class MyScanCallback extends ScanCallback
@TargetApi 21 只是为了防止使用任何新的 APIs 时出现任何编译错误。为了真正避免执行代码,它必须像您在几个地方所做的那样围绕构建版本检查进行包装。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
{
}
所以在这种情况下,肯定会创建一个 MyScanCallback 变量,但它不会在具有 api<21 的设备上实例化,因为您已将其包装在构造函数中的版本检查中。
正如您提到的,它使用的是 API 21 中引入的 ScanCallback,那么在旧版本中使用它肯定会出现问题。
要摆脱这种情况,我建议创建一个摘要 class,如下所示:
public abstract class BleConnector{
public abstract void startScan(Context context);
}
然后创建两个classes
public class BleConnectOldApi extends BleConnector{
public void startScan(Context context) throws PermissoinException {
//Your code here
}
}
和
@TargetApi(21)
public class BleConnect21Api extends BleConnector{
private MyScanCallback _scanCallback;
public void startScan(Context context) throws PermissoinException {
//Your code here
}
}
终于有了工厂class
public class BleConnectorFactory{
public static BleConnector getBleConnector() {
if (android.os.Build.VERSION.SDK_INT >= 21) {
return new BleConnect21Api();
}else{
return new BleConnectOldApi();
}
}
}
通过这种方式,您可以防止使用旧 API 版本中不存在的 class 时出现不必要的错误。
希望对您有所帮助。