簡単な答え:int Java はs とs をs とlongs の両方に自動的に拡張できますが、Java は aよりも (メモリ フットプリントの点で) 小さいため、 a に拡張することを選択します。引数を に明示的にキャストすることで、メソッドのバージョンを呼び出すことができます。floatdoublefloatdoubledoubledouble
System.out.print(m((double)a1) + "," + m((double)b1));
長い答え: Java の各プリミティブ データ型にはサイズ (バイト単位で測定) があり、これにより、特定のプリミティブが保持できる情報量 (または値の範囲) が決まります。次の表は、Java のプリミティブ データ型の一部のサイズを示しています。
byte     1 byte
short    2 bytes
char     2 bytes
int      4 bytes
float    4 bytes
long     8 bytes
double   8 bytes
Java は、Java 言語仕様で明確に定義された規則に従って、特定の状況で自動的に値を「拡張」します。次の拡張プリミティブ変換は、Java によって自動的に実行されます。
byte~short、int、long、float、またはdouble 
short、int、long、floatまたはdouble 
char、int、long、floatまたはdouble 
int、long、floatまたはdouble 
longfloatまたは_double 
floatにdouble 
この状況に適用されるその他の規則は次のとおりです。
- 拡大によって、数値の全体的な大きさに関する情報が失われることはありません。
 
- 整数型から別の整数型に拡張しても、情報はまったく失われません。数値は正確に保持されます。
 
intまたはlong値を にfloat、または値を に拡張すると、精度が失わlongれるdouble可能性があります。 
たとえば、Java は数値をまったく変更せずにanintを aに安全に拡張できます。どちらも整数型であり、aは an より大きいためです(ルール 2 を参照)。Java は anを aに拡張することもできますが、精度が失われる可能性があります。以下のサンプル コードは、この精度の低下を示しています。longlongintintfloat
public static void foo(float f) {
    System.out.println(f);
}
public static void main(String[] args) {
    int a = 123;
    int b = 1234567890;
    foo(a);
    foo(b);
}
への最初の呼び出しはfoo(float)、期待どおり「123.0」を出力します。int値「123」は値「123.0」に拡張されますfloat。2 番目の呼び出しでは "1.23456794E9" が出力されますが、これはルール 3 を考慮に入れると意味があります。値 "1234567940" は"1234567890"と同じ大きさですが、精度は低くなります。
ここで重要なもう 1 つの情報: 複数のオーバーロードされたメソッドが存在する場合、Java は、指定された引数を拡張できるように (メモリ フットプリントの観点から)最小のパラメーター タイプを持つメソッドを選択することによって、呼び出すメソッドを決定します。パラメータ タイプ。つまり、メソッドに渡す数値は、メソッドのパラメーターの型に拡張できる必要があり、複数のオーバーロードされたメソッドがその要件を満たす場合、Java はパラメーターの型が最小サイズのメソッドを選択します。
あなたの場合、 anintと alongを 2 つのオーバーロードされたメソッドのいずれかに渡しています。Java はメソッドm(float)をm(double)調べて、どのメソッドを呼び出すかを決定します。anは aおよびaintに拡張できますが、a (4 バイト) は a (8 バイト) よりも小さいため、Java は を呼び出すことを選択します。引数を指定してメソッドを呼び出す場合も同様です。 が選択されるのは、 aを拡張できる最小のデータ型であるためです。float doublefloatdoublem(float)longfloatlong