該實現基於Java反射API。
如果定義爲VAL枚舉值:
object Fruit extends Enumeration {
val Apple, Banana, Cherry = Value
}
有在類水果的VAL方法:
scala> Fruit.getClass.getMethods filter (_.getName.contains("Apple")) foreach println
public scala.Enumeration$Value line10$object$$iw$$iw$Fruit$.Apple()
toString
電話Enumeration.this.nameOf(i)
如果該名稱未明確設置。此方法將嘗試查找返回Value
實例的枚舉類中的所有方法。
val methods = getClass.getMethods
for (m <- methods
if (classOf[Value].isAssignableFrom(m.getReturnType) &&
!java.lang.reflect.Modifier.isFinal(m.getModifiers) &&
m.getParameterTypes.isEmpty &&
isValDef(m)))
這些是Fruit類的方法。
然後,它使用枚舉值的方法和ID的名稱來構建地圖id -> name
,並使用枚舉值的id從地圖中檢索名稱。
object X extends Enumeration {
val Y = Value
}
object Fruit extends Enumeration {
val x = X.Y
val A,B,C = Value
}
這Fruit.value返回object$Fruit.ValueSet(x, B, C)
不object$Fruit.ValueSet(A, B, C)
:
val name = m.getName
// invoke method to obtain actual `Value` instance
val value = m.invoke(this)
// invoke `id` method
val idMeth = classOf[Val].getMethod("id")
val id: Int = idMeth.invoke(value).asInstanceOf[java.lang.Integer].intValue()
這可以實現,如果你這樣定義一個枚舉很容易被破壞。