方法重载和原始类型如何工作?

时间:2019-01-31 11:14:45

标签: java overloading primitive-types

我正在做Java课堂练习。我的这段代码包含一个重载的方法:

class A {

    // Overloaded method
    public void f(int n, float x) {
        System.out.println("f(int n, float x) n = " + n + " x = " + x);
    }

    private void f(long q, double y) {
        System.out.println("f(long q, double y) q = " + q + " y = " + y);
    }

    public void f(double y1, double y2) {
        System.out.println("f(double y1, double y2) y1 = " + y1 + " y2 = " + y2);
    }

    public void g() {
        int n = 1;
        long q = 12;
        float x = 1.5f;
        double y = 2.5;
        System.out.println("--- dans g ");
        f(n, q);
        f(q, n);
        f(n, x);
        f(n, y);
    }
}

主要:

public static void main(String[] args){ 
    A a = new A() ;
    a.g() ;
    System.out.println ("--- dans main") ;
    int n=1 ; 
    long q=12 ; 
    float x=1.5f ; 
    double y = 2.5 ;

    a.f(n, q) ; // my problem is here
    a.f(q, n) ; 
    a.f(n, x) ; 
    a.f(n, y) ;  
}

当我在main中调用方法a.f(n,q)时,我会期望一个错误,但是当我的f(int n, float x)是一个q且大小较大时,它会调用方法long那么float的大小(8字节/ 4字节)那么我想知道这些原始类型如何工作?

3 个答案:

答案 0 :(得分:7)

Method invocations占据了规范的相当大的一部分。总而言之,编译器进行如下操作:

  1. 确定可以在其上调用该方法的类。
  2. 识别那些可能被调用的类上的方法。
  3. 如果识别出一种以上的方法,则选择最具体的一种。

步骤2是这里最有趣的步骤:此过程分为多个步骤。总结一下:

  1. 如果类上有一个具有完全相同的参数类型(严格调用)的non-varargs方法,请选择该方法。
  2. 如果类上有一个具有参数类型的non-varargs方法,可以从实际参数自动转换(松动调用),请选择该方法。
  3. 如果类上有一个varargs方法,其参数类型与自动转换匹配,请选择该方法。

您提供的参数与重载的任何参数类型都不完全匹配,因此您需要检查是否可以转换该参数以允许严格调用。严格调用are中的转换:

  
      
  • 身份转换(第5.1.1节)
  •   
  • 不断扩大的原始转换(第5.1.2节)
  •   
  • 扩展的参考转换(第5.1.5节)
  •   

int可以通过身份转换转换为intwidening primitive conversion可以将long转换为float

因此f(int, float)适用。

f(long, double)f(double, double)也适用,因为int可以扩展为longdouble;和long可以扩展为double

但是,由于f(int, float)可以扩展为intlong,而double可以扩展为{{ 1}}。因此,通过informal intuition laid out in JLS Sec 15.12.2.5,这些方法不如float特有。因此,double是被调用的那个。

答案 1 :(得分:1)

longs可以转换为float而不会引起错误。但是,你可能会失去精度。

有关详细信息,请参见the specs

答案 2 :(得分:-2)

以下19种特定于原始类型的转换称为扩大原始转换:

字节为短,整数,长,浮点或双精度

short到int,long,float或double

char转换为int,long,float或double

int表示long,float或double

漂浮或翻倍的长度

浮动翻倍

简化原始转换不会丢失有关数值的整体大小的信息。

...

将int或long值转换为float或将long值转换为double可能会导致精度损失-也就是说,结果可能会丢失该值的某些最低有效位。在这种情况下,最终的浮点值将是long值的正确舍入版本。