27

I have a quick and straighforward question:

I have this simple class:

public class A { public void m(Object o) { System.out.println("m with Object called"); } public void m(Number n) { System.out.println("m with Number called"); } public static void main(String[] args) { A a = new A(); // why will m(Number) be called? a.m(null); } } 

UPDATE: actually is method with Number actually being called. Sorry about the confusion.

If I call a.m(null) it calls method with Number parameter.

My question is: why is this? where in the java language specification is this specified?

3
  • 1
    ... because null is not a Number object, thus it falls into the more generalized Object bucket. Commented Feb 10, 2011 at 18:05
  • 5
    that's funny because on my machine (running it on eclipse) it alwways defaults to the Number method Commented Feb 10, 2011 at 18:06
  • -1 this is overloading, not overriding Commented Feb 10, 2011 at 18:29

5 Answers 5

27

First of all, it actually calls m(Number).

It happens because both methods are applicable, but m(Number) is the most specific method, since any argument of m(Number) can be passed to m(Object), but not vice versa.

If you replace m(Object) by m(String) (or add another method such as m(Date)), compiler would report ambiguity, since the most specific method can't be identified.

See the section Choosing the Most Specific Method in the Java Specification.

Sign up to request clarification or add additional context in comments.

1 Comment

ok, now that I've actually run the example code, I see this too. It also makes sense that once I added m(Date n){...} that I got an error: "method m(Object) is ambiguous for the type"
12
  1. This is not polymorphism or overriding. This is method overloading.
  2. I tested this and specific method is being called (not the m(Object)) and according to the spec the specific method is always called. Which overload will get selected for null in Java?

1 Comment

+1 for noting the difference between overriding and overloading
8

another related question for you to think about:

public static void main(String[] args) { A a = new A(); Object n = new Integer(1); a.m(n); // which method will be called? } 

1 Comment

"m with Object called" will be called but i don't know why. Can anyone explain? Intuitively, I thought "m with Number called" will be printed, but... noooooo.
1

My 2 cents. Method with Number argument is the one that is called, Because Number extends Object. I had a similar situation in the past, I did override a method and put Component instead of JComponent (by mistake). It took me one week to find out the reason why my method was never called. I figure it out, that if there are some inheritance relationship between the overloaded methods, the JVM matches first the deeper one in the class hierarchy.

Comments

0

Object is the default type in Java. If you refactor your m(Object o) method to m(String o) you'll have a compile time error saying that the call m(null) is ambiguous because Java cannot determine which class between String and Number defaults to null

Other than that, between m(Object o) and m(Number o), calling m(null) will call m(Number o) because it's the most specialized method. You would need to cast null into an Object (or anything not an instance of Number) otherwise.

a.m((String) null); 

2 Comments

null has no type and it calles m(Number)
well... formally there is a null type, and it's a subtype of all reference types. pretty weird.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.