将Scala单元转换为Java Void

将Scala单元转换为Java Void,java,scala,type-conversion,typesafe,Java,Scala,Type Conversion,Typesafe,我有一个Java类,它接受函数[String,Void],类似于消费者函数接口。我从Scala代码中调用这个Java函数。正如您在下面看到的,我接受Scala端的函数:=>Unit,因为它是等效的。当我尝试应用此函数代替Void返回类型不匹配时。显式强制转换.asInstanceOf[Void]也引发了异常。如何将=>单元转换为=>无效 // Java class AcceptFunction { public void temp(Function<String, Void>

我有一个Java类,它接受
函数[String,Void]
,类似于
消费者
函数接口。我从Scala代码中调用这个Java函数。正如您在下面看到的,我接受Scala端的
函数:=>Unit
,因为它是等效的。当我尝试应用此函数代替
Void
返回类型不匹配时。显式强制转换
.asInstanceOf[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
   })
}
//Java
类接受函数{
公共真空温度(功能f){
f、 申请(“你好”);
}
}
//斯卡拉
def温度(f:String=>单位):单位={
new AcceptFunction().temp(新函数[String,Void](){
覆盖def apply(t:String):Void=f(t)/您应该使用not
函数
类型,因为您的
函数
没有输出,并且
消费者
用于此场景。例如:

class AcceptFunction {
   public void temp(Consumer<String> f) { // Consumer for no output Function
      f.accept("Hello");
   }
}
def temp(f: String => Unit): Unit = {
   new AcceptFunction().temp(new Consumer[String]() {
   override def accept(t: String): Unit= f(t)    
   })
}
类接受函数{
public void temp(Consumer f){//无输出函数的Consumer
f、 接受(“你好”);
}
}
def温度(f:String=>单位):单位={
新的AcceptFunction().temp(新的使用者[字符串](){
覆盖def接受(t:字符串):单位=f(t)
})
}
显然

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.
scala>newjfunc.Acceptor().f(s=>println(s))
:12:错误:类型不匹配;
发现:单位
必填项:无效
新的jfunc.Acceptor().f(s=>println(s))
^
scala>new jfunc.Acceptor().f{s=>println(s);null}
你好,世界。
java与您展示的一样:

package jfunc;

import java.util.function.*;

public class Acceptor {
  public void f(Function<String, Void> g) { g.apply("hello, world."); }
}
包jfunc;
导入java.util.function.*;
公共类接受者{
公共空间f(函数g){g.apply(“你好,世界”);}
}
它是:

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
scala>:javap-c-
公共静态final java.lang.Void$anonfun$res0$1(java.lang.String);
代码:
0:getstatic#33//字段scala/Predef$.MODULE$:Lscala/Predef$;
3:aload_0
4:invokevirtual#37//方法scala/Predef$.println:(Ljava/lang/Object;)V
7:aconst_null
8:轮到你了
公共$line3.$read$$iw$$iw$();
代码:
0:aload_0
1:invokespecial#39//方法java/lang/Object。“:()V
4:aload_0
5:putstatic#41//字段模块$:L$line3/$read$$iw$$iw$;
8:aload_0
9:新的#43//jfunc类/接受器
12:dup
13:invokespecial#44//方法jfunc/Acceptor.“:()V
16:invokedynamic#63,0//invokedynamic#0:apply:()Ljava/util/function/function;
21:invokevirtual#67//方法jfunc/Acceptor.f:(Ljava/util/function/function;)V
24:getstatic#72//字段scala/runtime/BoxedUnit。单位:Lscala/runtime/BoxedUnit;
27:putfield#74//Field res0:Lscala/runtime/BoxedUnit;
30:返回

我有一个Java类,它接受
函数[String,Void]
,类似于
消费者
函数接口

那么这个类应该使用
Consumer
。首先,近似地说,
Function
从来都不是正确的类型。如果您不能更改它,至少要知道它是一个糟糕的设计,并且要小心使用这个库。Som snytt的回答已经说明了如何从Scala正确调用
temp
,编写impl很简单如果需要,将icit从
String=>Unit
转换为
函数[String,Void]
。因此,下面的答案是关于其他尝试失败的原因

因为它是等效的

准确地说:它相当于
void
,而不是
void
。等效的Java代码将调用
void
方法,例如
消费者。接受

public void tempOfVoid(Consumer<String> f) {
    temp(new Function<String, Void> {
        public Void apply(String x) {
            return f.accept(x);
        }
    };
}
正如som snytt的答案在Scala中所示


现在,您可以问:
Unit
是类型参数时会发生什么,因为
void
不能是,或者当类型
Unit
的值需要在运行时表示时(例如
valx:Any=()
)?在这些情况下,
Unit
scala.runtime.BoxedUnit
类表示,正如
Int
通常被转换为
Int
,但有时转换为
java.lang.Integer
。这解释了为什么强制转换为
Void
会引发异常(并且不会导致编译错误).
Void
不适合这些情况,因为它没有(非
null
)值,而
Unit
只有一个值:
()

你的意思是
。asInstanceOf[(String)=>Void]
?cf“我有一个Java类,它接受函数[String,Void],这类似于消费者函数接口。”那么这个类应该使用
消费者
。如果您不能更改它,至少要知道它是一个糟糕的设计,并小心使用这个库。“因为它是等效的”是的,它相当于
void
,而不是
void
。因此,如果使用返回
void
@AlexeyRomanov的Java方法,则会出现类型不匹配。我想了解互操作性,但我太懒了,我不需要它。我怀疑string=>单元应该很简单。也许你的答案应该是规范的?@som-snytt我已经把它扩展到了一个答案。谢谢你注意到这一点。我很好奇为什么上面的实现不起作用。
        public Void apply(String x) {
            f.accept(x);
            return null;
        }