[英]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.
問題在於您對通用參數設置了嚴格的限制NoSession
是SessionResult[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.