Java 或 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!
How do I define new types at runtime? I have a factory method that needs to create a new instance of this.type
with a marker interface. The marker interface was not mixed in at compile time. I need to find a way to do this at runtime.
I am using Scala, but I think the answer will be general enough to cover both Java and 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!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
这是不可能的。当然,有多种方法可以在运行时创建新类:只需使用任何字节码操作库。但是
this.type
不是“this
的类”,而是this
的单例类型(并且有无法在 Scala 类型签名中表达“this
的类”)!当然,如果
Apple
不扩展Eaten
,无论您在方法内做什么,它都不会编译。通常的解决方法是这样的,但如果您有多个标记接口,则这将不起作用:
This is impossible. Sure, there are ways of creating new classes at the runtime: just use any bytecode manipulation library. But
this.type
is not "the class ofthis
", but the singleton type ofthis
(and there is no way to express "the class ofthis
" in a Scala type signature)! SoAnd of course if
Apple
doesn't extendEaten
, it won't compile, whatever you do inside the method. The usual workaround is something likebut this won't work if you have more than one marker interface:
我不太确定你想要解决什么样的问题,但也许你可以使用类型构造函数之类的东西来代替实现特征,所以 Eaten 变得像
Apple.eat 返回一个
I'm not exactly sure what kind of problem you are trying to solve, but maybe instead of implementing a trait you can use something like a type constructor, so Eaten becomes something like
and Apple.eat returns an
JDK6 将允许您编译实际的 Java 代码。请参阅 http://www.java2s.com/Code/Java/JDK- 6/CompilingfromMemory.htm
或者(特别是如果您希望创建一个类来实现接口),您应该查看:
java.lang.reflect.Proxy
,这将让你做这样的事情:请注意 JMock 等也可以做到这一点非常简单。
JDK6 will let you compile actual Java code. See http://www.java2s.com/Code/Java/JDK-6/CompilingfromMemory.htm
Alternatively (especially if you wish to create a class to implement an interface), you should check out:
java.lang.reflect.Proxy
, which will let you do something like this:Note that JMock and the like also make this very straightforward.
好吧,在 Scala 中,有一种叫做隐式转换的东西 你可以使用。但 Java 中没有类似的东西。
你的代码看起来像这样:
Well, in Scala, there's this thing called implicit conversions that you can use. But there's no equivalent in Java though.
Your code would look something like:
现在据我所知(不多)scala 不是一种动态语言,它更像是一种函数式语言。现在在groovy中——它是一种动态语言,你可以在字符串或文本文件中定义一个类,并在运行时对其进行EVAL,但我不相信这些事情在scala中是可能的。
编辑:一些动态功能即将登陆scala
Now as far as I know (which is not much) scala is not a dynamic language, it is more of a functional language. Now in groovy - its a dynamic language, you can define a class in a string or in a text file and EVAL it at runtime, but I dont believe these things are possible in scala.
Edit : some dynamic features are coming to scala