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)

链接地址: http://www.djcxy.com/p/86198.html

上一篇: 从宏中获取具有匿名类方法的结构类型

下一篇: Scala:覆盖返回null的通用Java方法