1

(単純な) Java コードの同じ部分が、異なる Android デバイスで非常に異なる動作をするのはなぜですか?

その単純なコードはString.replace(CharSequence target, CharSequence replacement)with を使用するだけです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("", "-"));
    }
}

それは-j-u-s-t-_-a-_-s-t-r-i-n-g-私の LG Optimus 3D P920 (Android 2.3.3) と妹の Samsung Galaxy S2 (Android 4.1.2)で生成され、ほとんどのデバイスでも生成されると思います。

しかし、私の LG Optimus Chic (Android 2.2) では停止します (無限ループの疑いがあります)。

古い LG Optimus Chic と Android 2.2 にはバグがある可能性があります。(String.replace()実際にはバグがあります。)しかし、コードの一部String.replace()比較的単純です-「単純」とは、動的バインディング、スレッドなどがないことを意味します...

そのコードはコンパイル時にファイナライズする必要がありますか? Javaコンパイラはどのように機能しますか(Javaはクロスプラットフォーム言語であるため、動作が異なる場合があります)?

.apkPSは、コンパイルされたコードと同じであることを確認するために、Eclipseを使用してデバイスで直接実行するのではなく、実際にUSBでコンパイルしたものをAndroid携帯に転送しました。


Android 2.2 Froyo のソース コードを見つけました。

https://android.googlesource.com/platform/dalvik/+/froyo-release/libcore/luni/src/main/java/java/lang/String.java

の場合、無限ループ発生しますtarget.length == 0( ではdo-while loopstring.indexOf("", tail)が戻らない-1ため)。

疑問が少し解消されました。しかし...

String異なるデバイスで実行すると、異なるバージョンのクラスがロードされる理由はまだわかりません。これがクロスプラットフォームの意味ですか?

4

1 に答える 1

1

この質問を閉じさせてください。

具体的な参考資料は見つかりませんでした。しかし、試行錯誤を繰り返し、「Java コンパイラと C コンパイラの違い」についていくつか調査した結果です。はい、これが Java の動作です。一度コンパイルすると、どこでも実行できます(& どこでもデバッグできます)。

これが、Java VM が必要な理由です。これが、Java が C/C++ よりも高速にコンパイルされる理由です。これが、Java の実行速度が C/C++ よりも遅い理由です。

(推測) Java のコンパイル中は、クラスの署名のみが記録されます。VM で実行すると、これらの署名が対応するクラスの実際の実装と照合され、ジャストインタイムでマシン コードにコンパイルされます。異なる VM にはクラスの独自の実装があるため、 Java を一度コンパイルすると、異なるマシンで実行できるのはそのためです。これは、特定のバージョンにバグがあると、プログラマーがそれに対して何もできないという問題にもつながります。これは、実際のバグのある実装が、エンドユーザーがプログラムを実行しているクライアント側にあるためです。ユーザーが自分の VM を更新するのを待つ必要があります。

PS 実際、車輪を再発明し、独自のクラスを書き直すことができます。したがって、これらのクラスはデプロイされたプログラムにアタッチされます。

于 2013-06-06T01:58:35.027 に答える