How Static Type Checking Works in Java?

From Wiki:

Static type-checking is the process of verifying the type safety of a program based on analysis of a program’s source code.

Dynamic type-checking is the process of verifying the type safety of a program at runtime

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.

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

References:
1. Type system

2 thoughts on “How Static Type Checking Works in Java?”

  1. There is a case that I met before.
    Here is a interface Action with the action do(). and two class ActionA and ActionB both implement Action.

    In the code , I casted an ActionB object into an ActionA object in mistake and call the method do().

    Why is call the ActionA.do() not ActionB.do() but the object is an ActionB object?

    My English is not very well, sorry for the grammatical mistake.

Leave a Comment