Scala: Как получить класс композиции миксин? - PullRequest
10 голосов
/ 31 января 2010
scala> import java.util.Properties
import java.util.Properties

scala> trait Foo extends Properties
defined trait Foo

scala> classOf[Foo]
res0: java.lang.Class[Foo] = interface Foo

scala> class FooP extends Foo
defined class FooP

scala> classOf[FooP]
res1: java.lang.Class[FooP] = class FooP

scala> classOf[Properties with Foo]
<console>:7: error: class type required but java.util.Properties with Foo found
       classOf[Properties with Foo]
               ^

scala> new Properties with Foo
res2: java.util.Properties with Foo = {}

scala> res2.getClass
res3: java.lang.Class[_] = class $anon$1

Есть ли способ получить класс 'Properties with Foo' без создания экземпляра или нового класса?

Ответы [ 4 ]

7 голосов
/ 31 января 2010

classOf[X] работает, только если X соответствует физическому классу. T with U является составным типом и не соответствует классу.

Вы можете использовать Манифесты, чтобы определить удаление типа. Тип стирания T with U равен T.

scala> trait T
defined trait T

scala> trait U
defined trait U

scala> manifest[T with U]
res10: Manifest[T with U] = T with U

scala> manifest[T with U].erasure
res11: java.lang.Class[_] = interface T

Здесь вы можете видеть, что List[Int] и List[_] имеют одинаковое стирание:

scala> classOf[List[_]]
res13: java.lang.Class[List[_]] = class scala.collection.immutable.List

scala> classOf[List[Int]]
res14: java.lang.Class[List[Int]] = class scala.collection.immutable.List

scala> classOf[List[Int]] == classOf[List[_]]
res15: Boolean = true
1 голос
/ 31 января 2010

Нет, это невозможно, потому что "X с Y" - это анонимное определение в вашем примере.Это, конечно, не так для «класса X расширяет Z на Y».

0 голосов
/ 13 июля 2010

Я не уверен, что именно вы пытаетесь сделать с составным классом, но вы можете получить список реализованных интерфейсов и суперкласс данного анонимного класса, что может быть достаточно. Например:

trait X
trait Y
class Foo
val bar = new Foo with X with Y
val barClass = bar.getClass // class $anon$1
barClass.getInterfaces // Array(interface X, interface Y)
barClass.getSuperclass // class Foo
0 голосов
/ 09 февраля 2010

Вы не можете получить литерал класса, но вы можете проверить, соответствует ли объект этому типу двумя различными способами:

trait X
trait Y

val xy: AnyRef = new X with Y
val zz: AnyRef = new Object with X

xy.isInstanceOf[X with Y] // true
zz.isInstanceOf[X with Y] // false

xy match { case a: X with Y => true; case _ => false} // true
zz match { case a: X with Y => false; case _ => false} // false

Это очень похоже на это общее объявление в Java

public <T extends Comparable<T> & Serializable> T id(T t) { return t; }

Этот метод стирается до

public Comparable id(Comparable t) { return t; }

Однако в Java вы не можете сказать xy instanceof (X&Y), но на самом деле это то же самое, что xy instanceof X && xy instanceof Y

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...