Java言語仕様はそれについて非常に明確です(強調は私のものです):
15.12.2 コンパイル時のステップ 2: メソッド シグネチャの決定
[...]
最初のフェーズ (§15.12.2.2) は、ボックス化またはボックス化解除の変換を許可せずにオーバーロードの解決を実行します [...] このフェーズで適用可能なメソッドが見つからない場合、処理は 2 番目のフェーズに進みます。[...]
2 番目のフェーズ (§15.12.2.3) は、ボックス化とボックス化解除を許可しながら、過負荷の解決を実行します [...]
第 3 フェーズ (§15.12.2.4) では、オーバーロードを可変アリティ メソッド、ボックス化、およびボックス化解除と組み合わせることができます。
つまり、最初のステップのみprint(int)であり、print(float)適切な場合があります。後者は一致し、それ以上の調査は行われません。
このようなルールの理由は、JLS でも説明されています。
これにより、Java SE 5.0 より前の Java プログラミング言語で有効だった呼び出しが、可変アリティ メソッド、暗黙的なボックス化および/またはボックス化解除の導入の結果として、あいまいであると見なされないことが保証されます。
Testクラスが Java 1.4 に対してコンパイルされているとします(オートボクシングの前)。その場合、それは明らかです:引数と完全に互換性がないため、選択する必要があります( toが安全であると見なされ、暗黙的である可能性があるprint(float)理由に同意すると仮定します...)。longfloatprint(Long)long
後で、Java 5+ に対して同じコードをコンパイルします。コンパイラは次のことができます。
このコンテキストではprint(Long)、より「明白な」ものとして選択してください。したがって、Java 5 にアップグレードすると、プログラムの動作が異なります...
呼び出しがあいまいであるため、コンパイル エラーが発生します。したがって、以前は正しいコードが Java 5 でコンパイルされなくなりました (AFAIR は決して当てはまりません)。
...または古いセマンティクスを保持し、Java 1.4 と同じメソッドを呼び出す
print(float)Java 1.4 では が選択されていたため、 が使用されている理由が理解できたはずです。そして、Java は下位互換性がなければなりません。