Java Reference
In-Depth Information
and the following incorrect use:
public static void main(String[] args) {
PassThrough s = new PassThroughString();
s.passThrough(args);
}
This results in an "unchecked" warning at compile time because the use
of the raw type means that we don't know what type
passThrough
should
take or return. But we can see that
s.passThrough
should only be accept-
ing a
String
argument, and
args
is a
String[]
not a
String
. If the compiler
rejected the above, we could appease the compiler by casting
args
to
String
, and then we should expect, and would get, a
ClassCastException
at runtime. However, the compiler doesn't reject this code, but in fact if
we execute this method a
ClassCastException
is still thrown. This behavi-
or is specified as a special rule of method invocation that deals with this
situation in
JLS
15.12.4.5:
If the erasure of the type of the method being invoked differs in
its signature from the erasure of the type of the compile-time de-
claration for the method invocation, then if any of the argument
values is an object which is not an instance of a subclass or subin-
terface of the erasure of the corresponding formal parameter type
in the compile-time declaration for the method invocation, then a
ClassCastException
is thrown.
In simple terms, the compiler has to accept incorrect invocations like
the above at compile time, but it has to ensure that at runtime the bad
argument is not actually passed to the method. The
ClassCastException
must be thrown before invoking the method (as if we had put in the
bad cast ourselves). One way a compiler can ensure this is to introduce
what is known as a
bridge method.
A suitable bridge method in this case
would be the following: