【问题标题】:Scala: Metaobject for traitsScala:特征的元对象
【发布时间】:2010-09-29 12:58:45
【问题描述】:

在 Scala 中,有像 java.lang.Classjava.lang.reflect.Method 这样的元对象。但是对于特征存在什么元对象?

class Foo {
  def foo = "foo"
}

var obj = classOf[Foo]

obj // java.lang.Class[Foo] = interface Foo

打印界面。这是什么?

【问题讨论】:

  • Err... scala 2.8.0.final 打印 java.lang.Class[Foo] = class Foo

标签: scala metaprogramming


【解决方案1】:

上面的输出让我吃惊——它应该打印一个类。除非你想声明trait Foo。您使用的是哪个 Scala 版本?

nightly 给出以下输出:

Welcome to Scala version 2.9.0.r23117-b20100929093241 (Java HotSpot(TM) Server VM, Java 1.6.0_20).
Type in expressions to have them evaluated.
Type :help for more information.

scala> class Foo {
     | def foo = "foo"
     | }
defined class Foo

scala> var obj = classOf[Foo]
obj: java.lang.Class[Foo] = class Foo

在 Scala JVM 实现中,Scala 类通常被翻译成 JVM 字节码类。如果一个 trait 只包含像这里这样的方法声明:

trait Foo {
  def foo: String
}

编译器生成一个Java接口Foo

如果它也有定义,就像这里:

trait Foo {
  def foo = "foo"
}

编译器将生成一个接口Foo 和一个名为Foo$class 的所谓实现类,其中包含实际的方法体。这个实现类对程序员是不可见的。它用于底层的 mixin-composition。

在这两种情况下,如果你使用classOf构造来获取一个trait的Class对象,你会得到一个用于traitFoo接口的标准Java类对象,你可以用它来检查它的方法Foo 和上课一样。

【讨论】:

  • Foo$class 实际上可以通过一些诡计来实现,例如:classOf[Foo].getClassLoader.getClass("Foo$class")。但总的来说,答案是正确的。
  • 不错,没想到。
猜你喜欢
  • 2015-05-26
  • 2017-10-25
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 2012-12-11
  • 2018-03-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多