Java原语和重载

时间:2015-07-21 15:36:25

标签: java overloading primitive-types

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

我可以编写以下内容,它是有效的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;
}

当我在Map<String, Double>上调用上述方法时,defaultvalue参数不能是int

getOrDefault(aString, aStringDoubleMap, 0); // won't compile
getOrDefault(aString, aStringDoubleMap, 0d); // compiles and runs just fine

为什么Java会将int重载为double(就像它一样),然后将其自动装箱到Double?我认为答案在于Java如何进行运算符重载(即重载发生在+运算符中,而不是从int发生到double),但我不确定。

希望SO可以帮助我解决这个问题。

4 个答案:

答案 0 :(得分:4)

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

对于调用

getOrDefault(aString, aStringDoubleMap, 0); // won't compile

要工作,Java必须将0打包到Integer,然后以某种方式将其转换为Double。语言不允许这样做。它类似于你不能做的原因

Double value = 3; // Type mismatch: cannot convert from int to Double

来自JLS,on invocation contexts

  

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

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

  

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

     
      
  • 身份转换(第5.1.1节)
  •   
  • 扩大原始转换(第5.1.2节)
  •   
  • 扩大参考转换(第5.1.5节)
  •   
  • 拳击转换(§5.1.7),可选地后跟加宽参考转换
  •   
  • 一个拆箱转换(第5.1.8节),可选地后跟一个加宽的基元转换
  •   

intDouble不受任何支持。

如果你只是

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

public static void method(double d) {
}

它会起作用。

答案 1 :(得分:3)

您正在寻找exciting section 5.2 of the Java Language specification

基本上,当你添加一个int和double时,它会执行加宽转换。但是当尝试将一个int Autobox转换为Double时,它不知道这样做。事实上它是明确禁止的。

答案 2 :(得分:1)

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

double k = i + j;

这里发生的是隐式转换。较小尺寸的数据类型被扩展为更大尺寸的数据类型。这是由JVM隐式完成的。

对于getOrDefault,原语不适用于泛型。这里有autoboxing。 当您调用getOrDefault(aString, aStringDoubleMap, 0d);时,0d将自动装箱为Double对象。 但是在第一种情况下,JVM无法将0自动装箱到Double对象。

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

选中此link

不允许从int到double的隐式转换,然后装箱到Double。

0只能自动装箱到整数。 0d可以自动装箱为Double。

答案 3 :(得分:-1)

int - &gt; double转化是一种不断扩大的转化。扩展转化不会丢失数据,因此它们为performed automatically