JDK のバージョン、ビルド ツールのバージョン、およびビルド/コンパイル オプションが同一であると仮定すると、相違点の原因として考えられるものがいくつか考えられます。
タイムスタンプ - クラスファイルには、コンパイルのタイムスタンプが含まれる場合があります。コンパイルをまったく同時に実行しない限り、同じファイルの異なるコンパイルは異なるタイムスタンプになります。
ソース ファイル名のパス - 各クラス ファイルには、ソース ファイルのパス名が含まれます。異なるパス名で 2 つのツリーをコンパイルすると、クラス ファイルには異なるソース パス名が含まれます。
インポートされたコンパイル時定数の値 - クラスA
が別のクラスで定義されたコンパイル時定数を使用する場合 (「コンパイル時定数」の定義については JLS を参照)、定数の値はs クラス ファイルB
に組み込まれます。そのため、(定数の値が異なる)の異なるバージョンに対してA
コンパイルすると、 のコードは異なる可能性があります。A
B
A
identityHashcode
コンパイラによってキーで使用されることによるHashMap
違いは、一部のステップでマップの反復順序の違いにつながる可能性があります。これは.class
ファイル生成に大きな影響を与えませんが、それでも.class
ファイルの違いとして現れます。たとえば、一定のプール エントリが異なる順序になる可能性があります。
外部クラス/メソッドの署名の違い; たとえば、POM ファイルのいずれかで依存関係のバージョンを変更した場合。
有効なビルド クラスパスが異なると、インポートされたクラスが検出される順序が異なる場合があります。これにより、クラス ファイルの定数プール内のエントリの順序に重要でない違いが生じる可能性があります。これは、次のようなことが原因で発生する可能性があります。
- 外部 JAR ファイルのディレクトリに異なる順序で表示されるファイル
- ビルドツールがソースファイルを反復するときにソースファイルの順序が異なるため、ファイルが異なる順序でコンパイルされる2、または
- ビルドの並列処理 (有効にしている場合)。
ファイルの順序付けに関する問題には回避策があります。JDK-7003006-XDsortfiles
で説明されているように、文書化されていないオプションを使用してください。(それについて知ってくれた@Holgerへの称賛。)
通常、ファイル システム ディレクトリ内のファイルの実際の順序は表示されないことに注意してください。ls
や などのコマンドライン ツールdir
、およびファイル ブラウザは通常、エントリを表示する前に (名前順またはタイムスタンプ順に) 並べ替えます。
1 - これはコンパイラに依存します。javap
また、タイムスタンプが表示されることは保証されていません...それらが存在する場合。
2 - OS は、(syscall レベルで) ディレクトリを一覧表示すると、決定論的な順序でファイル システム オブジェクトが返されるという保証はありません。ファイルを削除して再追加した場合は、同じ順序で返されます。
違いの原因を特定するための最初のステップは、それらが何であるかを正確に理解することであることを付け加えておきます. おそらく難しい方法でそれを行う必要があります-クラスファイルのペアを手動でデコードして、実際に違いがある場所を特定し、違いが実際に何を意味するかを特定します。