문제

I have the following code,

class Foo<K> {

    public <T> T createK() {
        return null;
    }

    public void foo() throws ClassNotFoundException {
        K k = (1==1)?null:createK();
    }
}

However, it didn't compile. It caused the following compilation error (Oracle Java 7) on the line with the conditional operator:

Type mismatch: cannot convert from Object to K

When I rewrite the foo() method as follows,

public void foo() throws ClassNotFoundException {
    K k = null;
    if (1==1)
        k = null;
    else
        k = createK();
}

Then it compiles fine. How is this caused and how can I solve it?

도움이 되었습니까?

해결책

Although the conditional operator is not exactly same as if-else conditional, but this is a different issue.

This is a known bug with type inference of generic type parameter with conditional operator which doesn't work as expected.

The solution is to provide explicit type argument:

K k1 = (1==1) ? null : this.<K>createK(); 

...this would work, however with compiler warning - Dead Code (of course, due to 1 == 1 part). Note, how we need to explicit use this to invoke the method with explicit type argument. Simply doing <K>createK() won't work.

Adding the explicit type argument with method invocation - this.<K>createK(); forces the type T to be inferred as K, which is otherwise inferred as Object.


However, I suspect that your doubt is really related to the type inference. It's just a coincidence that the issue came out to be that. Even though, to get some idea about how conditional operators work in different situations, and what the type of its result is, you can schedule a visit to JLS §15.25 - Conditional Operator

다른 팁

No, the ternary (i.e. the ? :) is a very different beast from if ... then ... else.

The ternary is an operator and the two alternatives have to be expressions evaluating to the same type.

if ... then ... else is a convenient programming construct; the bits in between are statements not expressions.

In fact, the entire ternary construct is an expression, whereas the if ... then ... else is itself a statement. (You can assign a value to a ternary; e.g. foo = ... ? ... : ... but foo = if ... then ... else is meaningless and therefore syntatically invalid.)

Your code does not compile because the types of both sides of a conditional expression must match. There is no such requirement for the if statement - in fact, there is no requirement for the two parts to be related to each other in any way, let alone assigning the same variable.

Adding a cast fixes your conditional (demo on ideone):

K k = (1==1)?null:(K)createK();

Those operators are different.

1) In case of if ... then ... else there is no limitations of actions

2) Ternary operator. Using that both sides must have the same type.

You can fix everything with cast:

K k = (1 == 1) ? null : (K)(createK());

Using condition ? valueA : valueB operator is meaningful only if there is an Lvalue,

Lvalue = condition ? valueA : valueB

The exact meannig of this operator can be transformed to an if else statement:

int y,z;

int x= (y==0) ? y+1 : z+3

this ends up to be the same as:

if(y==0)
{
    x=y+1;
}else
{
    x = z+3;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top