Predict the output of this program:
import java.io.*; class LastError<T> { private T lastError; void setError(T t){ lastError = t;/* www. j a v a 2s . c o m*/ System.out.println("LastError: setError"); } } class StrLastError<S extends CharSequence> extends LastError<String>{ public StrLastError(S s) { } void setError(S s){ System.out.println("StrLastError: setError"); } } public class Main { public static void main(String []args) { StrLastError<String> err = new StrLastError<String>("Error"); err.setError("Last error"); } }
A.It prints the following: StrLastError: setError. B.It prints the following: LastError: setError. C.It results in a compilation error. D.It results in a runtime exception.
C.
It looks like the setError()
method in StrLastError
is overriding setError()
in the LastError
class.
However, it is not the case.
At the time of compilation, the knowledge of type S is not available.
Therefore, the compiler records the signatures of these two methods as setError(String)
in super class and setError(S_extends_CharSequence)
in subclass-treating them as overloaded methods (not overridden).
In this case, when the call to setError()
is found, the compiler finds both the overloaded methods matching, resulting in the ambiguous method call error.