我正在开发以下代码
static String m(float i) {
return "float";
}
static String m(double i) {
return "double";
}
public static void main(String[] args) {
int a1 = 1;
long b1 = 2;
System.out.print(m(a1) + "," + m(b1));
}
Run Code Online (Sandbox Code Playgroud)
两者都导致输出浮动,浮动,背后的原因请指教,如何调用双请告知非常感谢.
简短回答: Java可以自动将ints和longs扩展为floats和doubles,但Java会选择扩展为a,float因为它比a更小(就内存占用而言)double.您可以double通过将参数显式转换为以下内容来调用方法的版本double:
System.out.print(m((double)a1) + "," + m((double)b1));
Run Code Online (Sandbox Code Playgroud)
答案很简单: Java中的每个原始数据类型都有一个大小(以字节为单位),它确定给定基元可以容纳多少信息(或者更确切地说,是什么范围的值).下表显示了一些Java原始数据类型的大小:
byte 1 byte
short 2 bytes
char 2 bytes
int 4 bytes
float 4 bytes
long 8 bytes
double 8 bytes
Run Code Online (Sandbox Code Playgroud)
在某些情况下,Java将根据Java语言规范中明确定义的规则自动"扩展"您的值.以下扩展的原始转换由Java自动执行:
byte对short,int,long,float,或者doubleshort对int,long,float,或者doublechar对int,long,float,或者doubleint到long,float或doublelong到float或doublefloat 至 double适用于这种情况的其他规则是:
int或long值加宽到a float或a的long值double可能会导致精度损失.例如,Java可以安全地将a int扩展为a long而不更改数值,因为两者都是整数类型,并且a long大于a int(参见规则2).Java也可以int扩展为a float,但可能会丢失精度.下面的示例代码演示了这种精度损失.
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);
}
Run Code Online (Sandbox Code Playgroud)
第一次foo(float)打印按预期打印"123.0".的int值"123"时被加宽到float值"123.0".第二个调用打印"1.23456794E9",这在考虑规则3时是有意义的.值"1234567940" 与 "1234567890"的大小相同但不太精确.
另一条关键信息是:当存在多个重载方法时,Java通过选择具有最小参数类型的方法(就内存占用而言)来确定调用哪个方法,以便给定参数能够扩展为参数类型.换句话说,传递给该方法的数必须是能够被加宽到参数类型的方法的,和如果多个重载方法满足该要求,Java将选择其参数类型是最小尺寸的方法.
在您的情况下,您将传递一个int和一个long到两个重载方法之一.Java将查看方法m(float)并m(double)确定要调用的方法.一个int可以扩展为a float 和 a double,但是float(4个字节)小于double(8个字节),因此Java将选择调用m(float).使用long参数调用方法时也是如此:float选择它是因为它是long可以扩展为的最小数据类型.