scala方法isAnonymousClass返回false

时间:2014-03-20 19:02:25

标签: scala

我使用new {...}定义了一个匿名类但是当我尝试打印isAnonymousClass而不是返回true时,返回false这里有什么错误

scala> trait An{}
defined trait An

scala> val isAn = new An{}
isAn: An = $anon$1@2731370f

scala> println(isAn.getClass.isAnonymousClass)
false

2 个答案:

答案 0 :(得分:2)

代码示例:

package scala.tools.nsc
package interpreter

import scala.reflect.{ ClassTag, classTag }

class RichClass[T](val clazz: Class[T]) {
  def toTag: ClassTag[T] = ClassTag[T](clazz)

  // Sadly isAnonymousClass does not return true for scala anonymous
  // classes because our naming scheme is not doing well against the
  // jvm's many assumptions.
  def isScalaAnonymous = (
    try clazz.isAnonymousClass || (clazz.getName contains "$anon$")
    catch { case _: java.lang.InternalError => false }  // good ol' "Malformed class name"
  )

编辑:

如果isAnonymousClass抛出,您似乎希望退回到Scala名称测试。

调整名称测试并不是一件容易的事情,除非要删除封闭的类,这似乎是安全的。

  def isAnon(k: Class[_]) = {
    def klass = k.getEnclosingClass.getName
    val encl  = Option(k.getEnclosingMethod) orElse Option(k.getEnclosingConstructor)
    encl map (_ => k.getName drop klass.length match {
      case "" => true
      //case r  => (r dropWhile (_ == '$')).startsWith("anon$")  // nope
      case r  => List("$anon$", "$anonfun$") exists (r contains _)
    }) getOrElse false
  }

封闭类(由getEnclosingClass报告)并不总是正确的:

  Console println isAnon {
    object X { class Y; def y = new Y { class Z ; def z = new Z() } } ; X.y.z.getClass
  }

命名的类Z或isanon.Test$X$9$$anon$4$Z由对象isanon.Test$X$9$包围,而不是由Y的匿名子类包围。

在这种情况下,$anon$4是封闭器,Z是命名的内部类。

可以通过检测模式等来解决这个问题。

答案 1 :(得分:1)

有一个关于此问题的Scala bug raised,但它已被关闭,所以似乎不太可能修复此问题,因为您希望它能够在短时间内发挥作用。

与此同时,您可以使用@ som-snytt建议的类名检查,或者(我在这里支持downvote-oblivion)你可能能够使用{ {1}}而是? 请注意这里的区别:

isLocalClass