【问题标题】:Missing return statement after catch{throw..} implementationcatch{throw..} 实现后缺少 return 语句
【发布时间】:2019-06-25 18:00:58
【问题描述】:

即使它在try 块中有返回,它也会说缺少返回语句。我不明白。 我正在尝试制作一个 android 应用程序,并使用 android keystore 存储该应用程序的登录凭据。 另外,如果有人能给我一个简单的keystore 实现的例子,那就太好了。我找到了 2 个示例,它们不是很容易理解(缺少代码),也很难根据我的情况实施。

private SecretKey createKey() {
    try {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            keyGenerator.init(new KeyGenParameterSpec.Builder("Key", KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                    .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
                    .setUserAuthenticationRequired(true)            //burayı kaldırırsan screen locka gerek kalmaz
                    .setUserAuthenticationValidityDurationSeconds(5)
                    .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
                    .build());
            return keyGenerator.generateKey();
        }
    } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) {
        throw new RuntimeException("Failed to create a symmetric key", e);
    }

}

【问题讨论】:

  • 另外添加 - 在您的方法定义中抛出 RuntimeException。
  • @Jay 如果你抛出异常,你不需要返回任何东西。当他投掷RuntimeException
  • @Jay,是的,我错过了那个。感谢您的澄清。干杯。

标签: android passwords keystore


【解决方案1】:

问题是,如果您的 Build.VERSION.SDK_INT >= Build.VERSION_CODES.M 条件不满足,您将无法获得退货。

private SecretKey createKey() {
    try {
        KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            // ...
            return keyGenerator.generateKey();
        }
        // add a return here if we're not on >= Android M.
    } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) {
        throw new RuntimeException("Failed to create a symmetric key", e);
    }
    // you could also have a return here.
}

【讨论】:

  • 谢谢你,我太笨了。有什么建议在条件下尝试返回什么?由于我必须返回SecretKey,但是如果if语句不满足该条件,它就没有用了。
  • 是的,我们需要在 if 和 else 中都有 return !
  • @redduckto 就我个人而言,我会将 Android 版本的检查移到方法之外。您不想为旧设备运行createKey()。如果这是在对话框中,您不应该向用户显示对话框。这意味着任何访问createKey() 的人至少在使用Android M。
  • 谢谢,我会试试的。
【解决方案2】:

如果您的 if 语句不符合要求,您需要运行一个 return 语句。现在,只有当 SDK 大于 Build.VERSION_CODES.M 时,您才会返回一些东西。

您可以在整个 try 和 catch 之后放置一个 return 语句,因为如果您在 try 中返回,它将离开该方法。这意味着只有在构建 SDK 不满足要求时才会运行其他返回。

private SecretKey createKey() {
try {
    KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, "AndroidKeyStore");
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        keyGenerator.init(new KeyGenParameterSpec.Builder("Key", KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
                .setBlockModes(KeyProperties.BLOCK_MODE_CBC)
                .setUserAuthenticationRequired(true)            //burayı kaldırırsan screen locka gerek kalmaz
                .setUserAuthenticationValidityDurationSeconds(5)
                .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_PKCS7)
                .build());
        return keyGenerator.generateKey();
    }
} catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException e) {
    throw new RuntimeException("Failed to create a symmetric key", e);
}

// Return here...

}

【讨论】:

  • 例如,在 catch 之后我应该返回什么?不破坏代码中的逻辑?
  • @redduckto 我对 KeyGenerator 的研究不多。但是如果SDK版本不够高我猜你不想使用它?如果不是,我会尝试创建一个 null keyGenerator 来返回,以及一个错误消息?如果不是,我只会为 SDK 不够高的人编写你想要的代码。不知道有没有帮助。
【解决方案3】:

在最后一个大括号之前添加return语句

【讨论】: