方法重载中的Java强制转换

方法重载中的Java强制转换,java,casting,overloading,Java,Casting,Overloading,我有重载的方法,例如: public int sum1(int a, int b) { int c= a+b; System.out.println("The method1"); return c; } public float sum1(int a, float b) { float c= a+b; System.out.println("The method2"); return c; } public double sum1(fl

我有重载的方法,例如:

 public int sum1(int a, int b)
{
    int c= a+b; 
    System.out.println("The method1");
    return c; 
}
public float sum1(int a, float b)
{
    float c=  a+b;
    System.out.println("The method2");
    return c; 
}
public double sum1(float a, float b)
{
    double c=  (double) a+b;
    System.out.println("The method3");
    return c; 
}
从主要方法来看,假设我们有

 double x=10.10f;
 double y=10.20f; 
x和y的表观类型是double,但实际类型是float。当我打电话时

System.out.println(" the output is :"+cc.sum1(x,y)); 
编译时的错误

The method sum1(int, int) in the type Class is not applicable for the arguments double, double). 

它应该转到sum1的地方,即方法3,通过将double转换为float

将double转换为float可能会导致数据丢失,因为这是一种缩小转换,因此编译器不会自动完成。如果您希望将变量显式转换为float,则必须将其转换为float。

将double转换为float可能会导致数据丢失,因为这是一种缩小转换,因此编译器不会自动完成。如果你想让它发生,你必须将变量强制转换为显式浮动。

否,变量的实际类型是双精度的。您分配给该双变量的常量的类型是float,在分配时会得到提升。

否,变量的实际类型是double。您分配给该双变量的常量类型是float,它在分配时得到提升。

TL;此答案的DR版本:

基元类型的变量在执行时的类型与其编译时的类型不同。双人总是双人的,从来不是浮动的,等等。 重载解析使用表达式的编译时类型来选择使用哪个方法签名 所拾取签名的方法实现是使用方法调用目标的执行时间类型执行的 x和y的表观类型是double,但实际类型是float

不,不是。您刚刚得到了从指定的浮点文本到双值的转换。实际值是两倍

原语不像对象那样工作——例如,不知道int值在双变量中仍然是int

以整数类型为例更简单。假设我们有:

byte b = 100;
int x = b;
x的值是表示值100的32位整数。它不知道它最初是从一个字节值赋值的。。。在赋值点刚好发生了从字节到int的转换

将其与引用类型进行比较:

这里,y的值实际上是对字符串对象的引用。这种类型信息之所以被保留,正是因为有一个完整的对象可以包含它,而且变量本身的值只是一个引用。这些位本身不需要作为赋值的一部分进行更改——至少在一个简单的VM中,它们在x和y中是完全相同的位,因为它们引用的是同一个对象

然而,即使在这种情况下,重载解析也是基于参数的编译时类型,而不是它们在执行时的实际值。变量的执行时间类型涉及的唯一方式是基于方法调用的目标进行重写。因此,如果我们有:

Foo f = new X();
Foo g = new Y();
Foo h = new Z();

f.someMethod(g, h);

。。。然后,编译器将在Foo中寻找一个具有两个Foo参数或对象或其他超类/接口的方法-所涉及的对象的实际类型是无关的。但是,在执行时,如果该方法已在X中被重写,则由于f值引用的对象的执行时间类型,将调用该重写。

TL;此答案的DR版本:

基元类型的变量在执行时的类型与其编译时的类型不同。双人总是双人的,从来不是浮动的,等等。 重载解析使用表达式的编译时类型来选择使用哪个方法签名 所拾取签名的方法实现是使用方法调用目标的执行时间类型执行的 x和y的表观类型是double,但实际类型是float

不,不是。您刚刚得到了从指定的浮点文本到双值的转换。实际值是两倍

原语不像对象那样工作——例如,不知道int值在双变量中仍然是int

以整数类型为例更简单。假设我们有:

byte b = 100;
int x = b;
x的值是表示值100的32位整数。它不知道它最初是从一个字节值赋值的。。。在赋值点刚好发生了从字节到int的转换

将其与引用类型进行比较:

这里,y的值实际上是对字符串对象的引用。这种类型信息之所以被保留,正是因为有一个完整的对象可以包含它,而且变量本身的值只是一个引用。这些位本身不需要作为赋值的一部分进行更改——至少在一个简单的VM中,它们在x和y中是完全相同的位,因为它们引用的是同一个对象

然而,即使在这种情况下,重载解析也是基于参数的编译时类型,而不是它们在执行时的实际值。唯一的办法是 变量的执行时间类型所涉及的是基于方法调用目标的重写。因此,如果我们有:

Foo f = new X();
Foo g = new Y();
Foo h = new Z();

f.someMethod(g, h);

。。。然后,编译器将在Foo中寻找一个具有两个Foo参数或对象或其他超类/接口的方法-所涉及的对象的实际类型是无关的。但是,在执行时,如果该方法已在X中被重写,则由于f值引用的对象的执行时间类型,将调用该重写。

尝试添加新函数:public double sum1double a,double b。它会解决你的问题。
而且,这种类型的转换将导致数据丢失。

