2012-01-29 4 views
3

私は私のアプリでは、次のコードを持っている:Javaコンパイラは静的最終文字列を最適化しません。どうして?

public static final boolean DEBUG = true; 
    public static final boolean REL = !DEBUG; 

    private static final String DEBUG_OR_RELEASE = (REL) ? "RELEASE_VER" : "DEBUG_VER"; 

私は(ProGuardの経由でエクスポートしたとき)は、Javaコンパイラは、結果の.apkファイルから完全に"DEBUG_VER"文字列を排除しますが、私はの.apkファイルを調べたときにすることを考えました、私はそこに "DEBUG_VER"文字列を参照してください。

なぜですか?私は何が欠けていますか?私は何を間違えたのですか?

+0

"RELEASE_VER"が表示されないと思われる場合は、おそらくデバッグ用にコンパイルしていると思われますが、一般的にこのような最適化はデバッグモードでは無効になっています。 –

+0

さらに、文が最適化されても、文字列リテラルが定数プールに残っている可能性があります。基本的に無害です。 –

+0

'DEBUG_OR_RELEASE =(REL)? "DEBUG_VER": "DEBUG_VER" '?本当に?あなたの本当のコードを投稿してください。 – erickson

答えて

1

投稿した内容によると、DEBUGが真であるので、はfalseであるため、(REL) ? "RELEASE_VER" : "DEBUG_VER"は "DEBUG_VER"を返すはずです。

public static final boolean DEBUG = false; 

ことを試してみて、何が起こるかを参照してください。

これは、あなたがあなたの代わりに「RELEASE_VER」を参照してください期待している場合、あなたが設定する必要がありますので、観察しているまさにです。

+0

ありがとうございました。これは、リリース版をエクスポートするたびに 'boolean DEBUG'を* false *に変更することを覚えなければならないことを意味します。ああ。 – ateiob

1

変数がtrueに設定されていてもまだ実行されています。 ?:ステートメントは実行可能コードと操作コードの一部であり、Javaにはプリコンパイラがないため、はコンパイルするたびにに実行されます。

論理的に操作が同じであっても、Javaは操作を自動的に推論して単純化しません。

+0

ありがとう、しかし[これ](http://stackoverflow.com/a/1813873)によると可能です。その答えは間違っていますか? – ateiob

+0

彼はあなたが同じ結果を生み出すことを意味し、編集からそれを削除しないことを意味したと思います。しかし、私が間違っていたら、その答えは間違っています。 – Zyerah

+0

プリプロセッサがなくても、Javaコンパイラは到達できないコードを明らかに削除します(場合によってはそうする必要があります)。最終的なブール値に基づく条件は偽である。これはJava言語仕様、14.21節で議論されており、実際には容易に検証できます。 –

3

Javaバイトコードへのコンパイルは最適化を行っていません(ほんのわずかな例外を除いて)。

多くの書籍には、最適化が行われたときに「コンパイル」段階が間違っていることが簡略化されています。最適化が実際に行われるときは、バイトコードファイルがJVMによって処理されます。クリアランスのために、コンパイル時にバイトコードをコンパイルするときに、JVMツールによって行われるネイティブコードを処理する最適化が行われることがあります。

場合によっては最適化が全く行われないことがあります(JVMは解釈モードで動作します)。場合によっては、JIT(Just In Timeコンパイラ)によって最適化されているものがあります。また、適応オプティマイザは、最適化(最適化だけでなく、実行する追加操作の場合にコード実行のプロファイリングも行います)を処理します。

最後に、ファイルに問題はありません。それはちょうどJavaの世界の仕組みです。

"なぜですか?" - あなたが求めるかもしれません。バイトコードでこの「役に立たない」情報を保持する理由は、いくつのコードを削除すればよいのか分からないため、異なるJVMによって提供される最適化が効率的に機能する可能性があるからです。最良の方法は、情報を消去せず、オプティマイザに自分の仕事をさせることです。

+0

'最適化が実際に行われるとき、バイトコードファイルがJVMにロードされている間です - これはやや誤解を招き、後であなたが言うことと矛盾します。 JITは、読み込まれたメソッドを最適化するのではなく、解釈モードで一定回数実行した後にのみ最適化します。 (恐ろしい簡素化) – Voo

+0

小さな編集をより正確にするようにしましたが、私はここで単純化することは誤解を招く可能性があることを認識しています。 – msi

+0

@msiありがとうございました。これは理にかなっていますが、私の場合は、リリースAPKから "DEBUG_VER"文字列を削除したいと思います。どうすればそれを達成できますか? – ateiob

関連する問題