说我有以下课程:
class Person {
@BeanProperty
var firstName: String = _
}
是否可以通过反射或其他方式以类型安全的方式获取“firstName”的String表示?或生成的“getFirstName”函数的字符串表示?
如果它会以某种方式显示会很好:
val p = new Person
p.getFunction(p.getFirstName).toString // "getFirstName"
p.getAttribute(p.firstName).toString // "firstName"
修改
好的,需要更多解释;)
假设我想构建一个这样的SQL查询:
val jpql = "select p from Person p where p.age > 20";
所以我想尽可能使其成为类型安全并写下这样的东西:
val jpql = "select p from " + classOf[Person].getName + " where p." +
Person.getAttName(p.age) + " > 20";
通过这种方式,如果将来可以重构Scala代码,我可以在不破坏代码的情况下更改Person的属性名称。
答案 0 :(得分:2)
我假设您不知道要检查的类中的方法和属性名称(否则为什么要获取其名称而不是仅仅键入它们?)。此示例显示如何获取java.lang.String
类上的所有方法的名称。
scala> classOf[String].getMethods.map(_.getName)
res4: Array[java.lang.String] = Array(equals, hashCode, toString, charAt, compareTo,
compareToIgnoreCase, concat, endsWith, equalsIgnoreCase, getBytes, getBytes, getBytes,
getChars, indexOf, indexOf, indexOf, indexOf, intern, lastIndexOf, lastIndexOf,
lastIndexOf, lastIndexOf, length, regionMatches, regionMatches, replace, startsWith,
startsWith, substring, substring, toCharArray, toL...
答案 1 :(得分:2)
坏消息是Scala实际上没有能力引用这样的成员。你可以获得这样的“方法参考”:
scala> class Person(val firstName:String)
defined class Person
scala> val methodRef = new Person("i").firstName _
methodRef: () => String = <function0>
scala> methodRef()
res1: String = i
但它并没有给你你想要的反思性东西。好消息是有几个库可以为您提供这种类型安全的JDBC。以下是使用Squeryl的代码:
import org.squeryl.Schema
import org.squeryl.Session
import org.squeryl.PrimitiveTypeMode._
import org.squeryl.adapters.H2Adapter
import org.squeryl.SessionFactory
object Sample {
case class Person(val firstName:String, val age:Int)
object AppSchema extends Schema {
val people = table[Person]("People")
}
def main(args:Array[String]) {
import AppSchema.people
Class.forName("org.h2.Driver")
SessionFactory.concreteFactory = Some(()=> Session.create(java.sql.DriverManager.getConnection("jdbc:h2:~/temp/db", "sa", ""), new H2Adapter))
transaction {
AppSchema.create
people.insert(new Person("ifischer", 92))
people.insert(new Person("baby", 2))
for (olderPerson <- from(people)(p=> where(p.age gt 20) select(p))) {
println(olderPerson) //wont return "baby"!
}
}
}
}
那有多酷?例如,如果您尝试将年龄与String进行比较,则无法编译。当然,如果你使用p.ssn或其他一些未知字段,也不会编译。