Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala: Overwriting a Generic Java Method that returns null

Tags:

scala

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!

like image 515
robbbert Avatar asked Jun 21 '11 16:06

robbbert


1 Answers

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);
}
like image 111
Daniel C. Sobral Avatar answered Nov 04 '22 13:11

Daniel C. Sobral