Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java conditional operator and different types

I have two methods in the Item Class:

public void setValue(String v);
public void setValue(Double v);

and I want to use Conditional Operator to setVAlue in another class:

String str = ...
Double dbl = ...
item.setValue((condition) ? str : dbl);

but compiler says:

cannot find symbol
symbol  : method setValue(java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>)

I think compiler uses the nearest common superclass (super interface) of Double and String as type of conditional Operator. but why?

like image 881
Taher Khorshidi Avatar asked Jul 26 '14 05:07

Taher Khorshidi


People also ask

What is conditional operator in Java?

The operator is applied between two Boolean expressions. It is denoted by the two OR operator (||). It returns true if any of the expression is true, else returns false. Let's create a Java program and use the conditional operator. ConditionalOperatorExample.java The meaning of ternary is composed of three parts.

What is the syntax for ternary and conditional operators in Java?

There is a specific syntax for working with ternary or conditional operators in Java. The syntax for using ternary operators is given below. Generally, a conditional operator is used within a main (), or a specific function that is used to return certain values after the condition is executed.

What are the types of operators in Java?

Operators are symbols that perform operations on variables and values. For example, + is an operator used for addition, while * is also an operator used for multiplication. Operators in Java can be classified into 5 types: 1. Java Arithmetic Operators Arithmetic operators are used to perform arithmetic operations on variables and data. For example,

How many relational operators are there in Java?

Java provides six relational operators, which are listed in below table. The outcome of these operations is a boolean value. The relational operators are most frequently used in the expressions that control the if statement and the various loop statements.


3 Answers

Because to do anything else wouldn't make any sense. The ternary conditional operator must return some value of some specific type -- all expressions must result in a specific type at compile time. Further, note that overload resolution happens at compile time, as well. The behavior you are trying to invoke here (late binding) doesn't exist in this form in Java.

The type of the expression must be compatible with the true and false subexpressions. In this case, the nearest common ancestor class is Object, and you don't have a setValue(Object) overload.

This is the simplest way to rewrite what you have in a working way:

if (condition) {
    item.setValue(str);
} else {
    item.setValue(dbl);
}

You could also provide a setValue(Object) overload that inspects the type of object passed and delegates to the appropriate setValue() overload, throwing an exception if the type is not acceptable.

like image 200
cdhowie Avatar answered Oct 11 '22 16:10

cdhowie


The Java Language Specification says

[...]

Otherwise, the second and third operands are of types S1 and S2 respectively. Let T1 be the type that results from applying boxing conversion to S1, and let T2 be the type that results from applying boxing conversion to S2. The type of the conditional expression is the result of applying capture conversion (§5.1.10) to lub(T1, T2).

In your case, let's take T1 to be String and T2 to be Double.

From the JLS, about the least upper bound (lub)

The least upper bound, or "lub", of a set of reference types is a shared supertype that is more specific than any other shared supertype (that is, no other shared supertype is a subtype of the least upper bound).

You can continue reading the JLS to workout the exact way the lub is calculated, but from the definition above we can see that what's provided in the compiler error message makes sense.

Remember, the ternary operator is used as a single expression with a single value. That value must have a type at compile time. The JLS must therefore specify rules for it.

Here's a related question/answer

  • Why doesn't the ternary operator like generic types with bounded wildcards?
like image 34
Sotirios Delimanolis Avatar answered Oct 11 '22 16:10

Sotirios Delimanolis


IF you want to go with the ternary operator only following code will solve your problem. For testing I have put false as the default value you can put your conditional expression.

public class st1 {
    public static void main (String []args) {
        Item i = new Item();
        i.setValue (false?"test":0.0);
    }
}

class Item {
    private String str;
    private double d;
    public void setValue (Object str) {
        try {
            d = Double.parseDouble (str.toString());
            System.out.printf ("Double type : %f", d);
        } catch (NumberFormatException ne) {
            this.str = str.toString();
            System.out.printf ("String type : %s", this.str);
        }
    }
}
like image 1
iammurtaza Avatar answered Oct 11 '22 18:10

iammurtaza