Given is a Java method that returns java.lang.Object
s for a given string. I'd like to wrap this method in a Scala method that converts the returned instances to some type T
. If the conversion fails, the method should return None
. I am looking for something similar to this:
def convert[T](key: String): Option[T] = {
val obj = someJavaMethod(key)
// return Some(obj) if obj is of type T, otherwise None
}
convert[Int]("keyToSomeInt") // yields Some(1)
convert[String]("keyToSomeInt") // yields None
(How) Can this be achieved using Scala's reflection API? I am well aware that the signature of convert
might have to be altered.
Type casting is when you assign a value of one data type to another type. In C#, there are two types of casting: Implicit Casting (automatically) - converting a smaller type to a larger type size. char -> int -> long -> float -> double. Explicit Casting (manually) - converting a larger type to a smaller size type.
Java Type Casting. Type casting is when you assign a value of one primitive data type to another type. In Java, there are two types of casting: Widening Casting (automatically) - converting a smaller type to a larger type size. byte -> short -> char -> int -> long -> float -> double.
Type castings allow you to convert a variable from one type to another. In TypeScript, you can use the as keyword or <> operator for type castings. Type casting using the as keyword The following selects the first input element by using the querySelector () method:
There can be two types of Type Casting in Python – Implicit Type Casting; Explicit Type Casting; Implicit Type Conversion. In this, methods, Python converts data type into another data type automatically. In this process, users don’t have to involve in this process.
You could try shapeless's Typeable
,
scala> import shapeless._ ; import syntax.typeable._
import shapeless._
import syntax.typeable._
scala> def someJavaMethod(key: String): AnyRef =
| key match {
| case "keyToSomeInt" => 23.asInstanceOf[AnyRef]
| case "keyToSomeString" => "foo"
| }
someJavaMethod: (key: String)AnyRef
scala> def convert[T: Typeable](key: String): Option[T] =
| someJavaMethod(key).cast[T]
convert: [T](key: String)(implicit evidence$1: shapeless.Typeable[T])Option[T]
scala> convert[Int]("keyToSomeInt")
res0: Option[Int] = Some(23)
scala> convert[String]("keyToSomeString")
res1: Option[String] = Some(foo)
scala> convert[String]("keyToSomeInt")
res2: Option[String] = None
scala> convert[Int]("keyToSomeString")
res3: Option[Int] = None
That's what a ClassTag
is for:
import reflect.ClassTag
def convert[T : ClassTag](key: String): Option[T] = {
val ct = implicitly[ClassTag[T]]
someJavaMethod(key) match {
case ct(x) => Some(x)
case _ => None
}
}
It can be used as an extractor to test and cast to the proper type at the same time.
Example:
scala> def someJavaMethod(s: String): AnyRef = "e"
someJavaMethod: (s: String)AnyRef
[...]
scala> convert[Int]("key")
res4: Option[Int] = None
scala> convert[String]("key")
res5: Option[String] = Some(e)
Edit: Note however that a ClassTag
does not automatically unbox boxed primitives. So, for example, convert[Int]("a")
would never work, because the java method returns AnyRef
, it would have to be convert[java.lang.Integer]("a")
, and so on for other primitive types.
Miles's answer with Typeable
seems to take care of those edge cases automatically.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With