简体   繁体   中英

Strange behavior with java overloading

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

true ? "Must be a string" : new Object() 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 .

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.

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

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   
    }
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM