Scala:在不创建对象的情况下获取默认值
Posted
技术标签:
【中文标题】Scala:在不创建对象的情况下获取默认值【英文标题】:Scala: get default values without creating an object 【发布时间】:2016-03-13 15:36:06 【问题描述】:假设构造函数中有一个具有默认值的类:
class Adapter(url: String = "127.0.0.1", port: Int = 8080)
是否可以在运行时获取这些参数的默认值而不创建此对象的实例?
请不要询问用例,这更多是关于语言本身的问题。
【问题讨论】:
【参考方案1】:将它们移动到伴随对象中?
case class Adapter(url: String = Adapter.defaultURL, port: Int = Adapter.defaultPort)
object Adapter
val defaultURL = "127.0.0.1"
val defaultPort = 8080
如果只能从 case class
访问默认值,则可以使用 private
限定更多默认值
【讨论】:
这不是 OP 的这个问题的答案 这似乎是一个不错的答案。我不明白这个问题。如果问题是示例代码中的硬编码值,您可以轻松地想象一个 "def lookupAdapterUrl" 而不是 "val defaultURL" 。 . . . 您将如何以编程方式发现它们?【参考方案2】:我假设您最感兴趣的是默认方法是如何在内部实现的。这是您的代码的 javap 反汇编(使用非常有用的 :javap <classname>
scala 控制台命令:
scala> class Adapter(url: String = "127.0.0.1", port: Int = 8080)
defined class Adapter
scala> :javap -c Adapter$ // Adapter$ because we want the companion object
Compiled from "<console>"
public class Adapter$
...
public java.lang.String $lessinit$greater$default$1();
Code:
0: ldc #16 // String 127.0.0.1
2: areturn
public int $lessinit$greater$default$2();
Code:
0: sipush 8080
3: ireturn
...
如您所见,创建默认值的方法在伴随对象中被编码为特殊命名的方法。因此,要在不重构示例的情况下调用这些方法,您必须使用反射:
scala> Adapter.getClass.getMethod("$lessinit$greater$default$1").invoke(Adapter)
res8: Object = 127.0.0.1
scala> Adapter.getClass.getMethod("$lessinit$greater$default$2").invoke(Adapter)
res9: Object = 8080
显然,在生产代码中这样做可能不是一个好主意,因为名称修改细节等可能会改变。在这种情况下,只需使用@Sparko 的建议即可。
关于名称修改方案的说明:该方案是methodName + "$default$" + parameterNumber
。上例中要修饰的方法是构造函数,即“
【讨论】:
以上是关于Scala:在不创建对象的情况下获取默认值的主要内容,如果未能解决你的问题,请参考以下文章