我使用类型类和ad-hoc多态在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);
有效,但没有类型类合同方法可用。具体做法是:
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编译器为类型类生成的契约方法不可用。在我的build.sbt
文件中,我设置了compileOrder := CompileOrder.ScalaThenJava
,以确保首先编译这些Scala,以便这些方法可用。
根据@GhostCat的建议,我使用javap
找出Scala编译器生成以下.class
文件...
OpenBidDoubleAuction$DiscriminatoryPricingImpl$$anon$1.class
包含相关方法的字节码定义。
所以我想我需要知道如何从Java访问此字节代码文件中定义的内容?它甚至可能吗?
答案 0 :(得分:3)
通用答案是:这是两种不同的语言。 java端唯一可见的内容是OpenBidDoubleAuction
的字节码中的元素。
因此:一种可能的方式来表示&#34;我可以从Java使用什么&#34;:转向javap并检查scalac生成的字节代码。这将告诉您所有可用的方法及其签名。如果你发现你的&#34;增强&#34;这个例子太复杂了:退后一步。创建一个 minimal 示例 - 一小段scala;然后仔细分析生成的字节代码。
当然:你首先检查documentation - 你要避免在一些根本不可能的事情上浪费你的时间。您可以从Java方面使用各种语言元素。
(请注意:该链接已过时,但可能已经足够作为您自己研究的起点)
答案 1 :(得分:1)
Java没有implicit
关键字,也不知道任何关于implicits的内容。 Java implicit def
只是另一种方法。因此,当您从Java调用此代码时,您必须显式添加所有隐式转换和隐式参数。如果你想知道它会是什么样子,你可以打开一个Scala REPL并使用//print <tab>
提示来看看你的代码在几次desugarings之后会是什么样子并且明确暗示。
例如,给定一些类型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友好的包装器。