简体   繁体   中英

In Java, can I use the conditional expression to “choose” reference types?

Can I use the conditional expression to "choose" a reference type, as shown below?

??? = isTrue() ? Integer : Double;

Is there something I can place in " ??? " to make the code snippet compilable?

Edit : When I wrote Integer and Double, I didn't mean an instance of Integer or Double. I meant the reference type Integer and Double.

You can choose the implementation but you won't be able to use any of the specializities of the implementations; in your example, you could do

Number n = isTrue() ? 1 : 1.0;

which would be autoboxed to the correct datatype underneath but since the superclass is Number, you really wouldn't be able to do much with it.

EDIT:

Since the actual example above is a known bug in Java, here's another that behaves as expected:

CharSequence cs = isTrue() ? "I'm a String"
                           : new StringBuilder().append("I'm a StringBuilder");

System.out.println(cs+" "+cs.getClass());
// prints out
// I'm a String class java.lang.String

No, because that isn't syntactically valid Java. If you replace Integer by Integer.class and Double by Double.class, it will work just fine. However, I expect that's not what you want.

In that case, ??? would have to be

Class var

I think you're trying to use the ternary boolean operator to choose the reference type of your variable.

This is not possible in Java as Java is statically typed - meaning every type is well-defined at compile-time. Your expression would like to run a method and based on its output, determine the reference type which is not possible at compile-time.

You could do something like that but you would have to pass Integer and Double as strings to another argument, perhaps a constructor that would instantiate the type variables you are looking for. As you can see this solution requires a lot of creativity and so I guess the shorter and more correct answer to your question is not really.

Edit : my original answer is wrong, as pointed out by Jesper... and thanks to Jesper I have yet another reason to dissuade people from using the ternary operator, because the following if/else behavior exemplifies the behavior I originally sought after:

 Number n;
    if (isTrue()) { n = Double.valueOf(1.0); }
    else {n = Integer.valueOf(1);}
    System.out.println(n.getClass().getName()) //prints java.lang.Integer if isTrue returns false

Original answer:

You will need to assign to a supertype of Double or Integer to get this to work. Number should do the trick.

Number n = isTrue() ? whateverYouDoToReturnInteger() :  whateverYouDoToReturnDouble();

Granted, you will lose the exact subtype here, but it will compile at least which is what you wanted.

You can use different types but you have to store the result in a type that's the supertype of both. So the quick answer is no, you can't choose the reference type this way.

The closest you can get to it is storing them in the closest available supertype (in this case number):

Number n = functionReturningBoolean() ? 1.0 : 1;

...and then if you really want access to things specific to a single type, check and cast. This is nasty though and I can't think of a case where I'd use it in practice (though that's not a dig, purely academic questions are just as valid as practical ones!)

If you're just trying to get select a type, and not an instance, you could do something like:

Class result = isTrue() ? Integer.class | Double.class;

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