2

Suppose I have

val a: Option[String] = None
someJavaFunction(a)

And then in the java file, I want to do something like this:

public someJavaFunction(Option<String> o) {
  o.orNull();
}

The signature of orNull, however, is this:

orNull [A1 >: A](implicit ev : <:<[Null, A1]) : A1

So from Java, I'd need to supply this evidence function that is usually magicked in by Scala (from I know not where). How might I get hold of the evidence value to pass in here?

This is clearly not sensible.

Is it possible?

MHarris
  • 1,801
  • 3
  • 21
  • 34
  • 2
    http://stackoverflow.com/questions/7808821/java-calling-scala-case-class-w-implicit-parameter – user3707125 Jan 04 '16 at 16:31
  • A possibly could be to simply pass `null`, but that doesn't seem very clean. `o.orNull(null)`. – Clashsoft Jan 04 '16 at 16:31
  • @user3707125 Thanks for the pointer. I know how to pass the parameter - the question is, what do I pass in? – MHarris Jan 04 '16 at 17:01
  • @Clashsoft Good idea - unfortunately, that results in an NPE, looks like the implementation of orNull is using the evidence parameter. – MHarris Jan 04 '16 at 17:06

1 Answers1

2

The <:< class is defined in scala.Predef and normally it's scala.Predef.conforms() that gives you an instance in Scala. So you could do something like

public class Foo {
  public static String foo(scala.Option<String> o) {
    return o.orNull(
      (scala.Predef.$less$colon$less< scala.runtime.Null$ , String >)
      (Object)scala.Predef.conforms()
    );
  }
}

which gives an unchecked operation warning, but works.

You can also create an instance of scala.Predef.$less$colon$less that does the right thing (just returns its argument), and there the cast goes through without warning.

Note: you must leave a space after Null$ or javac gets confused.

Rex Kerr
  • 166,841
  • 26
  • 322
  • 407