Search code examples
scalagenericsintrospection

Returning Options of Class types in Scala methods


I am struggling with handling Class types for something I am writing, and the answer may involve generics, but I'm kind of stuck on what the right solution should be.

I have a Scala class Vehicle that has several child classes (Car, Bus, Train, Motorcycle, etc.):

class Vehicle {
    ...
}

class Car extends Vehicle {
    ...
}

class Motorcycle extends Vehicle {
    ...
}

I now am trying to write a utility method that can map a String to a Vehicle subclass (that is, the Class it is, not an instance of that class):

object VehicleUtils {
    def mapToVehicleType(vehicleType : String) : Vehicle = {
        var vType : Vehicle = null
        if(vehicleType == "car") {
            vType = Car
        } else if(vehicleType == "motorcycle") {
            vtype = Motorcycle
        } else if(...) {
            ...etc.
        }

        vType
    }
}

The problem is I'm confusing/blurring types vs. instances. I don't want the mapToVehicleType method to return an instance of, say, Car. I want it to simply return the Car class if "car" is provided as input, etc. Can anyone spot where I'm going awry and what the solution is. I'd also like to use Scala Options if possible, because the mapToVehicleType method can certainly return null.


Solution

  • Scala provides classOf[T] to get the class type of a class. For example: classOf[Car] returns an instance of type Class[Car].

    For mapping to the appropriate class type, you can use pattern matching to map the types from the provided string to an Option:

    def mapToVehicleType(vehicleType: String): Option[Class[_ <: Vehicle]] = {
        vehicleType match {
            case "car"        => Some(classOf[Car])
            case "motorcycle" => Some(classOf[Motorcycle])
            case _            => None
        }
    }