Java中没有初始化和用法的字段声明

Posted

技术标签:

【中文标题】Java中没有初始化和用法的字段声明【英文标题】:Declaration of field without initializations and usages in Java 【发布时间】:2016-10-31 02:45:45 【问题描述】:

我有一个问题涉及 java 编译器行为以及 android 的不同 API。

我有代表蓝牙 LE 连接的课程。我检查了这个类中的 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

MyScanCallback 类标有@TargetAPI 21,如果我的设备版本低于 21,我当然不想使用它

如您所见,_scanCallback 的所有用法和初始化都在 if 语句中。所以我的问题是:

在带有 apiprivate MyScanCallback _scanCallback; 是否有任何问题,或者如果没有 _scanCallback 的初始化和使用,编译器将删除它?

谢谢!

UDT

哦,我没有说 MyScanCallback 继承了 ScanCallback ,它来自 21 API 级别 public class MyScanCallback extends ScanCallback

【问题讨论】:

【参考方案1】:

@TargetApi 21 只是为了防止使用的任何新 API 出现任何编译错误。 Byt 要真正避免执行代码,它必须像您在几个地方所做的那样围绕构建版本检查进行。

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)


所以在这种情况下,肯定会创建一个 MyScanCallback 变量,但它不会在具有 api

正如你提到的,它使用的是 API 21 中引入的 ScanCallback,那么在旧版本中使用它肯定会是一个问题。

为了摆脱这种情况,我建议创建一个抽象类,如下所示:

public abstract class BleConnector

public abstract void startScan(Context context);


然后创建两个类

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


终于有了一个工厂类

public class BleConnectorFactory

    public static BleConnector getBleConnector() 

        if (android.os.Build.VERSION.SDK_INT >= 21) 
            return new BleConnect21Api();
        else
            return new BleConnectOldApi();
        

    

这样您可以防止在使用旧 API 版本中不存在的类时出现不必要的错误。

希望对你有所帮助。

【讨论】:

哦,我没有说 MyScanCallback 继承了 ScanCallback,它来自 21 API 级别 public class EegScanCallback extends ScanCallback。所以不会惹麻烦吗?此类的字段声明 太棒了!感谢分享...更新了我的答案。 非常感谢您的回答!好主意 欢迎。感谢您的支持。

以上是关于Java中没有初始化和用法的字段声明的主要内容,如果未能解决你的问题,请参考以下文章

Java成员变量和局部变量

[Java] 类和接口的初始化步骤 - 继承方面

C#中static静态变量的用法

toString的用法

如何初始化声明为局部变量的记录?

instanceof