I'm trying to run a code. i and i get two compilation errors:
1.Reference to System.out.println is ambiguous (conflict between method that gets char[] and a method that gets a String)
2.Cap#1 can't converted to T return st.pop()
import java.util.*;
public class Test
{
public static void main(String[] args)
{
Stack <Number> stackNumber = new Stack<Number>();
Test t = new Test();
t.setMethod(stackNumber,new Integer(3));
System.out.println(t.getMethod(stackNumber));
}
public <T extends Number> void setMethod (Stack<? super Number>st,T t)
{
st.add(t);
}
public <T>T getMethod (Stack<? extends Number >st)
{
return st.pop();
}
}
I know that i can change getMethod signature to return Number and program will be compiled successfully but i want to understand why with current signature i'm getting compilation errors? AFAIK, T without bounds considered as Object and a function that declares to return Object can return any Object since Object is the "Father" of all classes (including Number). Can someone me what i'm dismissing here?
The errors are both because
<T>is determined at the call site.Looking at compilation error 1:
Java selects the most specifically-applicable method. Any of the
PrintStream.printlnmethods that take a reference-typed parameter could be selected.From JLS 15.12.2.5:
Anything that you can pass to
println(char[])orprintln(String)can also be passed toprintln(Object), therefore the former methods are more specific than the latter. As such, these will be selected in preference toprintln(Object).However, some things that can be passed to
println(char[])cannot be passed toprintln(String), therefore neither of those is more specific than the other, hence the ambiguous method call.Now looking at compilation error 2:
This method must be safe to invoke in all situations. You invoke it like this:
i.e. you treat the result simply like an object. But you could, legally, write this at the call site:
It's hopefully clear that this would fail, because something popped out of a stack containing numbers can't be cast to a
String.Because the compiler can't guarantee that it will be called with a "safe"
T, it's an error.