别名意味着有多个别名指向同一个位置,且这些别名有不同的类型。
在下面的代码例子中,a和b是两个不同的名字,有不同的类型A和B,B继承A
B[] b = new B[10]; A[] a = b; a[0] = new A(); b[0].methodParent();
在内存中,它们指向了同一个位置,如下:
内存中的该位置同时被a和b指向,在运行期间,方法的调用由实际存储的对象来决定。
如果你拷贝以下代码到你的浏览器,会发现没有编译错误,
package simplejava; class A { public void methodParent() { System.out.println("method in Parent"); } } class B extends A { public void methodParent() { System.out.println("override method in Child"); } public void methodChild() { System.out.println("method in Child"); } } public class Q20 { public static void main(String[] args) { B[] b = new B[10]; A[] a = b; a[0] = new A(); b[0].methodParent(); } }
但是当你运行以上代码的时候,结果会输出如下错误信息:
原因是因为Java是在运行期间处理别名的,在运行期间,知道第一个元素应该是B对象,而不是A对象。
因此,如果代码改成如下所示将会运行成功:
B[] b = new B[10]; A[] a = b; a[0] = new B(); b[0].methodParent();
结果打印:
译文链接:http://www.programcreek.com/2012/12/how-does-java-handle-aliasing/