What does this warning mean:
reflective access of structural type member method getMap should be enabled
The warning includes a reference to the scala docs but I don't understand how my code is related to the explanation. (Specifically the explanation mentions reflection... how is my code using reflection?)
I have this: (Scala 2.11.2)
object getMap {
implicit def fromOptionToConvertedVal[T](o:Option[T]) = new {
def getMap[R] (doWithSomeVal:(T) => R) = new {
def orElse(handleNone: => R) = o match {
case Some(value) => doWithSomeVal(value)
case None => handleNone
}
}
}
}
import getMap._
val i:Option[Int] = Some(5)
val x = i getMap (_*2) orElse 1
This generates the warning below:
[warn] /Users/Greg/git/Favorites-Demo/src/main/scala/com/rs/server/ThriftServer.scala:34: reflective access of structural type member method getMap should be enabled
[warn] by making the implicit value scala.language.reflectiveCalls visible.
[warn] This can be achieved by adding the import clause 'import scala.language.reflectiveCalls'
[warn] or by setting the compiler option -language:reflectiveCalls.
[warn] See the Scala docs for value scala.language.reflectiveCalls for a discussion
[warn] why the feature should be explicitly enabled.
[warn] val x = i getMap (_*2) orElse 1
[warn] ^
[warn] /Users/Greg/git/Favorites-Demo/src/main/scala/com/rs/server/ThriftServer.scala:34: reflective access of structural type member method orElse should be enabled
[warn] by making the implicit value scala.language.reflectiveCalls visible.
[warn] val x = i getMap (_*2) orElse 1
[warn] ^
Given a type or instance of some object at runtime , reflection is the ability to: or to access or invoke members of that object. Let’s jump in and see how to do each of the above with a few examples. As with other JVM languages, Scala’s types are erased at compile time.
The symbol for Person s constructor can be obtained using only the runtime universe ru by looking it up in the declarations of type Person. scala> val ctorm = cm.reflectConstructor (ctor) ctorm: scala.reflect.runtime.universe.
A first category is suspicious code that is likely the result of a programming mistake: Warnings about non-exhaustive pattern matches and uncheckable type arguments are also issued by default (note that exhaustivity warnings just received a big upgrade in Scala 2.13.4 ):
Thus, the Scala compiler often creates synthetic classes (i.e. automatically-generated classes) that are used at runtime in place of user-defined classes. This is quite commonplace in Scala and can be observed when using Java reflection with a number of Scala features, e.g. closures, type members, type refinements, local classes, etc.
I think what's going on is that the new { ... }
objects are structurally typed, which require reflection to implement.
The underlying reason is that Scala structural typing allows objects to be treated as if they are instances of many types according to which methods they actually have (like duck typing). The JVM allows exactly one type so methods that are not part of the object's underlying type have to be accessed via something other than a normal virtual method call. The mechanism that's used in this case is reflection.
When the scala compiler sees an invocation of a method that's being called on a structurally typed object it (modulo some optimizations) translates a method call like:
a.f(b, c)
to
a.getClass
.getMethod("f", Array(classOf[B], classOf[C]))
.invoke(a, Array(b, c))
Example taken from the place where the technique was described.
The Scala team decided to enforce an opt-in policy for advanced features. reflectiveCalls
happens to be one of them as documented in this SIP
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