简体   繁体   English

Java参数签名解析

[英]Java parametric signature resolution

Why does this code print 2.0 and not 1.0? 为什么此代码显示2.0而不是1.0?

abstract class B<T extends Number> {
    abstract Number f(T j);
}

class A<T extends Number> extends B<T> {
    public Number f(Float j) {
        return 1f;
    }

    public Number f(T j) {
        return j;
    }
}

public class J {
    public static void main(String[] args) {
        B<Float> a = new A<>();
        Number r = a.f(2f);
        System.out.println(r);
    }
}

What are you expecting. 你在期待什么 You have only one method declared in class B: 您只有在类B中声明的一种方法:

abstract Number f(T j);

The method in the class A A类中的方法

public Number f(Float j);

does not override the former. 不覆盖前者。 They have different signatures. 它们具有不同的签名。 So the method 所以方法

public Number f(T j) {
    return j;
}

gets called. 被叫。

So the heart of the problem here is that you have declared the variable a to be of type B . 因此,这里问题的核心在于,您已将变量a声明为B类型。 Since the B class has only one method, that's the one that wins. 由于B类只有一种方法,那就是获胜的方法。 However, in your main , if you change the type of a to be of type A , you'll notice that it will not compile because it is ambiguous. 然而,在你的main ,如果你改变的类型, a是类型的A ,你会发现它不能编译,因为它是不明确的。 However, if you did change the method in the class A to accept a primitive instead, and in the main() method defined the variable a to be of type A , it would result in 1.0 . 但是,如果您确实将类A的方法更改为接受原语,并且在main()方法中将变量a定义为A类型,则结果为1.0 Ie, the following will result in printing 1.0 : 即,以下将导致打印1.0

class A<T extends Number> extends B<T> {
    public Number f(float j) {
        return 1f;
    }

    public Number f(T j) {
        return j;
    }
}


public class J {
    public static void main(String[] args) {
        A<Float> a = new A<>();
        Number r = a.f(2f);
        System.out.println(r);
    }
}

In Your code below 在下面的代码中

abstract class B<T extends Number> {
 abstract Number f(T j);
}

class A<T extends Number> extends B<T> {
    public Number f(Float j) //this method does not override the superclass method

    {
        return 1f;
    }

    public Number f(T j) {
        return j;
    }
}

public class J {
    public static void main(String[] args) {
        B<Float> a = new A<>();
        Number r = a.f(2f);
        System.out.println(r);
    }
}

when call to af(2f) is occured it will call the 发生对af(2f)的调用时,它将调用

public Number f(T j)
{
return j;
}

which return j thus output provided is 2.0 返回j从而提供的输出是2.0

float is not the same thing as Float . floatFloat

Auto-boxing makes it feel the same, but one main difference is you can't pass a null into a float parameter. 自动装箱使它具有相同的感觉 ,但主要区别在于您不能将null传递给float参数。

I recommend using the @Override annotation on your overridden methods, so the compiler will tell you if the signature is correct 我建议在您的重写方法上使用@Override批注,这样编译器会告诉您签名是否正确

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM