2010-01-31 15 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 

C'è un modo per ottenere la classe di "Proprietà con Pippo" senza creare un'istanza o una nuova classe?Scala: come ottenere una composizione di mixin di classe?

risposta

7

classOf[X] funziona solo se X corrisponde a una classe fisica. T with U è un tipo composto e non corrisponde a una classe.

È possibile utilizzare Manifests per determinare la cancellazione di un tipo. La cancellazione del tipo di 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 

Qui può vedere che List[Int] e List[_] hanno lo stesso cancellazione:

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

ma (nuovo T con U) .getClass restituisce una classe. Quindi cos'è? – IttayD

+3

'new T with U' dichiara e istanzia una classe anonima che implementa le interfacce' T' e 'U'. – retronym

1

No, non è possibile perché "X con Y" è una definizione anonima nel tuo esempio. Questo non è il caso per "la classe X estende Z con Y", ovviamente.

0

Non è possibile ottenere una classe letterale, ma si può verificare se un oggetto si riunisce questo tipo in due modi diversi:

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 

E 'un po' come questa dichiarazione generica in Java

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

Questo metodo viene cancellata per

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

Tuttavia in Java non si può dire che xy instanceof (X&Y) ma è davvero la stessa xy instanceof X && xy instanceof Y

0

non sono sicuro esattamente quello che stai cercando di fare con il composito classe, ma quello che puoi fare è ottenere l'elenco delle interfacce implementate e la superclasse di una determinata classe anonima che potrebbe essere sufficiente. Ad esempio:

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

Quello che volevo è ottenere la classe di composizione senza creare un'istanza o una nuova classe – IttayD

Problemi correlati