Search code examples
javascalatype-conversiontypesafe

Convert Scala Unit to Java Void


I have a Java class which takes Function[String, Void], which is similar to Consumer functional interface. I am calling this Java function from Scala code. As you can see below, I accept function: => Unit on Scala side as it is void equivalent. When I attempt to apply this function in place of Void return type type mismatch happens. Explicit casting of .asInstanceOf[Void] also threw an exception. How do we convert => Unit to => Void?

// Java 
class AcceptFunction {
   public void temp(Function<String, Void> f) {
      f.apply("Hello");
   }
}

// Scala
def temp(f: String => Unit): Unit = {
   new AcceptFunction().temp(new Function[String, Void]() {
   override def apply(t: String): Void = f(t) // <===== error expecting Void instead of Unit
   })
}

Solution

  • Apparently,

    scala> new jfunc.Acceptor().f(s => println(s))
    <console>:12: error: type mismatch;
     found   : Unit
     required: Void
           new jfunc.Acceptor().f(s => println(s))
                                              ^
    
    scala> new jfunc.Acceptor().f { s => println(s) ; null }
    hello, world.
    

    where the java is like you show:

    package jfunc;
    
    import java.util.function.*;
    
    public class Acceptor {
      public void f(Function<String, Void> g) { g.apply("hello, world."); }
    }
    

    it does:

    scala> :javap -c -
      public static final java.lang.Void $anonfun$res0$1(java.lang.String);
        Code:
           0: getstatic     #33                 // Field scala/Predef$.MODULE$:Lscala/Predef$;
           3: aload_0
           4: invokevirtual #37                 // Method scala/Predef$.println:(Ljava/lang/Object;)V
           7: aconst_null
           8: areturn
    
      public $line3.$read$$iw$$iw$();
        Code:
           0: aload_0
           1: invokespecial #39                 // Method java/lang/Object."<init>":()V
           4: aload_0
           5: putstatic     #41                 // Field MODULE$:L$line3/$read$$iw$$iw$;
           8: aload_0
           9: new           #43                 // class jfunc/Acceptor
          12: dup
          13: invokespecial #44                 // Method jfunc/Acceptor."<init>":()V
          16: invokedynamic #63,  0             // InvokeDynamic #0:apply:()Ljava/util/function/Function;
          21: invokevirtual #67                 // Method jfunc/Acceptor.f:(Ljava/util/function/Function;)V
          24: getstatic     #72                 // Field scala/runtime/BoxedUnit.UNIT:Lscala/runtime/BoxedUnit;
          27: putfield      #74                 // Field res0:Lscala/runtime/BoxedUnit;
          30: return