Scala: Overwriting a Generic Java Method that returns null
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 - ie, 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);
}
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.
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)
上一篇: 从宏中获取具有匿名类方法的结构类型