java - 如何将 instanceof 与 scala 对象一起使用?

标签 java scala instanceof

我有以下 Scala 层次结构:

sealed trait SessionResult[+T] {
  def toOption: Option[T]
}

object SessionResult {
  trait SessionValue[T] extends SessionResult[T] {
    def session: T
    def toOption: Option[T] = Some(session)
  }
  trait NoSessionValue[T] extends SessionResult[T] {
    def toOption: Option[T] = None
  }

  case class Decoded[T](session: T) extends SessionResult[T] with SessionValue[T]
  case class CreatedFromToken[T](session: T) extends SessionResult[T] with SessionValue[T]

  case object NoSession extends SessionResult[Nothing] with NoSessionValue[Nothing]
  case object TokenNotFound extends SessionResult[Nothing] with NoSessionValue[Nothing]
  case object Expired extends SessionResult[Nothing] with NoSessionValue[Nothing]
  case class Corrupt(e: Exception) extends SessionResult[Nothing] with NoSessionValue[Nothing]
}

但是我在 java 中使用这段代码,下面的代码无法编译:

SessionResult<SomeSession> sr = ...
System.out.println(sr instanceof NoSession)

为什么?以及如何使用 instanceof 来检查 scala 对象的类?

我得到的错误是:

Inconvertible types; cannot cast SessionResult<SomeSession> to NoSession.

最佳答案

问题在于您对通用参数设置了硬性限制 - NoSessionSessionResult[Nothing] .

因此(用 Java 的说法)SessionResult<T> 的唯一兼容变体兼容 SessionResult.NoSession$可以是SessionResult<Nothing$> .

即这将编译

public SessionResult<Nothing$> test() {

    return null;
}

public void blah() {
    if(test() instanceof SessionResult.NoSession$) {
    }
}

而例如这不会

public <T> SessionResult<T> test() {

    return null;
}

public void blah() {
    if(test() instanceof SessionResult.NoSession$) {
    }
}

幸运的是,自NoSession是一个 object ,因此您可以只引用测试单例值:

SessionResult.NoSession$.MODULE$.equals(test());

( equals 是必需的,因为您需要向上转换为 Object - 您可以手动执行此操作,但 equals 可以节省您一些时间)


或者,您可以选择性地通配泛型参数,即:

public static SessionResult<?> testYay() {
    return SessionResult.NoSession$.MODULE$;
}

public static SessionResult<?> testNay1() {
    return null;
}

public static SessionResult<?> testNay2() {
    return SessionResult.Expired$.MODULE$;
}

public static <T> SessionResult<T> testNay3() {
    return null;
}

public static void blah() {
    //prints true
    System.out.println(testYay() instanceof SessionResult.NoSession$);
    //prints false
    System.out.println(testNay1() instanceof SessionResult.NoSession$);
    //prints false
    System.out.println(testNay2() instanceof SessionResult.NoSession$);
    //prints false (and compiles)
    System.out.println((SessionResult<?>) testNay3() instanceof SessionResult.NoSession$);
}

这是一个非常 hacky 的解决方案,但对于在 Java 中主要处理此类相等性检查的代码来说可能是最方便的。如 testNay3 中所示,您可以通过简单的就地强制转换以这种方式限制使用泛型类型的“附带损害”。

编辑: 根据 Alexey's 更改为通配符提示。

关于java - 如何将 instanceof 与 scala 对象一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45216479/

相关文章:

java - 如何使用基于java的配置将队列绑定(bind)到交换

java - 如何在 Spring 框架中使用 Apache 的 MultiKeyMap

Scala 映射与 Either

scala - Spark : How to get the latest file from s3 in the last 10 days

java优化挑剔: is it faster to cast something and let it throw exception than calling instanceof to check before cast?

java - USB主机传输Android与Spartan 6 FPGA

scala - 在 FP 中处理 POST 的*正确*方法是什么?

java - 当派生类主要用于扩展状态而不是行为时,如何动态获取继承层次结构中的子类?

typescript - 通过扩展和实现的组合理解 TS 的类型推断/缩小

java - Java中将json字符串连接成json对象