GeeCON Prague 2014*
The moose likes Java in General and the fly likes Generics, type inferrence, and the ternary operator; strange error Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


JavaRanch » Java Forums » Java » Java in General
Bookmark "Generics, type inferrence, and the ternary operator; strange error " Watch "Generics, type inferrence, and the ternary operator; strange error " New topic
Author

Generics, type inferrence, and the ternary operator; strange error

Garrett Rowe
Ranch Hand

Joined: Jan 17, 2006
Posts: 1296
Hope this example isn't too cryptic. I tried to reproduce the error with as little code as possible but its still a little verbose.

The code compiles without warning as written, but if i comment out the if/else statements and uncomment the *equivalent* statement using the ternary operator I get a compiler error:

Type mismatch: Cannot convert from StrangeGenericsError.Option<Object> to StrangeGenericsError.Option<T>

Anyone know why the ternary option cannot be used in this instance?
[ December 30, 2006: Message edited by: Garrett Rowe ]

Some problems are so complex that you have to be highly intelligent and well informed just to be undecided about them. - Laurence J. Peter
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18570
    
    8

Let me give it a try: you have type parameters in those two methods (the <T> that comes right after the "static" declaration). But you don't use them when you call them from your third method, so I'm guessing that they default to <Object>. That would explain the error message you're getting. I don't understand why you only get it with the ternary expression, I would have thought it would apply to all unparametrized instances of the calls to the first two methods.

This may be something that works differently in different compilers (e.g. Eclipse's versus Sun's). Unfortunately I don't have access to my computer that has Java 5 on it just now so I can't try it out.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Not that the T in the class declaration and the T in the declaration of the static methods are *not* the same.

Originally posted by Paul Clapham:
I don't understand why you only get it with the ternary expression, I would have thought it would apply to all unparametrized instances of the calls to the first two methods.


Because if the method call is used *directly* as the return expression, the compiler can infer the type argument.

So the compiler kind of thinks "I don't have a type argument for this call, but it's used in a return statement, so it should be compatible to the return type."

Whereas the same is not true for the ternary operator: "I don't have a type argument for this method call, and I'm inside a ternary operator. Mhh, no choice but use Object as the type argument. Now the type of the ternary expression is Option<Object>, but I need to return an Option<T>. That's not possible, I'll have to report an error..."


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Garrett Rowe
Ranch Hand

Joined: Jan 17, 2006
Posts: 1296
you have type parameters in those two methods (the <T> that comes right after the "static" declaration). But you don't use them when you call them from your third method, so I'm guessing that they default to <Object>.

The parameterized type should be inferred by the type of the reference it is assigned to. I'm not sure if I'm phrasing that right but here is what I mean in code; a main method can be added to the class:


This may be something that works differently in different compilers (e.g. Eclipse's versus Sun's). Unfortunately I don't have access to my computer that has Java 5 on it just now so I can't try it out.


Well I tried it using Sun's compiler and got a similar compilation error:
C:\~\StrangeGenericsError.java:43: incompatible types
found : StrangeGenericsError.Option<java.lang.Object>
required: StrangeGenericsError.Option<T>
return arg == null ? alwaysChooseOne() : alwaysChooseTwo();
^
1 error

Tool completed with exit code 1

[ December 31, 2006: Message edited by: Garrett Rowe ]
Garrett Rowe
Ranch Hand

Joined: Jan 17, 2006
Posts: 1296
Not[e] that the T in the class declaration and the T in the declaration of the static methods are *not* the same.
Yeah, I should have used a different letter to make that more obvious.

...So the compiler kind of thinks "I don't have a type argument for this call, but it's used in a return statement, so it should be compatible to the return type."

Whereas the same is not true for the ternary operator: "I don't have a type argument for this method call, and I'm inside a ternary operator. Mhh, no choice but use Object as the type argument. Now the type of the ternary expression is Option<Object>, but I need to return an Option<T>. That's not possible, I'll have to report an error..."


I think I get this. Since the call to the method is used directly in the return statement, the type can be inferred, however using the ternary operator, the entire ternary statement gets evaluated first, and since there is not a type to infer yet the expression defaults to Option<Object> then when the compiler *sees* that the return type is an Option<T> and not an Option<Object> it reports an error. Is that kind of what you were saying?
[ December 31, 2006: Message edited by: Garrett Rowe ]
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Garrett Rowe:

Is that kind of what you were saying?


Exactly!
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
 
subject: Generics, type inferrence, and the ternary operator; strange error