3

我正在开发以下代码

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));
}

两者都导致输出 float, float ,请告知背后的原因以及如何调用 double 请告知非常感谢。

4

4 回答 4

7

简短回答: Java 可以自动将ints 和longs 扩大到floats 和doubles,但 Java 会选择扩大到 a float,因为它比 a 更小(就内存占用而言)double。您可以double通过将参数显式转换为 a 来调用该方法的版本double

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 自动执行:

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

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

  1. 加宽不会丢失有关数值整体大小的信息。
  2. 从一个整数类型扩大到另一个整数类型根本不会丢失任何信息;数值被完全保留。
  3. int将 a或值扩大long到 afloat或将long值扩大到 adouble可能会导致精度损失

例如,Java 可以安全地将 anint扩展为 along而根本不改变数值,因为两者都是整数类型并且 along大于 an int(参见规则 2)。Java 也可以将 a 扩大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);
}

第一次调用foo(float)按预期打印“123.0”。值“ int123”被扩大到float值“123.0”。第二个调用打印“1.23456794E9”,当您考虑规则 3 时,这是有道理的。值“1234567940”与“1234567890”的量级相同,但精度较低。

另一条关键信息:当存在多个重载方法时,Java 通过选择具有最小参数类型(就内存占用而言)的方法来确定调用哪个方法,以便给定参数能够扩展为参数类型。换句话说,你传递给方法的数量必须能够扩大到方法的参数类型,如果多个重载方法满足该要求,Java 将选择参数类型最小的方法。

在您的情况下,您将 anint和 a传递long给两个重载方法之一。Java 将查看方法m(float)m(double)确定调用哪个方法。anint可以扩大到 afloat a double,但是 a float(4 个字节)小于 a double(8 个字节),所以 Java 会选择调用m(float). 当您使用long参数调用方法时也是如此:float选择它是因为它是 along可以扩展到的最小数据类型。

于 2012-04-29T07:11:48.317 回答
4

如果要调用double版本,请将其明确设为双精度: m((double)a1)

看看JLS §8.4.9 - 方法重载

于 2012-04-29T05:43:35.887 回答
3

尝试

    System.out.print(m(1f)+","+ m(2d));

你为什么要创建一个 int 和 long 来测试它?好吧,实际发生的是默认情况下这两个参数都转换为浮点数。

于 2012-04-29T05:43:27.930 回答
1

我怎么能叫双重?

使用double变量

double d = 3.3;
m(d);
于 2012-04-29T05:43:58.267 回答