Reputation: 5136
In Scala, I need to execute code that fulfills the following requirement:
Pass a java.lang.Class
into a factory method. The class passed to this method must extend the abstract class Project
. I will instantiate this class, perform various actions, and return it.
Here's what I have...
object ProjectFactory {
def create (clazz: java.lang.Class[T <: Project]): Project = {
val newProject = clazz.newInstance
/* snip */
newProject
}
}
abstract class Project
...and here is the error I am getting:
identifier expected but <: found
I know this is just a syntax issue - how do I express this logic?
Upvotes: 1
Views: 156
Reputation: 33019
You need to declare the type parameter after the method name, not at the use site:
object ProjectFactory {
def create[T <: Project](clazz: java.lang.Class[T]): Project = {
val newProject = clazz.newInstance
/* snip */
newProject
}
}
abstract class Project
I'm not an expert with Scala's reflection libraries, but I think this might be cleaner:
object ProjectFactory {
def create[T <: Project: Manifest]: Project = {
val newProject = classManifest[T].erasure.newInstance.asInstanceOf[Project]
/* snip */
newProject
}
}
abstract class Project
That way you don't have to explicitly pass in a class object—you just parameterize the method with the type you want. Again, I bet there's a better way to do this, so I'd appreciate feedback from those with more experience in this area.
Also, I think Scala 2.10 has dropped Manifests in favor of ClassTags or something like that...
Upvotes: 6
Reputation: 62835
You were close:
object ProjectFactory {
def create[T <: Project](clazz: java.lang.Class[T]): Project = {
val newProject = clazz.newInstance
/* snip */
newProject
}
}
abstract class Project
Upvotes: 2