尝试添加新功能:公共双用1双用a,双用b。它会解决你的问题。
而且,这种类型的转换将导致数据丢失。

这样的浮动很有趣。。他们总是试图自动转换成双打。这段代码进行编译,每一次都是浮动的

    public class wood {
    public static void main(String[] args) {
        float x = 10.1f;
        float y = 10.2f;
        System.out.println("Sum of x and y = " + sum1((float)x, (float)y));
    }
    public static float sum1(float x, float y) {
        return (float)((float)x+(float)y);
    }
}
编辑;请注意,使用括号外的强制转换运算符将在计算括号内的内容之后进行强制转换。所以,

System.out.println((int)(50.5 + 50.7));
将打印出101

在java中,有些数据转换是自动的,有些则需要强制转换运算符。。简单地说,java将自动进行加宽转换,而您必须使用cast操作符来缩小转换

基本数据类型的层次结构如下所示:

字节//1字节-128到127

短//超过32000的2个字节从0开始给予/接受

int//0中超过20亿个给定/获取的4字节

长//8字节,超过9千分之10^18从0中获取/给予

float//4字节保留7位小数

double//8字节保留15位小数

java不会自动进行缩小转换,因为这样数据就有丢失的风险。byte和short都将自动变为int

short s = 5;
byte b = 5;
short sum = s + b;  //this will cause an error!
s和b会自动将加宽转换为int,如果没有强制转换运算符,int不能指定给short

short sum = (short)(s + b);

是需要的。

这样的浮动很有趣。。他们总是试图自动转换成双打。这段代码进行编译,每一次都是浮动的

    public class wood {
    public static void main(String[] args) {
        float x = 10.1f;
        float y = 10.2f;
        System.out.println("Sum of x and y = " + sum1((float)x, (float)y));
    }
    public static float sum1(float x, float y) {
        return (float)((float)x+(float)y);
    }
}
编辑;请注意,使用括号外的强制转换运算符将在计算括号内的内容之后进行强制转换。所以,

System.out.println((int)(50.5 + 50.7));
将打印出101

在java中,有些数据转换是自动的,有些则需要强制转换运算符。。简单地说,java将自动进行加宽转换,而您必须使用cast操作符来缩小转换

基本数据类型的层次结构如下所示:

字节//1字节-128到127

短//超过32000的2个字节从0开始给予/接受

int//0中超过20亿个给定/获取的4字节

长//8字节,超过9千分之10^18从0中获取/给予

float//4字节保留7位小数

double//8字节保留15位小数

java不会自动进行缩小转换,因为这样数据就有丢失的风险。byte和short都将自动变为int

short s = 5;
byte b = 5;
short sum = s + b;  //this will cause an error!
s和b会自动将加宽转换为int,如果没有强制转换运算符,int不能指定给short

short sum = (short)(s + b);

将需要。

我甚至没有看到?“x和y的表面类型是双精度的,但实际类型是浮点型”–不,类型只是双精度的。基元类型不是多态的。float不是double的子类,即使它是:重载解析操作静态类型。而且,你的第二个过载是多余的。只要让编译器在调用时将int隐式转换为float即可。@5gon12eder:int是否将float转换为无损转换?@Thilo是的,它是。然而,LONGTO float并非如此。他们似乎只是将其定义为无损/加宽“从int到float,或从long到float,或从long到double的扩展原语转换可能会导致精度损失-也就是说,结果可能会丢失一些值的最低有效位。在这种情况下,生成的浮点值将是整数值的正确舍入版本,使用IEEE 754舍入到nearest模式。“我甚至看不到任何?“x和y的表面类型是双精度的,但实际类型是浮动”-不,类型只是双精度的。基元类型不是多态的。float不是double的子类,即使它是:重载解析操作静态类型。而且,你的第二个过载是多余的。只要让编译器在调用时将int隐式转换为float即可。@5gon12eder:int是否将float转换为无损转换?@Thilo是的,它是。然而,LONGTO float并非如此。他们似乎只是将其定义为无损/加宽“从int到float,或从long到float,或从long到double的扩展原语转换可能会导致精度损失-也就是说,结果可能会丢失一些值的最低有效位。在这种情况下,生成的浮点点
t值将是整数值的正确四舍五入版本,使用IEEE 754四舍五入到最近的模式。“@Thilo:True。将添加一些内容。@TheLostMind:是的,方法签名是在编译时选择的。但不仅仅是检查,即使在运行时出现了更好的签名,也会使用该签名。@Thilo:看看我的编辑是否足够-如果您想让我更详细地介绍,请告诉我。我有点不愿意回答这个问题,因为这个问题只涉及原语。@Thilo:是的。将添加一些内容。@TheLostMind:是的,方法签名是在编译时选择的。但不仅仅是检查,即使在运行时出现了更好的签名,也会使用该签名。@Thilo:看看我的编辑是否足够-如果您想让我更详细地介绍,请告诉我。我有点不愿意回答这个问题,因为这个问题只涉及原语。很高兴它有意义。了解java如何进行数据类型转换很重要。很高兴这有意义。了解java如何进行数据类型转换很重要。