Category >> Diagram >> Memory  

How does Java handle aliasing?

What is Java aliasing?

Aliasing means there are multiple aliases to a location that can be updated, and these aliases have different types.

In the following example, a and b are two variable names that have two different types A and B. B extends A.

B[] b = new B[10];
A[] a = b;
 
a[0] =  new A();
b[0].methodParent();

In memory, they both refer to the same location.

Java Aliasing

The pointed memory location are pointed by both a and b. During run-time, the actual object stored determines which method to call.

How does Java handle aliasing problem?

If you copy this code to your eclipse, there will be no compilation errors.

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 Main {
 
	public static void main(String[] args) {
 
		B[] b = new B[10];
		A[] a = b;
 
		a[0] =  new A();
		b[0].methodParent();
	}
}

But if you run the code, the output would be:

Exception in thread "main" java.lang.ArrayStoreException: aliasingtest.A
	at aliasingtest.Main.main(Main.java:26)

The reason is that Java handles aliasing during run-time. During run-time, it knows that the first element should be a B object, instead of A.

Therefore, it only runs correctly if it is changed to:

B[] b = new B[10];
A[] a = b;
 
a[0] =  new B();
b[0].methodParent();

and the output is:

override method in Child
Category >> Diagram >> Memory  
  • Tony Kaser

    It’s easier to see what is happening if you examine the underlying class.

    public static void main(String[] args) {
    B[] b = new B[10];
    A[] a = new A[10];

    System.out.println(“Before:”);
    System.out.println(“a = ” + a.getClass().getCanonicalName());
    System.out.println(“a contains ” + a.getClass().getComponentType().getCanonicalName());

    a = b;

    System.out.println(“After:”);

    System.out.println(“a = ” + a.getClass().getCanonicalName());
    System.out.println(“a contains ” + a.getClass().getComponentType().getCanonicalName());
    }

    and the output is :

    Before:
    a = my.pkg.A[]
    a contains my.pkg.A
    After:
    a = my.pkg.B[]
    a contains my.pkg.B

    Notice that while ‘a’ was declared as A[], the assignment “a = b” changes the type of ‘a’ to B[].
    Since ‘a’ is no longer an array of class A it can no longer store any instances of class A