6

I saw this one question in scjp preparation book.

public class Yikes {
    public static void go(Long n) {
        System.out.println("Long ");
    }
    public static void go(Short n) {
        System.out.println("Short ");
    }
    public static void go(int n) {
        System.out.println("int ");
    }
    public static void main(String [] args) {
        short y = 6;
        long z = 7;
        go(y);
        go(z);
    }
}

The output is int Long.

I am passing short datatype variable to overloaded method go. Now go has a short datatype version also. Then how come the one with int is getting invoked? What is the reason for this behaviour?

I am quite new in java. So please help me here.

Shades88
  • 7,934
  • 22
  • 88
  • 130
  • 1
    `Short` and `short` are distinct types, many expressions get promoted to `int`. – Brian Cain Aug 26 '12 at 13:43
  • Check http://stackoverflow.com/questions/477750/primitive-type-short-casting-in-java – home Aug 26 '12 at 13:46
  • Yep, if you used `short` rather than (the abomination) `Short` then you'd get the expected result. – Hot Licks Aug 26 '12 at 13:46
  • my god...I just didn't notice. `short` and `Short`??? Gotta be aware of weird ways of java from now on. – Shades88 Aug 26 '12 at 13:53
  • Yep. [All the primitive types have corresponding objects for boxing.](http://docs.oracle.com/javase/specs/jls/se5.0/html/conversions.html#190697) – verdesmarald Aug 26 '12 at 13:54

1 Answers1

9

Since there is no method go(short s) to choose, Java has to choose another one. This can be done in two ways:

  1. Widening, widening the short to an int
  2. Autoboxing, surrounding the short with a Short, the corresponding wrapper class.

Since widening has been around longer than autoboxing (introduced in Java 5), the JVM chooses this alternative first if available.

Therefore, the go(int n) method is invoked.

Keppil
  • 45,603
  • 8
  • 97
  • 119
  • For further reference, [S5.3](http://docs.oracle.com/javase/specs/jls/se5.0/html/conversions.html#12687) of the JLS lists the order that conversions are considered when deciding which overload to call. – verdesmarald Aug 26 '12 at 13:51
  • Are you sure the reason for precedence is just age? It makes sense since that way is backwards compatible. – Luis Aug 26 '12 at 13:53
  • Have to learn to read the java code more carefully now. `short` and `Short` two different datatypes !! – Shades88 Aug 26 '12 at 13:54
  • @Luis: Yes, they didn't want to change the way old code works, so they pretty much had to give widening higher priority. – Keppil Aug 26 '12 at 13:56
  • but wait..There's `long z` variable which went to method with Long datatype as argument. Then why it didn't give compile error? – Shades88 Aug 26 '12 at 13:59
  • @Shades88: First it sees if it can widen the `long` to anything, which it can't. So, then it tries to autobox it, which succeeds. If you add a new method `go(double n)` the widening will succeed and this will be invoked instead of the `go(Long l)`. – Keppil Aug 26 '12 at 14:03
  • 1
    @Shades88: Since you can't widen a `long` to either a `short` or an `int`, Java uses Autoboxing to *convert* from `long` to `Long`. – João Silva Aug 26 '12 at 14:04