簡體   English   中英

如何在scala對象中使用instanceof?

[英]How to use instanceof with scala object?

我有以下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.NoSession$兼容的SessionResult<T>的唯一兼容變體可以是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$);
}

這是一個非常棘手的解決方案,但對於大多數處理Java中的這種相等性檢查的代碼來說,這可能是最方便的。 testNay3 ,您可以通過簡單的就地強制轉換來限制使用泛型類型的“附帶損害”。

編輯: 根據Alexey的提示更改為通配符。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM