views:

122

answers:

1

In Scala, there are metaobjects like java.lang.Class and java.lang.reflect.Method. But what metaobject exists for traits?

class Foo {
  def foo = "foo"
}

var obj = classOf[Foo]

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

It prints interface. What is this?

+5  A: 

The output above comes as a surprise to me - it should print a class. Unless you wanted to declare trait Foo. What Scala version are you using?

The nightly gives the following as the output:

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

In the Scala JVM implementation Scala classes are usually translated into a JVM bytecode class. If a trait consists only of method declarations like here:

trait Foo {
  def foo: String
}

a Java interface Foo is generated by the compiler.

If it has definitions as well, like here:

trait Foo {
  def foo = "foo"
}

the compiler will generate an interface Foo and a so-called implementation class with the name Foo$class which contains the actual method bodies. This implementation class is not visible to the programmer. It is used for mixin-composition under the hood.

In both cases, if you use classOf construct to obtain the Class object of a trait, you will get the standard Java class object for the interface of the trait Foo, which you can use to inspect the methods of Foo in the same way as you would do it for classes.

axel22
Foo$class is actually attainable through some trickery like:classOf[Foo].getClassLoader.getClass("Foo$class"). But in general the answer is spot on.
jsuereth
Nice, haven't thought about that.
axel22