Reputation: 3378
In Java, there is a Class<T>
class that represents, well, classes. It's useful when you need to do some class checks dynamically at runtime, for example, if some interface can accept varied number of arguments and it expects the arguments to have specific types: then the interface can return a list of Class
objects to specify its requirements.
Apparently, it's available in Scala as well, but just as an alias to the Java class). Is it OK to use this in Scala (or in general, the Class
class, in pure Scala code), or would there be a more idiomatic way to achieve the same thing there?
For more context, this is what I'm thinking of:
trait BuiltInFunction[Node] {
def symbol: String
def arity: Int
def argumentTypes: List[Class[Node]]
def apply(args: List[Node]): Node
}
BuiltInFunction
represents functions that each can have different number of arguments and expect the arguments to be different subtypes of Node
. If the system encounters a function, it will make sure that it's applied to arguments of proper types (as defined by argumentTypes
) by calling the apply
method with those arguments.
Is using Class
the right way to do it in Scala?
Upvotes: 1
Views: 90
Reputation: 170839
If you don't need Scala-specific details (differentiating between properties and methods, implicits, etc.) using Class
is perfectly fine; if it wasn't, it wouldn't be available in scala.Predef
as an alias!
If you do, there is Scala reflection but to be honest, in my experience it's harder to use than the Java Class
-based reflection. If you can use both I'd prefer Class
.
OTOH:
List[Class[Node]]
is not correct if you
expect the arguments to be different subtypes of Node
It should be List[Class[_ <: Node]]
instead.
Class
only reflects classes after erasure, e.g. classOf[List[String]]
and classOf[List[Int]]
are the same. If you need to differentiate them Class
won't be enough.
Upvotes: 4