[英]Scala: Why asInstanceOf can accept a type parameter but isInstanceOf can not?
[英]Why there is a ClassCastException when isInstanceOf returns true on a scala type with wildcard parameter?
我的問題是:
控制台輸出:
Welcome to Scala version 2.10.0 (Java HotSpot(TM) Client VM, Java 1.6.0_35).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import reflect.runtime.{universe => ru}
import reflect.runtime.{universe=>ru}
scala> val t = ru.typeOf[Option[_]]
t: reflect.runtime.universe.Type = scala.Option[_]
scala> t.isInstanceOf[ru.TypeRef]
<console>:10: warning: abstract type reflect.runtime.universe.TypeRef is unchecked since it is eliminated by erasure
t.isInstanceOf[ru.TypeRef]
^
res0: Boolean = true
scala> t.asInstanceOf[ru.TypeRef]
res1: reflect.runtime.universe.TypeRef = scala.Option[_]
scala> t.asInstanceOf[ru.TypeRef].args
java.lang.ClassCastException: scala.reflect.internal.Types$ExistentialType cannot be cast to scala.reflect.api.Types$TypeRefApi
at .<init>(<console>:10)
at .<clinit>(<console>)
at .<init>(<console>:7)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:731)
at scala.tools.nsc.interpreter.IMain$Request.loadAndRun(IMain.scala:980)
at scala.tools.nsc.interpreter.IMain.loadAndRunReq$1(IMain.scala:570)
at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:601)
at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:565)
at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:745)
at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:790)
at scala.tools.nsc.interpreter.ILoop.command(ILoop.scala:702)
at scala.tools.nsc.interpreter.ILoop.processLine$1(ILoop.scala:566)
at scala.tools.nsc.interpreter.ILoop.innerLoop$1(ILoop.scala:573)
at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:576)
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply$mcZ$sp(ILoop.scala:867)
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:822)
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:822)
at scala.tools.nsc.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:135)
at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:822)
at scala.tools.nsc.interpreter.ILoop.main(ILoop.scala:889)
at org.jetbrains.plugins.scala.compiler.rt.ConsoleRunner.main(ConsoleRunner.java:64)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.CommandLineWrapper.main(CommandLineWrapper.java:121)
TypeRef
是抽象類型,因此將其擦除到上限。 通常,這意味着不可能進行可靠的isInstanceOf
和模式匹配(最終依賴於此)。
但是,由於反射API廣泛使用抽象類型,因此我們建立了一種特殊的機制,以基於類標記對抽象類型的實例進行模式匹配。 如果在范圍內您具有與抽象類型相對應的類標記,則所有內容均可靠運行。
自然地,我們提供了捆綁在Universe中的一堆類標簽,幾乎每個抽象類型一個。 要注意的是,您確實需要導入這些類標記。 通常這不是問題,因為幾乎每個人都import ru._
,但是在這種情況下會出現。 我們認為這是一個問題,但仍有待解決。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.