【问题标题】:Android: variable has incorrect value in while loopAndroid:变量在while循环中的值不正确
【发布时间】:2016-02-26 02:15:48
【问题描述】:

在 Android Studio 中开发 Android 应用时,while 循环中使用的变量的值不正确。我将它在一个测试用例中简化为一个非常简单的用例:

  1. 在 Android Studio 中新建项目,空白 Activity
  2. 将以下代码添加到主活动中

方法开始:

@Override
public void onStart() {
    super.onStart();

    int count = 2;
    int index = 1;

    int value = 23;

    Log.i("test", "value before = " + value);
    while (index < count) {
        Log.i("test", "value in while loop = " + value);
        index++;
        value = 0;
    }
}

执行测试应用时的输出是:

value before = 23
value in while loop = 0

而结果应该是

value in while loop = 23

调试时,结果如预期('while loop = 23'),但在常规调试构建中,结果是错误的。主活动类的反汇编代码看起来没问题,变量'value'的值在while循环体的末尾设置为0。当 while 循环体中的某些代码或函数使用变量 'value' 时,它的值将是 0 而不是 23。在测试用例中,我使用 Log 语句来简化。

换行不会出错

value = 0;

if (value == 23) {
    value = 0;
}

或者当我删除线时

value = 0; 

所以它看起来像一些优化错误。但是做了哪些优化会导致这种情况呢?它使代码不可靠。

【问题讨论】:

  • 这真的取决于您的特定 Java 版本和 - 最重要的是 - 特定的 JVM。但是,是的,Java 进行优化,JVM 进行运行时优化,循环展开可以是优化之一。例如,看这里:Java JIT loop unrolling policy?.
  • @paulsm4 将代码输出从 23 更改为 0 是一种非法优化。需要发生的事情已明确定义。您可以在纸上追踪代码,您会发现 23 是您可以在此处打印的唯一值。只有在没有明显影响的情况下才允许重新排序指令。
  • Idk,但我以前见过这个,只在三星 Galaxy S5s 左右。没有其他设备受到影响。我猜三星搞砸了他们的优化。我没有时间进一步调查,因为我没有那种类型的手机可以测试(只有几个 Play 商店错误报告)
  • @joshgoldeneagle 我检查了 for 循环,它有同样的问题。有变通办法,这不是问题。但问题是这个问题正在损害正常的执行流程,这非常危险,因为你没有预料到。
  • 感谢所有 cmets。以@zapl 为例,可以确认存在真正的优化错误,至少在某些三星手机中是这样。在执行优化时,绝不应该以更改代码语义的方式更改执行流程。 如果有人知道如何与三星联系,请告诉我。

标签: java android optimization runtime-error samsung-mobile


【解决方案1】:

如果你真的确定写的代码能正常工作那么从现在开始,你必须开始检查(有序):

  • 配置 --> 您的项目配置是否完全可以使用 Java 版本、jdks 或 Java 版本与使用的 Android 库兼容?您的 Java 和 Andorid 库是否配置正确?
  • environment --> 您的调试模拟器是第三方库还是您的调试设备是调试代码的有效设备?您的编码操作系统是否与您的 ide、Java 版本或 Android 库兼容?
  • JVM --> 您是否尝试卸载并使用正确的 Java jdk 源代码以及您正在使用的版本重新安装?

也许您必须提供有关您的环境的一些详细信息,例如 Java 版本、Android 最低版本、操作系统或您使用的 IDE。

我希望这些项目符号能让你产生一些正确的联想来解决你的问题。

【讨论】:

    【解决方案2】:

    我无法重现该示例。我总是得到(运行和调试配置):

    value before = 23
    value in while loop = 23
    

    我刚刚在我的 Android Studio 中创建了一个新项目,并使用 SDK 版本 28 对其进行了编译。然后我只是在模拟器中运行了该项目(使用 API 26),一切都按预期工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-01-17
      • 1970-01-01
      • 1970-01-01
      • 2011-07-12
      • 1970-01-01
      • 2019-03-01
      • 2017-10-05
      相关资源
      最近更新 更多