从 Java 代码访问 Scala 类型 Class?
Accessing Scala Type Class from Java code?
我使用类型 classes 和临时多态性在 Scala 中创建了许多不同的拍卖实现。
可以找到 Scala 实现的示例 here。
在 Scala 中创建一个拍卖实例如下...
val google: GoogleStock = GoogleStock(tick=1)
val pricingRule = new MidPointPricingPolicy[GoogleStock]
val withDiscriminatoryPricing = OpenBidDoubleAuction.withDiscriminatoryPricing(pricingRule)
我希望用户能够从 Java 8.
访问拍卖实施
但我似乎无法弄清楚如何在 Java 中创建拍卖实例。采用这种方法:
MidPointPricingPolicy<GoogleStock> midPointPricing = new MidPointPricingPolicy<GoogleStock>();
OpenBidDoubleAuction.DiscriminatoryPricingImpl<GoogleStock> auction = OpenBidDoubleAuction$.MODULE$.withDiscriminatoryPricing(midPointPricing);
有效,但 none 类型的 class 合同方法可用。具体来说:
OpenBidDoubleAuction.DiscriminatoryPricingImpl<GoogleStock> auction2 = auction.insert(order3);
...产生以下编译错误。
Error:(90, 82) java: cannot find symbol
symbol: method insert(org.economicsl.auctions.singleunit.orders.LimitAskOrder<org.economicsl.auctions.GoogleStock>)
location: variable auction of type org.economicsl.auctions.singleunit.twosided.SealedBidDoubleAuction.UniformPricingImpl<org.economicsl.auctions.GoogleStock>
似乎在编译 Java 代码时,Scala 编译器为类型 class 生成的契约方法不可用。在我的 build.sbt
文件中,我设置了 compileOrder := CompileOrder.ScalaThenJava
以确保首先编译这些 Scala,以便这些方法可用。
根据@GhostCat 的建议,我使用 javap
发现 Scala 编译器生成了以下 .class
文件...
OpenBidDoubleAuction$DiscriminatoryPricingImpl$$anon.class
其中包含相关方法的字节码定义。
所以我想我需要知道如何从 Java 访问此字节代码文件中定义的内容?有可能吗?
一般的答案是:那是两种不同的语言。在 java 端 visible 的唯一东西是 bytecode 中为 OpenBidDoubleAuction
找到的元素。
因此:您计算 "what can I use from Java" 的一种可能方法:转到 javap 并检查 scalac 生成的字节码。这将告诉您所有可用的方法及其签名。如果你发现你的 "enhanced" 例子太复杂了:退后一步。创建一个 minimal 示例 - 一小块 scala;然后仔细分析生成的字节码。
当然:您首先要检查 documentation - 您希望避免将时间浪费在根本不可能的事情上。从事物的 Java 方面来看,您不能使用各种语言元素。
(请注意:link 已过时,但可能足以作为您自己研究的起点)
Java 没有 implicit
关键字,也不知道任何关于隐含的东西。 implicit def
到 Java 只是另一种方法。因此,当您从 Java 调用此代码时,您必须显式添加所有隐式转换和隐式参数。如果你想知道那会是什么样子,你可以打开一个 Scala REPL 并使用 //print <tab>
提示来查看你的代码在经过几次脱糖和显式隐含后会是什么样子。
例如,给定一些类型类 Foo
和隐式 FooSyntax
:
scala> 42.foo //print <tab>
FooSyntax[Int](42)(Foo.fooInt).foo // : String
明确地说,在它说 <tab>
的地方,您必须按 Tab 键而不是键入它:)
然后,如果你有点幸运,你所要做的就是将脱糖的 Scala 进一步转换为实际的 Java:
FooSyntax(42, Foo.fooInt()).foo();
如果您不那么幸运,您可能需要添加一些额外的 MODULE$
内容。如果您 甚至更少 幸运并且您必须与结构类型或交叉类型之类的东西进行互操作,那么您可能必须分别使用反射或转换。
但一般来说:如果您想从 Java 调用相同的代码,不要 使用 Scala 的高级功能,如类型类。如果您必须创建一个可从 Java 调用的库,那么尝试编写(在 Scala 中)Java 友好的包装器 advanced/incompatible 部分。
我使用类型 classes 和临时多态性在 Scala 中创建了许多不同的拍卖实现。
可以找到 Scala 实现的示例 here。
在 Scala 中创建一个拍卖实例如下...
val google: GoogleStock = GoogleStock(tick=1)
val pricingRule = new MidPointPricingPolicy[GoogleStock]
val withDiscriminatoryPricing = OpenBidDoubleAuction.withDiscriminatoryPricing(pricingRule)
我希望用户能够从 Java 8.
访问拍卖实施但我似乎无法弄清楚如何在 Java 中创建拍卖实例。采用这种方法:
MidPointPricingPolicy<GoogleStock> midPointPricing = new MidPointPricingPolicy<GoogleStock>();
OpenBidDoubleAuction.DiscriminatoryPricingImpl<GoogleStock> auction = OpenBidDoubleAuction$.MODULE$.withDiscriminatoryPricing(midPointPricing);
有效,但 none 类型的 class 合同方法可用。具体来说:
OpenBidDoubleAuction.DiscriminatoryPricingImpl<GoogleStock> auction2 = auction.insert(order3);
...产生以下编译错误。
Error:(90, 82) java: cannot find symbol
symbol: method insert(org.economicsl.auctions.singleunit.orders.LimitAskOrder<org.economicsl.auctions.GoogleStock>)
location: variable auction of type org.economicsl.auctions.singleunit.twosided.SealedBidDoubleAuction.UniformPricingImpl<org.economicsl.auctions.GoogleStock>
似乎在编译 Java 代码时,Scala 编译器为类型 class 生成的契约方法不可用。在我的 build.sbt
文件中,我设置了 compileOrder := CompileOrder.ScalaThenJava
以确保首先编译这些 Scala,以便这些方法可用。
根据@GhostCat 的建议,我使用 javap
发现 Scala 编译器生成了以下 .class
文件...
OpenBidDoubleAuction$DiscriminatoryPricingImpl$$anon.class
其中包含相关方法的字节码定义。
所以我想我需要知道如何从 Java 访问此字节代码文件中定义的内容?有可能吗?
一般的答案是:那是两种不同的语言。在 java 端 visible 的唯一东西是 bytecode 中为 OpenBidDoubleAuction
找到的元素。
因此:您计算 "what can I use from Java" 的一种可能方法:转到 javap 并检查 scalac 生成的字节码。这将告诉您所有可用的方法及其签名。如果你发现你的 "enhanced" 例子太复杂了:退后一步。创建一个 minimal 示例 - 一小块 scala;然后仔细分析生成的字节码。
当然:您首先要检查 documentation - 您希望避免将时间浪费在根本不可能的事情上。从事物的 Java 方面来看,您不能使用各种语言元素。
(请注意:link 已过时,但可能足以作为您自己研究的起点)
Java 没有 implicit
关键字,也不知道任何关于隐含的东西。 implicit def
到 Java 只是另一种方法。因此,当您从 Java 调用此代码时,您必须显式添加所有隐式转换和隐式参数。如果你想知道那会是什么样子,你可以打开一个 Scala REPL 并使用 //print <tab>
提示来查看你的代码在经过几次脱糖和显式隐含后会是什么样子。
例如,给定一些类型类 Foo
和隐式 FooSyntax
:
scala> 42.foo //print <tab>
FooSyntax[Int](42)(Foo.fooInt).foo // : String
明确地说,在它说 <tab>
的地方,您必须按 Tab 键而不是键入它:)
然后,如果你有点幸运,你所要做的就是将脱糖的 Scala 进一步转换为实际的 Java:
FooSyntax(42, Foo.fooInt()).foo();
如果您不那么幸运,您可能需要添加一些额外的 MODULE$
内容。如果您 甚至更少 幸运并且您必须与结构类型或交叉类型之类的东西进行互操作,那么您可能必须分别使用反射或转换。
但一般来说:如果您想从 Java 调用相同的代码,不要 使用 Scala 的高级功能,如类型类。如果您必须创建一个可从 Java 调用的库,那么尝试编写(在 Scala 中)Java 友好的包装器 advanced/incompatible 部分。