Java参数签名解析
为什么该代码打印2.0而不是1.0Java参数签名解析,java,oop,generics,inheritance,Java,Oop,Generics,Inheritance,为什么该代码打印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;
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);
}
}
抽象类B{
抽象数f(tj);
}
A类延伸至B类{
公众号f(浮动j){
返回1f;
}
公众号f(T j){
返回j;
}
}
公共类J{
公共静态void main(字符串[]args){
B a=新的a();
数字r=a.f(2f);
系统输出println(r);
}
}
你期待什么。在类B中只声明了一个方法:
abstract Number f(T j);
A类中的方法
public Number f(Float j);
不覆盖前者。他们有不同的签名。那么方法呢
public Number f(T j) {
return j;
}
被呼叫。您期望的是什么。在类B中只声明了一个方法:
abstract Number f(T j);
A类中的方法
public Number f(Float j);
不覆盖前者。他们有不同的签名。那么方法呢
public Number f(T j) {
return j;
}
在下面的代码中调用。
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);
}
}
在下面的代码中,这样输出的返回值是2.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) //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);
}
}
因此,输出提供的返回j是2.0,因此这里的问题的核心是您已将变量
a
声明为B
类型。因为B
类只有一个方法,那就是获胜的方法。但是,在main
中,如果将a
的类型更改为a
类型,您会注意到它不会编译,因为它是不明确的。但是,如果确实更改了类A
中的方法以接受原语,并且在main()
方法中将变量A
定义为类型A
,则会导致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);
}
}
A类扩展B类{
公众号f(浮动j){
返回1f;
}
公众号f(T j){
返回j;
}
}
公共类J{
公共静态void main(字符串[]args){
A=新的A();
数字r=a.f(2f);
系统输出println(r);
}
}
因此,这里的核心问题是您已将变量a
声明为B
类型。因为B
类只有一个方法,那就是获胜的方法。但是,在main
中,如果将a
的类型更改为a
类型,您会注意到它不会编译,因为它是不明确的。但是,如果确实更改了类A
中的方法以接受原语,并且在main()
方法中将变量A
定义为类型A
,则会导致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);
}
}
A类扩展B类{
公众号f(浮动j){
返回1f;
}
公众号f(T j){
返回j;
}
}
公共类J{
公共静态void main(字符串[]args){
A=新的A();
数字r=a.f(2f);
系统输出println(r);
}
}
float
与float
不同
自动装箱使其感觉相同,但一个主要区别是不能将null
传递到float
参数中
我建议在重写的方法上使用
@Override
注释,这样编译器会告诉您签名是否正确float
与float
不同
自动装箱使其感觉相同,但一个主要区别是不能将null
传递到float
参数中
我建议在被重写的方法上使用
@Override
注释,这样编译器会告诉您签名是否正确好的,但是为什么它不重写超类方法?好的,但是为什么它不重写超类方法?我天真地希望它调用具有更严格签名的方法f(Float)
而不是f(T扩展数字)
我天真地期望它调用具有更严格签名的方法f(Float)
而不是f(T扩展数字)