2010-01-31 10 views
10
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 

¿Hay alguna forma de obtener la clase de 'Propiedades con Foo' sin crear una instancia o clase nueva?Scala: ¿Cómo obtener la clase de composición de mixina?

Respuesta

7

classOf[X] solo funciona si X corresponde a una clase física. T with U es un tipo compuesto, y no corresponde a una clase.

Puede usar Manifests para determinar el borrado de un tipo. El borrado de tipo de T with U es 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 

Aquí se puede ver que List[Int] y List[_] tienen la misma borrado:

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 
+0

pero (nueva T con U) .getClass devuelve una clase. ¿Entonces que es? – IttayD

+3

'new T with U' declara y crea una clase anónima que implementa las interfaces' T' y 'U'. – retronym

1

No, no es posible porque "X con Y" es una definición anónima en su ejemplo. Este no es el caso para "la clase X extiende Z con Y", por supuesto.

0

no se puede obtener una clase literal, sino que puede probar si un objeto se encuentra con este tipo de dos maneras diferentes:

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 

Se parece mucho a esta declaración genérica en java

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

Ese método se borra a

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

Sin embargo en Java no se puede decir xy instanceof (X&Y) pero en realidad es el mismo que xy instanceof X && xy instanceof Y

0

No estoy seguro exactamente lo que estás tratando de hacer con el compuesto clase, pero lo que puede hacer es obtener la lista de interfaces implementadas y la superclase de una determinada clase anónima que podría ser suficiente. Por ejemplo:

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 
+1

Lo que quería es obtener la clase de composición sin crear una instancia o clase nueva – IttayD

Cuestiones relacionadas