Java原语和重载

Java原语和重载,java,overloading,primitive-types,Java,Overloading,Primitive Types,我一直听说(并认为)Java是一种强类型语言。但直到最近我才注意到我几乎每天都在使用的东西:int和double重载 我可以编写以下内容,这是有效的Java代码: int i = 1; double j = 1.5; double k = i + j; 但是,如果我有一个方法,其中一个参数是double,我需要指定它: public static <K, V> V getOrDefault(K k, Map<K, V> fromMap, V defaultvalue)

我一直听说(并认为)Java是一种强类型语言。但直到最近我才注意到我几乎每天都在使用的东西:
int
double
重载

我可以编写以下内容,这是有效的Java代码:

int i = 1;
double j = 1.5;
double k = i + j;
但是,如果我有一个方法,其中一个参数是
double
,我需要指定它:

public static <K, V> V getOrDefault(K k, Map<K, V> fromMap, V defaultvalue) {
    V v = fromMap.get(k);
    return (v == null) ? defaultvalue : v;
}
为什么Java会将
int
重载到
double
(就像它另外做的那样),然后将其自动装箱到
double
?我认为答案在于Java如何实现运算符重载(即重载发生在
+
运算符中,而不是从
int
double
),但我不确定


希望SO能在这方面帮助我。

int->
double
转换是一种扩展转换。加宽转换不会丢失数据,所以会丢失数据。

这是因为原语不适用于泛型。它们需要装箱

用于调用

getOrDefault(aString, aStringDoubleMap, 0); // won't compile
为了工作,Java必须将
0
装箱为
整数,然后以某种方式将其转换为
双精度
。这是语言不允许的。这与为什么你不能做相似

Double value = 3; // Type mismatch: cannot convert from int to Double
联合联络小组

如果表达式的类型无法转换为 在松散调用上下文中允许转换的参数, 然后发生编译时错误

表达式的类型,
0
,一个整数文本,是
int
。松散调用上下文定义为

松散调用上下文允许更宽松的转换集, 因为如果没有,它们只用于特定的调用 可以使用严格的调用上下文找到适用的声明。 松散调用上下文允许使用以下内容之一:

  • 身份转换(§5.1.1)
  • 扩大原语转换(§5.1.2)
  • 拓宽参考转换(§5.1.5)
  • 装箱转换(§5.1.7)后可选加宽参考转换
  • 取消装箱转换(§5.1.8)后可选地进行加宽原语转换
int
Double
不受任何这些选项的支持

如果你只是

public static void main(String[] args) throws Exception {
    method(3);
}

public static void method(double d) {
}
它会起作用的。

您正在寻找合适的


基本上,当您添加int和double时,它将执行加宽转换。但它不知道在尝试将int自动装箱为Double时如何执行此操作。事实上,它是明确禁止的。

Java不支持运算符重载(字符串concat(+))运算符是一个例外

double k = i + j;
这里发生的是隐式转换。较小的数据类型被扩展为较大的数据类型。这是由JVM隐式完成的

对于
getOrDefault
,原语不能与泛型一起工作。 调用
getOrDefault时(aString,aStringDoubleMap,0d),0d将自动装箱到双对象。
但在第一种情况下,JVM无法将0自动装箱到双对象

Java不会隐式执行扩展原语转换(0到0d)和装箱转换(double到double)

检查这个

不允许从int隐式转换为double,然后从装箱转换为double

0只能自动装箱为整数。
0d可以自动装箱为双倍。

这不是OP的问题。问题是为什么在
Double d=1
,文本
1
不会转换为
double
,然后自动装箱为
double
。不,我没有否决你的答案。也许是问题中的错别字?引用:“为什么Java会将int重载为double(就像它另外做的那样),然后将其自动装箱为double?”我猜他的意思是“不”,但我错过了。这是调用上下文,而不是赋值上下文所涵盖的内容。这是真的,是第5.3节,不是第5.2节,但两节中允许的转换列表是相同的。我明白了。我认为Java会首先将0转换为0d(Renjith和Andrew提到的扩展转换),然后是autobox。当然,正如您所指出的,不允许从
Integer
转换为
Double
double k = i + j;