简体   繁体   中英

Java (or Groovy) equivalent of Scala's apply

In Scala if there is an object Foo that has apply(x: Int) I can call it with Foo(42) (as shorthand for Foo.apply(42) ).

Is it possible to replicate this in either Java or Groovy? I had thought maybe Groovy's call would function similar but neither def call(int x) or static def call(int x) resulted in calling call

EDIT : adding example DSL as requested

Typical/existing DSL: alter 't' add 'a' storing BAR (where BAR is an enum). Attempting to add something that will take the place of BAR in the above but will accept an argument, but without differing the syntax too much, ideally: alter 't' add 'a' storing FOO(42)

I've created FOO as a class with a constructor that accepts an int - what I'm looking for now is a way to call that constructor by FOO(42) instead of new FOO(42) or FOO.call(42)

The straightforward way in Groovy would be to write a static call() method on the class, but it doesn't make Clazz() work. It might be a bug, but i couldn't find a JIRA about it.

I'd like to suggest using closures:

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")

Update : seems like the class name is resolved as an static method call in the callee context, this works (but it's not usable in a DSL):

class A { 
    static call(str) { str.toUpperCase() } 
}
assert ((Class)A)("qwop") == "QWOP"

Update 2: As per your DSL example, would removing the parens be feasible?

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'
]

Closure in Groovy has method call() that can be ommitted:

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

In Java the closest alternative is the Runnable : it provides no-arg run() but cannot be short-handed

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM