Java(或Groovy)相当于Scala';s申请

Java(或Groovy)相当于Scala';s申请,java,groovy,Java,Groovy,在Scala中,如果有一个对象Foo具有apply(x:Int)我可以用Foo(42)来调用它(作为Foo.apply(42)) 可以在Java或Groovy中复制这一点吗?我原以为Groovy的调用的功能可能类似,但无论是def调用(intx)还是静态def调用(intx)都不会导致调用调用 编辑:根据请求添加示例DSL 典型/现有DSL:alter't'add'a'存储条(其中BAR是一个枚举)。 试图添加将取代上述BAR的内容,但会接受一个参数,但不会有太多语法差异,理想情况下:alter

在Scala中,如果有一个对象
Foo
具有
apply(x:Int)
我可以用
Foo(42)
来调用它(作为
Foo.apply(42)

可以在Java或Groovy中复制这一点吗?我原以为Groovy的
调用
的功能可能类似,但无论是
def调用(intx)
还是
静态def调用(intx)
都不会导致调用
调用

编辑:根据请求添加示例DSL

典型/现有DSL:
alter't'add'a'存储条
(其中
BAR
是一个枚举)。 试图添加将取代上述
BAR
的内容,但会接受一个参数,但不会有太多语法差异,理想情况下:
alter't'add'a'存储FOO(42)


我已经将FOO创建为一个具有接受int的构造函数的类-我现在要寻找的是一种通过
FOO(42)
调用该构造函数的方法,而不是
new FOO(42)
FOO.call(42)

Closure
在Groovy中有方法
call()
可以编写:

def action = { a, b = 1 -> println "$a and $b" }
action.call 1 // prints "1 and 1"
action( 1, 3 ) // prints "1 and 3"

在Java中,最接近的替代方法是
Runnable
:它不提供arg
run()
,但不能缺少人手Groovy中最简单的方法是在类上编写
静态调用()
方法,但它不能使
Clazz()
工作。这可能是一个错误,但我找不到关于它的吉拉

我建议使用闭包:

import groovy.transform.Canonical as C

@C class Bar { def bar }

@C class Baz { def baz }

A = { new Bar(bar: it) }

B = { new Baz(baz: it) }


assert A("wot") == new Bar(bar: "wot")
assert B("fuzz") == new Baz(baz: "fuzz")

更新:似乎类名在被调用方上下文中解析为静态方法调用,这是可行的(但在DSL中不可用):


更新2:根据您的DSL示例,删除paren是否可行

class FOO {}


def params = [:]

alter = { 
  params.alter = it
  [add : { 
      params.add = it
      [storing: { 
          params.clazz = it
          [:].withDefault { params.param = it }
      }]
  }]
}


alter 't' add 'a' storing FOO 42


assert params == [
  alter : 't',
  add   : 'a',
  clazz : FOO,
  param : '42'
]

很酷的问题,你能提供更多吗info@KickButtowski它适用于DSL,在DSL中,通常会调用枚举,但需要添加带参数的内容,因此它被实现为类而不是枚举。但理想情况下,我希望这个特殊情况下的DSL语法尽可能接近其他情况
FOO(42)
new FOO(42)
FOO更接近
FOO。call(42)
@Exupery你能发布一些DSL的例子吗?在这方面可能会有一些解决办法。一般来说,DSL是一个相当好的主意,但在弄乱了一些之后,我绝对不喜欢将某些语言贬抑成一种既不是原始语言也不是“自然语言”的混血儿。如果你要写一个DSL,为什么不自己去解析它呢?这样你就可以得到你想要的确切的语言,而不是一些随机的英语,比如text,语法奇怪的requireme.nts???@WillP添加的示例DSL也适用于类
class Foo{def call(x){println x};foo=新的foo();foo(42)
@cfrick comment应该是一个答案。@cfrick它能与static
call
一起工作吗?只是想知道这里是否可以使用完全相同的scala语法。@cfrick这更接近我要查找的内容,但需要它而无需实例化Foo@Opal简单地添加
static
似乎不起作用。另外,
call.metaClass.Foo
乍一看不起作用。使用
@Canonical
是无可挑剔的删除paren是完全可以的,但是您的示例重写了所有DSL,这绝对不是。我需要一个解决方案来处理
FOO 42
部分,该部分完全独立于任何其他内容。@Exupery是第一个使用闭包的例子,合适吗?是的,带闭包的那一个很合适!很抱歉昨天没有注意到这一点-我觉得我没有合适的位置来粘贴与
a={new Bar(Bar:it)}
相当的东西,但是再次查看它,我意识到我可以将其放入枚举的静态方法中(保存所有其他/正常的“FOO”),并将该方法命名为
FOO
。然后我当然意识到我可以用那种方法返回新的FOO(x)
,哈。谢谢你让我走上了正确的道路![您的答案明确地解决了我问题的一般/原始形式]
call()
也适用于枚举,如果这有任何帮助的话:
enum P{E;def call(){“wot”};断言P.E()=“wot”
class FOO {}


def params = [:]

alter = { 
  params.alter = it
  [add : { 
      params.add = it
      [storing: { 
          params.clazz = it
          [:].withDefault { params.param = it }
      }]
  }]
}


alter 't' add 'a' storing FOO 42


assert params == [
  alter : 't',
  add   : 'a',
  clazz : FOO,
  param : '42'
]