关于长期和浮动

dgh*_*htr 3 java

我正在开发以下代码

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)

两者都导致输出浮动,浮动,背后的原因请指教,如何调用双请告知非常感谢.

Wil*_*del 7

简短回答: 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自动执行:

  • byteshort,int,long,float,或者double
  • shortint,long,float,或者double
  • charint,long,float,或者double
  • intlong,floatdouble
  • longfloatdouble
  • floatdouble

适用于这种情况的其他规则是:

  1. 扩展不会丢失有关数值总体大小的信息.
  2. 从整数类型扩展到另一种整数类型根本不会丢失任何信息; 数值完全保留.
  3. 将a intlong值加宽到a float或a的longdouble可能会导致精度损失.

例如,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可以扩展为的最小数据类型.