Using Java reflection
There is no notion of default value for method parameters in Java byte code.
So how does the Scala compiler represent default values at runtime? For each parameter with a default value the compiler adds a new method into the same class. The name of that synthesized method follows the pattern: <methodName>$default$<parameterNumber>
.
In your case, the name of the method that returns the default value of y
is getSum$default$2
. It takes no argument and it returns 10
.
In order to get the value you need to call that method on an instance of class X
. If you do not have an instance of X
then you cannot get the value at runtime.
That is because, in the general case, a default value can depend on some previous parameters or even on some fields of the class.
class X(default: Int) {
def getSum(x: Int, y: Int = default): Int = x + y
}
class Y {
def getSum(x: Int)(y: Int = x): Int = x + y
}
In the first case the body of getSum$default$2
is this.default
. In the second case the getSum$default$2
method takes x
as parameter and returns its value.
Using Scala Compile-time Reflection (Scala 2)
Possibly you could use scala-reflect to find the DefDef
tree of the getSum$default$2
method. Then you may be able to get the body of the method.
See Scala 2 reflection documentation here.
Using Macros (Scala 3)
You can create a macro method that returns the body of the getter method of some default value.
Here I made some experiment:
package macros
import quoted._
object Check:
inline def defaultValue[T]: Any = ${ impl[T] }
private def impl[T](using Quotes, Type[T]): Expr[Any] =
import quotes.reflect.*
val tpe = TypeRepr.of[T]
val symbol = tpe.classSymbol
.getOrElse(report.throwError("It is not a class"))
val classTree = symbol.tree.asInstanceOf[ClassDef]
val method = classTree.body
.collect { case m: DefDef => m }
.find(m => m.name == "getSum$default$2")
.getOrElse(report.throwError("Getter method not found"))
method.rhs.get.asExprOf[Any]
@main def run(): Unit =
println(macros.Check.defaultValue[X])
We need to use the -Yretain-trees
compiler option to compile that code. It should print 10
.