2

i've some problems with java overloading and dynamic parameters..

import java.lang.*;

public class Program
{
     public static void main(String []args){
        testOverloading("Test string");
        testOverloading(new Object());
        testOverloading( true ? "Must be a string" : new Object());
     }

     public static void testOverloading(String test) {
         System.out.println("it's a string");
     }

     public static void testOverloading(Object test) {
         System.out.println("it's an object");
     }

}

running this code the java assume that "true ? "Must be a string" : new Object()" is an object and not a string..and the output is the follow:

it's a string
it's an object
it's an object

is there a solution/explaination for this kind of issue?

Update:

i tried also using a different approach:

changing:

testOverloading( true ? "Must be a string" : new Object());

in

testOverloading( true ? "Must be a string" : new Program());

and

public static void testOverloading(Object test) {

in

public static void testOverloading(Program test) {

and the output is:

error: no suitable method found for testPoly(Object)

so i've to assume that it's a compiler limitation with parameters that use single-line condition

in fact using normal the output is right:

    if (true)
        testOverloading("Must be a string");
    else
        testOverloading(new Object());

output: it's a string
Joseph
  • 1,029
  • 13
  • 26
  • 5
    That's not polymorphism, that's method overloading. Polymorphism would involve multiple types. (E.g., classes `A` and `B`, both of which implement `foo`.) – T.J. Crowder Aug 29 '14 at 14:58
  • 6
    `true ? "Must be a string" : new Object()` should have a single type of return. In this case, the compiler will choose the highest class in the class hierarchy for the elements being returned, which is `Object`. – Luiggi Mendoza Aug 29 '14 at 14:58
  • possible duplicate of [Unexpected type resulting from the ternary operator](http://stackoverflow.com/questions/25230171/unexpected-type-resulting-from-the-ternary-operator) – Alex - GlassEditor.com Aug 29 '14 at 15:01

5 Answers5

7

true ? "Must be a string" : new Object() should have a single type of return. In this case, the compiler will choose the highest class in the class hierarchy for the elements being returned, which is Object.

Luiggi Mendoza
  • 85,076
  • 16
  • 154
  • 332
2

In ternary operator the return type of both the expression should be same. But the compiler chooses the highest class hierarchy which is new object() in case of any conflict.

The Java docs says:

The type of a conditional expression is determined as follows:

If the second and third operands have the same type (which may be the null type), then that is the type of the conditional expression.

Rahul Tripathi
  • 168,305
  • 31
  • 280
  • 331
2

There's no way to know if your ternary operator will return a string or an object in compiling time so the compiler chooses the type of the highest class in the hierarchy, which is object in this case.

You can better understand it by trying to assign the result of the ternary operator to a String variable, you will get a compilation error

Ex:

String result = true ? "Must be a string" : new Object(); // compiler error
luizcarlosfx
  • 399
  • 1
  • 4
  • 11
1

It is not strange. It is because string is inherited from an object. Since your return statement can be of type object or string it chooses object type. If you cast it to be a string you would see different behavior.

you need to do something like this:

public class ReturnClass{
    Object object;
    ReturnType returnType;  


    public static Enum ReturnType {
        STRING,
        OBJECT   
    }
}
StackFlowed
  • 6,664
  • 1
  • 29
  • 45
  • Thanks for the superfast reply! however in my real environment need to use a dynamic parameter that could be conditionally a string or an object ... is the only way to allow it to use a normal if instead single-line condition? – Joseph Aug 29 '14 at 15:09
  • I would suggest you to use a differentiating parameter like enum which would tell you about a return type. since object is super abstract is a parent for most of the primitive types won't be able to achieve what you desire by simple methods. – StackFlowed Aug 29 '14 at 15:14
  • @Joseph by the description of your code, seems like you have a code smell. Please provide a more accurate implementation of this in your specific project or scenario. – Luiggi Mendoza Aug 29 '14 at 15:15
  • Please chef the edit you need to do something like this to attain with you want... – StackFlowed Aug 29 '14 at 15:24
  • @Aeshang how Enums could be used in overloading way? i wouldn't use switchers – Joseph Aug 29 '14 at 15:37
  • you testPoly would return a ReturnClass type object. and the you can use the enum to differentiate – StackFlowed Aug 29 '14 at 15:39
0

In an expression like statement, string constant would be constructed by compiler using StringBuilder. In an example of true ? "Must be a string" : new Object(), turns to true ? new StringBuilder ("Must be a string") : new Object(). Hence there was no match for StringBuilder, then it tries to typecast to parent default Object type.

dvrnaidu
  • 151
  • 1
  • 1
  • 9