• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Sheriffs:
  • Ron McLeod
  • Devaka Cooray
  • Henry Wong
Saloon Keepers:
  • Tim Holloway
  • Stephan van Hulst
  • Carey Brown
  • Tim Moores
  • Mikalai Zaikin
Bartenders:
  • Frits Walraven

varargs and overload resolution | OCP 17

 
Ranch Foreman
Posts: 38
5
MySQL Database Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi

I'm studying about varargs and overload resolution in java for certification exam. I was trying some coding examples.
Though,I've got the expected output in the following examples. But I want to make sure my reasoning behind the expected
output is correct.

Kindly look at these sample snippets and my reasoning in comments and provide your guidance in case there is some gap in my understanding of
concepts.


Thanks
 
Marshal
Posts: 79956
396
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Please use ordinary block comments rather than documentation comments. One * after the / please.
You will find all the gory details in the JLS (=Java® Language Specification) (see phase 3).
Since varargs is a way to ceate an array, passing anObject[] is a better fit than the one‑argument method.
I think you have overlooked the arity of the arguments. When you pass one Integer argument, the one‑argument method is a better fit than the varargs method; if you pass any other number, the varargs method will be a better fit.
Challenge: without running any more code, tell us what will happen,
  • 1: if you call go();
  • 2: if you call go(null);
  • 3: if you write a method go(Object[])
  • 4: if you call go(new String[]{"Coderanch", "is", "brilliant",});


  • Sorry: I wrote most of this reply earlier today and forgot to push “Submit”.
     
    Dalvir Singh Bains
    Ranch Foreman
    Posts: 38
    5
    MySQL Database Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thanks for your reply Campbell.  I'll keep in mind coding writing guidelines as you've mentioned.

    I've honestly dumped my brain memory stack in this response without running this code. I want to discover any potential "unknown unknowns" in my understanding of this concept.

    Please excuse me for being a bit verbose.
    I'm answering your questions as per my understanding. Please review:

    1: if you call go();

    Here, we're calling go() without any argument. This method call technically maps to both method signatures. However,  compiler will look for the most specific method, which is Object...(internally Object[ ]) in this case. Since , Object [ ] IS-A Object ( Every array IS-A Object in java). Hence, for zero arguments in this case , most specific method is Object... for compiler.
    Answer: Object...

    2: if you call go(null);

    null value is a valid value for both method signatures. So, there's a clash here. Compiler resolves it by choosing the most specific based on the provided null argument at call site. Out of 2 method candidates, Object [ ] is more specific than Object. Since every argument that can be passed to method call go(Object... ) can also be passed to go(Object) but not the other way around ( for this call involving null). By this logic, I believe, most specific method is varargs version Object... over Object in this case.
    Answer: Object...

    3: if you write a method go(Object[])

    Compiler looks for a method taking Object [ ] as argument. There is none here. It widens the type to Object since Object[ ] IS-A Object in java. Now, there's a match and binds the method invocation call to Object version. No need to go to the resolution phase involving varargs since method invocation call is resolved already without involving varargs.
    Answer: Object

    4: if you call go(new String[]{"Coderanch", "is", "brilliant",});

    Here, we're passing an instantiation of the String [ ]. Now, String [ ] IS-A Object and String [ ] is also subtype of Object [ ]  due to covariance in arrays. How will compiler choose the most specific method?
    I believe same reasoning as Question 3 applies here. String [ ] is widened to Object and the Object version is selected over varargs.
    Answer: Object

    Thanks
     
    Campbell Ritchie
    Marshal
    Posts: 79956
    396
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Dalvir Singh Bains wrote:. . . go() without any argument . . . technically maps to both method signatures.

    No, it doesn't. It cannot match go(Object) and must therefore be converted to a zero‑length array.

    . . .
    null value is a valid value for both method signatures. . . . most specific method is varargs version Object... over Object in this case.
    Answer: Object...

    Disagree. You are forgetting the arity of the arguments, so the one‑argument method takes rpecedence over the varargs method.

    3: if you write a method go(Object[])

    Compiler looks for a method taking Object [ ] as argument. . . .

    No. Since Object... is converted to Object[] inside the method, the compiler will perceive two methods which are override‑equivalent to each other and the code will fail to compile.

    4: if you call go(new String[]{"Coderanch", "is", "brilliant",});

    Try it and see; the code compiles but fails with an error at runtime.

    Thanks

    That's a pleasure
     
    Dalvir Singh Bains
    Ranch Foreman
    Posts: 38
    5
    MySQL Database Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thanks Campbell for your reply.  

    I ran all the 4 examples both using IntelliJ and Online Java Compiler (Programiz). I have attached the compilation results along with this message.

    CASE 1: go()
    I believe I’m satisfied with your feedback to first example. Not passing any argument to a method is considered 0-arity argument. Hence, it’s a clear match for the Object...  

    However, for the remaining three cases, I believe we can discuss as our results differ.I’ll cover each case one by one. It can be a bit long post but I tried to be as specific as possible.Please bear with me.

    As per section 15.12.2. Compile-Time Step 2: Determine Method Signature of JLS, method overload resolution happens in three phases.
    1.The first phase performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.



    CASE 2: Now, when we use go(null);

    As per your comment to second case,  

    Disagree. You are forgetting the arity of the arguments, so the one‑argument method takes precedence over the varargs method.



    go(null) is a 1-arity method; so as per the above statement it should map to go(Object) rather than go(Object...) during first phase of overload resolution.since a variable arity method is treated as a fixed arity method in the first phase.

    But I believe what’s going on here is: since null type has no explicit name and null reference can be cast to any other reference type. Hence, compiler can’t perfrom a widening reference conversion of null value in Phase 1. since it can be hypothetically widened to any reference type. Both go(Object) and go(Object...) are equally valid candidates for overload resolution in phase 1 as discovered by compiler.

    RESULT: we have 2 potential applicable methods; so choose most specific method as per algorithm mentioned in

    JLS  15.12.2.5. Choosing the Most Specific Method



    I believe, the main decisive point for non-generic methods as per this dreaded JLS section  is to prefer specific type over general type; which in this case is Object... not Object.

    Since all arrays are considered objects in java but not all java objects are arrays.

    So, Object[ ] IS-A Object and hence, compiler chose the most specific method go(Object...) over go(Object)  for the method call go(null).

    That’s the output I got for CASE 2.

    CASE 3: go(Object[ ])
    if I consider the following code snippet:  

    Since, we’re explicitily providing the method argument of type Object[ ] (compiler knows the static type of variable obj at compile time)

    Compiler uses the Strict Invocation Context rules of Phase 1 which allow use of identity conversion to choose a method.

    5.1.1. Identity Conversion  
    A conversion from a type to that same type is permitted for any type.  



    Hence, compiler does overload resolution based on Identity conversion in this case and no need to go to Phase 2 and Phase 3.

    So, I disagree with your following reply as code compiles based on above logic.

    No. Since Object... is converted to Object[] inside the method, the compiler will perceive two methods which are override‑equivalent to each other and the code will fail to compile.



    CASE 4:   go(new String[ ]{"Coderanch", "is", "brilliant"});

    I ran the code and it compiled fine running the Object... version of the method.

    REASON: I believe at compile time, the argument expression which is an array creation expression is evaluated to be of type String[ ] in the method call go( new String[ ] {"Coderanch", "is", "brilliant"})

    Now, during the first phase of the overload resolution, compiler looks for potentially applicable methods for the call go(String[ ]) using phase 1 Strict Invocation context rules.

    Since, the array component type is String which is a reference type, compiler first applies the  widening reference conversion for array type. In order to do widening reference conversion among array types,the following rule is followed:

    As per section 4.10.3. Subtyping among Array Types of JLS

    If S and T are both reference types, then S[ ] is a direct subtype of T[ ] iff S is a direct subtype of T.



    Since String is a direct subtype of Object in java. Hence, String [ ] is a direct subtype of Object [ ]

    Compiler found a method match in phase 1 and resolution process is over.

    I believe that’s the reason in this case Object... will be chosen by compiler over Object. On compilation it’s chosing the Object... version in Case 4.

    Please review my answer and suggest any improvement and guide me if possible regarding my approach.

    Thanks
    first.PNG
    [Thumbnail for first.PNG]
    fourth.PNG
    [Thumbnail for fourth.PNG]
    second.PNG
    [Thumbnail for second.PNG]
     
    Campbell Ritchie
    Marshal
    Posts: 79956
    396
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Yes, you are right: interpreting null, or an array supplied as an argument, as Object[] gives you a more specific fit than calling them a plain simple Object.
     
    Dalvir Singh Bains
    Ranch Foreman
    Posts: 38
    5
    MySQL Database Java
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thanks Campbell for your inputs. I learned multiple java concepts indirectly while I worked on these problems. It was absolutely worth the time.
     
    Campbell Ritchie
    Marshal
    Posts: 79956
    396
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Dalvir Singh Bains wrote:Thanks Campbell . . .

    That's a pleasure and sorry for my mistakes.
     
    Dalvir Singh Bains
    Ranch Foreman
    Posts: 38
    5
    MySQL Database Java
    • Likes 1
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    You're welcome Campbell. I earned my first coderanch cow.yayyyy!!
     
    Grow a forest with seedballs and this tiny ad:
    Gift giving made easy with the permaculture playing cards
    https://coderanch.com/t/777758/Gift-giving-easy-permaculture-playing
    reply
      Bookmark Topic Watch Topic
    • New Topic