为什么同一段(简单的)Java 代码在不同的 Android 设备上表现非常不同?
那段简单的代码只是使用 String.replace(CharSequence target, CharSequence replacement)
和 target == ""
:
package com.example.stringreplacetest;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String str = "just_a_string";
System.out.println(str.replace("", "-"));
((TextView) findViewById(R.id.textView)).setText(str.replace("", "-"));
}
}
它在我的 LG Optimus 3D P920 (Android 2.3.3) 和我姐姐的三星 Galaxy S2 (Android 4.1.2) 上生成-j-u-s-t-_-a-_-s-t-r-i-n-g-
,我猜你的大多数设备上也是如此。
但它在我的 LG Optimus Chic (Android 2.2) 上停止了(怀疑是无限循环)。
旧的 LG Optimus Chic 和 Android 2.2 可能有问题。 (String.replace()
确实有 a bug 。)但是 the piece of code在 String.replace()
中相对简单 - “简单”意味着没有动态绑定(bind)、没有线程等...
不是 that piece of code应该在编译期间完成? Java 编译器如何工作(我知道 Java 是一种跨平台语言,它的工作方式可能不同)?
附言为了确保它是同一段编译代码,我实际上通过 USB 将编译的 .apk
传输到我的 Android 手机,而不是使用 Eclipse 直接在设备中运行它们。
我找到了 Android 2.2 Froyo 的源代码:
当 target.length == 0
时,它确实导致无限循环(因为在 do-while 循环
中,string. indexOf("", tail)
将永远 返回-1
)。
疑惑稍微解开了。但是……
我仍然不知道为什么在不同的设备上运行时会加载不同版本的 String
类。这就是跨平台的意思吗?
最佳答案
让我结束这个问题。
我找不到具体的文献引用。但是经过我的反复试验,以及对“Java 与 C 编译器之间的差异”的一些研究。是的,这就是 Java 行为 - 一次编译,到处运行(&到处调试)。
这就是我们需要 Java VM 的原因。这就是 Java 比 C/C++ 编译速度更快的原因。这就是 Java 运行速度比 C/C++ 慢的原因。
(我猜)当 Java 编译时,它只记录类签名。在 VM 上运行时,它将这些签名与相应类的实际实现进行匹配,及时将它们编译成机器代码。这就是为什么 Java 可以编译一次,在不同的机器上运行,因为不同的 VM 有自己的类实现。这也导致了一个问题,如果某个版本中存在错误,程序员无能为力。这是因为实际的错误实现是在最终用户运行程序的客户端。我们需要等待用户更新他们自己的 VM。
附言事实上我们可以重新发明轮子,重新编写我们自己的类。因此,这些类将附加到已部署的程序中。
关于android - 为什么同一段(简单的)Java 代码在不同的 Android 设备上表现非常不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16537310/