"<i><b>if we replace the S into lower case s for Short(i.e public static void go(Short n)) we will get the O/P "Short Long</b></i>"
short is not the same data type as Short.
short is a primitive type, while Short is a class.
Depending on the type of your "y" variable, the appropriate method will be called, so, if you declare your "y" variable as "short", java will look for a go implementation that takes one "short" argument, but it does not exist, so the "int" implementation is called (it is the best option in this case as short is like a small int).
So, you can change <b>both</b>, the method definition and the variable data type to "short" or change both to "Short" and it will work as you expect.
Another way of answering the question is to describe how the JVM tries to resolve runtime execution of polymorphed methods like the "go" method described above.
"long" and "short" are unsigned primitive data types in Java, with a limitation assigned to their maximum and minimum values. "long" has a much broader range than "short" does, indicated by their names.
When the JVM tries to do a runtime resolution of which method to execute based on the type of value in the execution parameter, it attempts to resolve it exactly first:
However, the implementation does not provide an exact match, so the JVM will attempt to implicitly convert to the next closest matching primitve. If no match there, the JVM will "cast" the primitive values to Object types that represent a safe implementation of the possible values, and call a "go()" method that implements that match.
short => int
long => Long
So, go(short) executes the go(int) method, and go(long) executes the go(Long) method.