问题描述
我正在做我的 Java 课程练习.我有这个包含重载方法的代码:
I'm doing my Java class exercises. I have this code which contains an overloaded method:
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 中调用方法 af(n,q)
时,我预计会出现错误,但它调用方法 f(int n, float x)
而我的q
是一个 long
数字,它的大小大于 float
的大小(8 字节/4 字节) 所以我想知道这些原语如何类型有效吗?
When I call the method a.f(n,q)
in main I expect an error, but it calls the method f(int n, float x)
while my q
is a long
number and it's size is bigger then a float
's size (8 byte / 4 byte) So I wonder how these primitive types works?
推荐答案
方法调用 占据了规范的相当长的一段.总而言之,编译器按如下方式进行:
Method invocations occupy a pretty length chunk of the spec. To summarize, the compiler proceeds as follows:
- 确定可能会在其上调用方法的类.
- 识别那些可能被调用的类的方法.
- 如果确定的方法不止一种,请选择最具体的一种.
第 2 步是这里最有趣的一步:这包括多个步骤.总结一下:
Step 2 is the most interesting one here: this proceeds in a number of steps. To summarize:
- 如果类上存在具有完全相同参数类型(严格调用)的非可变参数方法,请选择该方法.
- 如果类上有一个非可变参数方法,其参数类型从实际参数自动转换(松散调用),请选择该方法.
- 如果类上有一个参数类型与自动转换匹配的可变参数方法,请选择该方法.
您提供的参数与重载的任何参数类型都不完全匹配,因此您需要检查是否可以转换该参数以允许严格调用.严格调用中的转换是一个>:
You're supplying parameters that don't exactly match any of the parameter types of the overloads, so you need check if you can convert that parameters to allow strict invocation. The conversions in strict invocations are:
- 身份转换(第 5.1.1 节)
- 扩大原始转换(第 5.1.2 节)
- 扩大参考转换(第 5.1.5 节)
int
可以通过身份转换转换为 int
.long
可以通过 扩大原始转换到float
.
An int
can be converted by identity conversion to int
. A long
can be converted by widening primitive conversion to a float
.
因此 f(int, float)
是适用的.
f(long, double)
和 f(double, double)
也适用,因为 int
可以扩展为 long
和 double
;并且long
可以加宽到double
.
f(long, double)
and f(double, double)
are also applicable, since int
can be widened to long
and double
; and long
can be widened to double
.
然而,这些不如 f(int, float)
具体,因为 int
可以扩展为 long
和 double
和 float
可以加宽为 double
.因此,根据 非正式直觉在 JLS Sec 15.12.2.5 中列出,这些方法不如 f(int, float)
特定.因此,f(int, float)
是被调用的那个.
However, these are less specific than f(int, float)
, since int
can be widened to long
and double
, and float
can be widened to double
. Hence, by the informal intuition laid out in JLS Sec 15.12.2.5, these methods are less specific than f(int, float)
. As such, f(int, float)
is the one that is invoked.
这篇关于方法重载和原始类型如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!