Expression of type Null doesn't conform to expected type T
I need to override the following Java method in a Scala class:
public class Test<T> {
public T test(T o, boolean x) {
if (x) {
return o;
}
return null;
}
}
With the following approach (in Scala), the compiler complains, “Expression of type Null doesn’t conform to expected type T”:
class Test2[T] extends Test[T] {
override def test(o: T, x: Boolean): T = {
if (x) {
return o
}
return null
}
}
I’ve also tried to define Option[T] as return value, but then again, the compiler complains that the method signatures wouldn’t match.
Any idea? - Thanks!
Edit:
Daniel’s suggestion works for the problem as originally posted; however, my actual problem unfortunately still differs slightly (by having the generic type parameter in the method, not class, definition) (sorry):
Java:
public class Test {
public <T> T test(T o, boolean x) {
if (x) {
return o;
}
return null;
}
}
Scala:
class Test2 extends Test {
override def test[T >: Null](o: T, x: Boolean): T = {
if (x) {
return o
}
return null
}
}
Compilation again fails with the error, “Expression of type Null doesn’t conform to expected type T”.
(I believe that’s because the override does not cover any possibilities - i.e., something of type Nothing could be passed to Test.test(…) - well, could it? ? )
What does work is throwing a RuntimeException instead of returning null as Ricky suggested; nonetheless, I’d be grateful for further input.
Thanks all!
解决方法
You need this:
class Test2[T >: Null] extends Test[T] {
The problem is that Nothing cannot be null, and, being the subtype of everything, it is a valid value of T. So you need to specify Null as the lower bound.
EDIT
Unfortunately, there’s no good way around your actual problem. In this case, you’ll have to write null.asInstanceOf[T] and leave it at that.
And, yes, you can call it with non-nullable types. Try this, for example:
object Test3 {
val test = new Test();
val x: Int = test.test(5, false);
}
That’s the perfect solution for the problem as originally posted; however, I had to find out that the actual problem slightly differs. - I’ll mark this as the solution if there shouldn’t be a more accurate answer, but could you please look once more into the - now edited - question. - Thanks very much. – robbbert Jun 21 ‘11 at 20:02 Thanks, well done. - Both solution work (the second one using [T] as type parameter), although I yet don’t fully understand the issue … – robbbert Jun 22 ‘11 at 12:17 @robbbert Search for information on Nothing and Null to understand it better. – Daniel C. Sobral Jun 22 ‘11 at 16:11
|
T is unrestricted, so it can be any type including Int, Double, Float or other subtypes of AnyVal which cannot be null.
You probably want class Test2[T <: AnyRef] rather than class Test[T], declaring that T is any type that is AnyRef (basically java.lang.Object) or any subtype thereof.
In general, try to return something more useful than null, or throw an exception. There may be cases where you have to do it because of some third party API, but if that isn’t the case, see if there’s a better way. null doesn’t appear in the method’s type, whereas Option does, for instance.
this answer edited Jun 21 ‘11 at 17:45 oxbow_lakes 94.2k 37 263 411 answered Jun 21 ‘11 at 17:16 Ricky Clarkson 2,227 1 12 20 That’s what I thought, but def z[T <: AnyRef]: T = null still doesn’t compile. – kassens Jun 21 ‘11 at 17:19 class Test2[T <: AnyRef] extends Test[T] should compile just fine – oxbow_lakes Jun 21 ‘11 at 17:47 @oxbow_lakes No, it doesn’t, Daniel’s answer is correct. – kassens Jun 21 ‘11 at 18:08 The [T <: AnyRef] does not compile; however, throwing a RuntimeException would work well from a practical point of view. - Moreover, I’ve slightly edited the original question. - If you’d have any more ideas, I’d be grateful. - Thanks! – robbbert Jun 21 ‘11 at 20:05
|
Have you considered using Option instead following will work:
class Test{
def test[T] (value:T,flag :Boolean) :Option[T] = {
if (flag){
Some(value)
}else{
None
}
}
}
It will help to distinguish situations like test(null,true) and test(null,false)
还没有评论,来说两句吧...