Wednesday, 12 April 2017

How Static Type Checking Works in Java?

Java uses static type checking to analyze the program during compile-time to prove the absence of type errors. The basic idea is never let bad things happen at runtime. By understanding the following example, you should have a good understanding of how static type checking works in Java.

Oracle Java Tutorials and Materials, Oracle Java Certifications, Oracle Java Guide


Code Example


Suppose we have the following classes, A and B. B extends A.

class A {
A me() {
return this;
}

public void doA() {
System.out.println("Do A");
}
}

class B extends A {
public void doB() {
System.out.println("Do B");
}
}

First of all, what does "new B().me()" return? An A object or a B object?

The me() method is declared to return an A, so during compile time, compiler only sees it return an A object. However, it actually returns a B object during run-time, since B inherits A's methods and return this(itself).

How Static Type Checking Works?


The following line will be illegal, even though the object is being invoked on is a B object. The problem is that its reference type is A. Compiler doesn't know its real type during compile-time, so it sees the object as type A.

//illegal
new B().me().doB();

So only the following method can be invoked.

//legal
new B().me().doA();

However, we can cast the object to type B, like the following:

//legal
((B) new B().me()).doB();

If the following C class is added,

class C extends A{
public void doBad() {
System.out.println("Do C");
}
}

then the following statement is legal and can pass static type checking:

//legal
((C) new B().me()).beBad();

Compiler does not know it's real time, but runtime will throw a cast exception since B can not be casted to C:

 java.lang.ClassCastException: B cannot be cast to C