【问题标题】:Using Option[Boolean] from Java使用 Java 中的 Option[Boolean]
【发布时间】:2018-08-30 22:24:33
【问题描述】:

我有一个带有返回 Option[Boolean] 的方法的 Scala Trait。我想编写一个实现此特征的 Java 类。不幸的是,编译器抱怨以下代码:

trait WithBoolean {
  def doSth(): Option[Boolean]
}

public class MyClass implements WithBoolean {
  @Override
  public Option<Boolean> doSth() {
    return null;
  }
}

编译错误是:

doSth() in MyClass cannot implement doSth() in WithBoolean
public Option<Boolean> doSth() {
                       ^
return type Option<Boolean> is not compatible with Option<Object>

如果我稍微更改代码,它确实可以编译:

public class MyClass implements WithBoolean {
  @Override
  public Option<Object> doSth() {  //return type has been changed to Object
    return null;
  }
}

但这显然不是一个好的解决方案。为了能够使用正确的返回类型,我需要进行哪些更改?

【问题讨论】:

    标签: java scala


    【解决方案1】:

    我现在无法对此进行测试,但我最好的猜测是您混淆了一些 imports,因此尝试用 Option&lt;java.lang.Boolean&gt; 覆盖 Option&lt;scala.Boolean&gt;

    【讨论】:

    • 除了import scala.Option;之外没有导入
    • 在这种情况下,Java 代码中不合格的Boolean 将引用java.lang.Boolean,这与您的Scala 界面中的scala.Boolean 完全无关。
    • 而且 scala.Boolean 不能从 Java 中使用,所以 Java 看到的类型 Option 很遗憾。
    • @AlexeyRomanov:啊,对,scala.Boolean 实际上并不存在,因为它是一个fictional class invented by the compiler,给人一种原始bool 是一个对象的错觉。
    【解决方案2】:

    你可以试试

    public class MyClass implements WithBoolean {
      @Override
      public Option<? super Boolean> doSth() {
        return null;
      }
    }
    

    【讨论】:

    • @user3346601 很抱歉听到这个消息:(
    【解决方案3】:

    你可以试试这个:

    (value != null)?new Some<T>(value):scala.Option.apply((T) null);
    
    (value != null)?new Some<Boolean>(value):scala.Option.apply((Boolean) null);
    

    【讨论】:

      【解决方案4】:

      来自类描述:

      Boolean(相当于 Java 的 boolean 原始类型)是 [[scala.AnyVal]] 的子类型。 Boolean 的实例不由底层运行时系统中的对象表示。

      Java Boolean 扩展 AnyRef(有关此 here 的更多信息)。
      AnyRefAnyVal 都扩展了 Any,相当于 java.lang.Object
      这就是为什么只有 Option&lt;Object&gt; 有效。

      如果你想要类型安全,你可以这样做:

      trait WithBoolean {
        def doSth(): Option[Boolean]
      }
      
      abstract class WithBooleanForJava extends WithBoolean {
      
        override def doSth(): Option[Boolean] = doSthJava().map(Boolean.box(_))
      
        def doSthJava(): Option[java.lang.Boolean]
      }
      

      所以你的 java 类看起来就像你想要的那样:

      public class MyClass extends WithBooleanForJava {
      
          @Override
          public Option<Boolean> doSthJava() {
              return null;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2013-06-15
        • 2021-03-15
        • 2018-03-24
        • 2011-09-07
        • 2022-12-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-02
        相关资源
        最近更新 更多