public class A{
public static int x = 1;
public int m(A a, B b){
return a.m(b, b) + x;
}
}
public class B extends A {
public int m(A a1, B a2){
if(a1 == a2)
return x;
return super.m(a1,a2);
}
}
Run Code Online (Sandbox Code Playgroud)
这是我过去考试的一个问题.
public class Main{
public static void main(String[] args){
B b1 = new B(){int m(A a, A b){ return 10; }};
System.out.println(b1.m(b1, b1));
}
}
Run Code Online (Sandbox Code Playgroud)
问题是,以下输出是什么.我在答案1中是对的.但我没有完全理解为什么.
由于B对象的内部类是(A,A).我是否正确认为它不能覆盖超级方法m,因为它是(A,B)?如果交换了两个方法的参数,它是否能够覆盖?
既然它既不能覆盖也不能超载,它什么也不做,只是在B类中使用方法m?
对象的内部类是否仅适用于自身?它就像一个异类吗?
为所有问题道歉.
提前致谢.
编辑:
从我到目前为止的理解,因为静态类型设置为B,所以类型B无法看到anon类.如果将其设置为公开,则可以看到它,但仍然不会使用它.
这使我对另一个问题感到困惑.
public class A{
public static int x = 1;
public int m(A a, B b){
return a.m(b, b) + x;
}
}
public class Main{
public static void main(String[] args){
A a1=new A();
A a2=new A(){
int m(A a,B b){
return 10;
}};
B b1=new B();
System.out.println(a1.m(a2,b1));
}
}
Run Code Online (Sandbox Code Playgroud)
当调用以下内容时,输出为11.调用a1.m时,它传递a2和b1.
在A类中,当调用am(b,b)时.它调用动态类型.这是因为一旦解析它会变为动态类型吗?那么现在它可以使用anon类了吗?
让我们一起浏览JVM:
B b1 = new B(){ int m(A a,A b) { return 10; } };
Run Code Online (Sandbox Code Playgroud)
这将创建一个带有两个类型参数的B方法的匿名重载的实例.但这与类(或)定义的方法不同,因为它们的签名(vs )不同.m()A m()BAA, AA, B
然后:
System.out.println(b1.m(b1, b1));
Run Code Online (Sandbox Code Playgroud)
这调用带有两个类型参数b1的m()方法B.
现在JVM查找的m()是:
m()有两个类型的参数B;B,它找到一个匹配:一个名称m()的方法,其第一个参数是a A(因为B继承A),第二个参数是type B;b1被完全忽略了!(见https://gist.github.com/fge/5762353)因此调用m()类的方法B.在这种方法中,我们有:
if (a1 == a2) // TRUE!
return x;
Run Code Online (Sandbox Code Playgroud)
由于条件为真(已使用两个参数调用的方法是完全相同的对象引用),因此x必须返回值; 和x由类定义A,其中类B extends:
public static int x = 1;
Run Code Online (Sandbox Code Playgroud)
由于这是A类的静态成员(B类不隐藏),因此可以通过实例方法从Aor的任何实例中访问它B; 因此,该程序的返回码和输出为1.
| 归档时间: |
|
| 查看次数: |
95 次 |
| 最近记录: |