2015-07-02 13 views
25

Ho bisogno di ottenere solo i nomi dei campi di case class, non sono interessato ai suoi valori. Ho pensato che non fosse il problema e getClass.getDeclaredFields.map (_. GetName) mi restituirebbe un elenco di nomi di campi. E non riesco a trovare una domanda simile.Scala. Ottieni l'elenco dei nomi dei campi dalla classe

scala> case class User(id: Int, name: String) 
defined class User 

scala> User.getClass.getDeclaredFields 
res14: Array[java.lang.reflect.Field] = Array(public static final User$ User$.MODULE$) 

scala> User.getClass.getDeclaredFields.toList 
res15: List[java.lang.reflect.Field] = List(public static final User$ User$.MODULE$) 

scala> val user = User(1, "dude") 
user: User = User(1,dude) 

scala> user.getClass.getDeclaredFields.toList 
res16: List[java.lang.reflect.Field] = List(private final int User.id, private final java.lang.String User.name) 

Che cos'è questo $ utente $ .MODULE? Cos'è quello?

Metodo getDeclaredFields funziona bene quando si ha un'istanza della classe caso, ma io non voglio creare un'istanza al fine di ottenere solo i campi

Perché questo non è vero? User.getClass.getDeclaredFields (_. GetName) == Lista ("id", "nome")

risposta

45

Utilizzando User.getClass, si fa riferimento all'oggetto compagno di classe che Scala per impostazione predefinita crea per la classe del caso e non la classe del caso stesso. Per ottenere l'oggetto classe della classe case, utilizzare classOf[User].

In alternativa, è possibile utilizzare API di riflessione di Scala per ottenere i metadati di una classe caso, che vi dà molte più informazioni:

import scala.reflect.runtime.universe._ 

def classAccessors[T: TypeTag]: List[MethodSymbol] = typeOf[T].members.collect { 
    case m: MethodSymbol if m.isCaseAccessor => m 
}.toList 

test in consolle SBT:

scala> case class User(name: String, age: Int) 
defined class User 

scala> classAccessors[User] 
res0: List[reflect.runtime.universe.MethodSymbol] = List(value age, value name) 
+2

Essi sembrano provenire di nuovo in ordine lexo. C'è un modo per farli tornare nell'ordine in cui sono dichiarati nel codice? – samthebest

+1

Questa risposta ha una discussione che spiega come ottenere in ordine: http://stackoverflow.com/a/16079804/1586965 – samthebest

10

User.getClass non ti dà l'equivalente di User.class in Java, ma ti dà la classe del compagno oggetto della classe User. È possibile recuperare l'oggetto Class di User con classOf[User].

modifica: Oh e User$.MODULE$ è un accessorio per l'istanza singleton utilizzata internamente. Consideralo come l'equivalente a MyClass.INSTANCE quando stai scrivendo singleton in Java.

Problemi correlati