Lan*_*uhn 3 java reflection scala
如何在运行时定义新类型?我有一个工厂方法需要this.type 使用标记接口创建一个新实例.标记接口在编译时未混合.我需要找到一种在运行时执行此操作的方法.
我正在使用Scala,但我认为答案将足以涵盖Java和Scala.
trait Fruit {
def eat: this.type with Eaten = {
getClass.getConstructors()(0).newInstance(Array()).asInstanceOf[this.type];
// somehow this needs to return a new instance of this.type with the Eaten trait
// note that "Apple with Eaten" is not a type that exists at compile-time
}
}
trait Eaten // marker interface
class Apple extends Fruit
val apple1 = new Apple
val apple2 = a.eat // should return a new Apple with Eaten instance
def eater(eaten: Eaten) = ... // this function only accepts Eaten fruit
eater(apple1) // wont compile!
eater(apple2) // will compile!
Run Code Online (Sandbox Code Playgroud)
这是不可能的.当然,有一些方法可以在运行时创建新类:只需使用任何字节码操作库.但是,this.type是不是 "之类的this",但对单类型this(有没有办法表达"之类的this"在斯卡拉类型签名)!所以
def eat: this.type with Eaten = {
// may do something here, but in the end you have to return
this
}
Run Code Online (Sandbox Code Playgroud)
当然,如果Apple不扩展Eaten,它将无法编译,无论你在方法内做什么.通常的解决方法是类似的
class Fruit[F : Manifest <: Fruit[F]] {
def eat: F with Eaten = {
val clazz = manifest[F].erasure
val result = // do your bytecode manipulations here
result.asInstanceOf[F with Eaten]
}
}
Run Code Online (Sandbox Code Playgroud)
但是如果你有多个标记界面,这将不起作用:
val apple = new Apple // Apple
val washed = apple.wash // Apple with Washed
val eaten = washed.eat // Apple with Eaten, but no longer Washed!
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1526 次 |
| 最近记录: |