Class ELMethodRegistry
ELMethodContributor makes callable from
expressions parsed at runtime, and turns them into an ELMethodExecutor that dispatches them
directly, without reflection.
A registration carries the declared signature next to the code that runs it. The signature is what the
specification needs and what a method reference cannot supply on its own — the overload selection of the
section 1.6, the coercions of the section 1.23 and the metadata of a jakarta.el.MethodExpression
are all defined in terms of the declared parameter types:
registry.method(Book.class, "discounted", double.class, Integer.class, Book::discounted)
.staticMethod(Math.class, "abs", int.class, int.class, Math::abs)
.constructor(Book.class, String.class, Book::new);
The methods a registration produces are reusable: they hold the signature and the invocation, never the arguments they were resolved with, so the interpreter resolves a call site once and re-invokes the same method on every later evaluation. Only a name carrying several overloads is resolved again per call, since the arguments then decide which one applies.
- Since:
- 1.1
- Author:
- Denis Stepanov
- See Also:
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic interfaceInvokes an instance method taking no argument.static interfaceInvokes an instance method taking one argument.static interfaceInvokes an instance method taking two arguments.static interfaceInvokes a static method, a constructor or a function taking no argument.static interfaceInvokes a static method, a constructor or a function taking one argument.static interfaceInvokes a static method, a constructor or a function taking two arguments.static interfaceInvokes a registered method of any arity.static interfaceBuilds an instance of a functional interface that runs a lambda expression. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionbuild(int order) Builds the executor dispatching everything registered so far.constructor(Class<?> type, Class<?>[] parameterTypes, boolean varArgs, ELMethodRegistry.Invocation invocation) Registers a constructor of any arity, callable asType(arguments).<A,T> ELMethodRegistry constructor(Class<T> type, Class<A> first, ELMethodRegistry.Fn1<A, T> call) Registers a constructor taking one argument, callable asType(argument).function(String prefix, String localName, Class<?> declaringType, String methodName, Class<?> returnType, Class<?>[] parameterTypes, boolean varArgs, ELMethodRegistry.Invocation invocation) Registers a function, callable asprefix:localName(arguments), or aslocalName(arguments)when the prefix is empty.<A,R> ELMethodRegistry function(String prefix, String localName, Class<?> declaringType, String methodName, Class<R> returnType, Class<A> first, ELMethodRegistry.Fn1<A, R> call) Registers a function taking one argument.@Nullable ELMethodRegistry.Lambda<?> functionalInterface(Class<?> type) The registration presenting a lambda expression as the given functional interface.<T> ELMethodRegistryfunctionalInterface(Class<T> type, ELMethodRegistry.Lambda<T> factory) Registers how a lambda expression is presented as an instance of a functional interface the application declares, which is the coercion of the section 1.23.2 of the specification.booleanisEmpty()Whether nothing has been registered.method(Class<?> type, String name, Class<?> returnType, Class<?>[] parameterTypes, boolean varArgs, ELMethodRegistry.Invocation invocation) Registers an instance method of any arity, including one of variable arity.method(Class<?> type, String name, Class<?> returnType, Class<?>[] parameterTypes, boolean varArgs, Annotation[] annotations, ELMethodRegistry.Invocation invocation) Registers an instance method carrying annotations, which ajakarta.el.MethodExpressionreports throughjakarta.el.MethodReference.<T,R> ELMethodRegistry method(Class<T> type, String name, Class<R> returnType, ELMethodRegistry.Call0<T, R> call) Registers an instance method taking no argument.<T,A, R> ELMethodRegistry method(Class<T> type, String name, Class<R> returnType, Class<A> first, ELMethodRegistry.Call1<T, A, R> call) Registers an instance method taking one argument.<T,A, B, R> ELMethodRegistry method(Class<T> type, String name, Class<R> returnType, Class<A> first, Class<B> second, ELMethodRegistry.Call2<T, A, B, R> call) Registers an instance method taking two arguments.staticMethod(Class<?> type, String name, Class<?> returnType, Class<?>[] parameterTypes, boolean varArgs, ELMethodRegistry.Invocation invocation) Registers a static method of any arity, including one of variable arity.<R> ELMethodRegistrystaticMethod(Class<?> type, String name, Class<R> returnType, ELMethodRegistry.Fn0<R> call) Registers a static method taking no argument.<A,R> ELMethodRegistry staticMethod(Class<?> type, String name, Class<R> returnType, Class<A> first, ELMethodRegistry.Fn1<A, R> call) Registers a static method taking one argument.<A,B, R> ELMethodRegistry staticMethod(Class<?> type, String name, Class<R> returnType, Class<A> first, Class<B> second, ELMethodRegistry.Fn2<A, B, R> call) Registers a static method taking two arguments.
-
Constructor Details
-
ELMethodRegistry
public ELMethodRegistry()Creates an empty registry.
-
-
Method Details
-
method
public <T,R> ELMethodRegistry method(Class<T> type, String name, Class<R> returnType, ELMethodRegistry.Call0<T, R> call) Registers an instance method taking no argument.- Type Parameters:
T- The type declaring the methodR- The return type- Parameters:
type- The type declaring the methodname- The name the expression calls it byreturnType- The declared return typecall- The invocation- Returns:
- This registry
-
method
public <T,A, ELMethodRegistry methodR> (Class<T> type, String name, Class<R> returnType, Class<A> first, ELMethodRegistry.Call1<T, A, R> call) Registers an instance method taking one argument.- Type Parameters:
T- The type declaring the methodA- The type of the argumentR- The return type- Parameters:
type- The type declaring the methodname- The name the expression calls it byreturnType- The declared return typefirst- The declared type of the argumentcall- The invocation- Returns:
- This registry
-
method
public <T,A, ELMethodRegistry methodB, R> (Class<T> type, String name, Class<R> returnType, Class<A> first, Class<B> second, ELMethodRegistry.Call2<T, A, B, R> call) Registers an instance method taking two arguments.- Type Parameters:
T- The type declaring the methodA- The type of the first argumentB- The type of the second argumentR- The return type- Parameters:
type- The type declaring the methodname- The name the expression calls it byreturnType- The declared return typefirst- The declared type of the first argumentsecond- The declared type of the second argumentcall- The invocation- Returns:
- This registry
-
method
public ELMethodRegistry method(Class<?> type, String name, Class<?> returnType, Class<?>[] parameterTypes, boolean varArgs, ELMethodRegistry.Invocation invocation) Registers an instance method of any arity, including one of variable arity.The arguments reach the invocation coerced to
parameterTypes, the variable arity ones packed into an array of the component type of the last parameter.- Parameters:
type- The type declaring the methodname- The name the expression calls it byreturnType- The declared return typeparameterTypes- The declared parameter typesvarArgs- Whether the last parameter is of variable arity, which requires it to be an arrayinvocation- The invocation- Returns:
- This registry
-
method
public ELMethodRegistry method(Class<?> type, String name, Class<?> returnType, Class<?>[] parameterTypes, boolean varArgs, Annotation[] annotations, ELMethodRegistry.Invocation invocation) Registers an instance method carrying annotations, which ajakarta.el.MethodExpressionreports throughjakarta.el.MethodReference.- Parameters:
type- The type declaring the methodname- The name the expression calls it byreturnType- The declared return typeparameterTypes- The declared parameter typesvarArgs- Whether the last parameter is of variable arity, which requires it to be an arrayannotations- The annotations declared on the methodinvocation- The invocation- Returns:
- This registry
-
staticMethod
public <R> ELMethodRegistry staticMethod(Class<?> type, String name, Class<R> returnType, ELMethodRegistry.Fn0<R> call) Registers a static method taking no argument.- Type Parameters:
R- The return type- Parameters:
type- The type declaring the methodname- The name the expression calls it byreturnType- The declared return typecall- The invocation- Returns:
- This registry
-
staticMethod
public <A,R> ELMethodRegistry staticMethod(Class<?> type, String name, Class<R> returnType, Class<A> first, ELMethodRegistry.Fn1<A, R> call) Registers a static method taking one argument.- Type Parameters:
A- The type of the argumentR- The return type- Parameters:
type- The type declaring the methodname- The name the expression calls it byreturnType- The declared return typefirst- The declared type of the argumentcall- The invocation- Returns:
- This registry
-
staticMethod
public <A,B, ELMethodRegistry staticMethodR> (Class<?> type, String name, Class<R> returnType, Class<A> first, Class<B> second, ELMethodRegistry.Fn2<A, B, R> call) Registers a static method taking two arguments.- Type Parameters:
A- The type of the first argumentB- The type of the second argumentR- The return type- Parameters:
type- The type declaring the methodname- The name the expression calls it byreturnType- The declared return typefirst- The declared type of the first argumentsecond- The declared type of the second argumentcall- The invocation- Returns:
- This registry
-
staticMethod
public ELMethodRegistry staticMethod(Class<?> type, String name, Class<?> returnType, Class<?>[] parameterTypes, boolean varArgs, ELMethodRegistry.Invocation invocation) Registers a static method of any arity, including one of variable arity.- Parameters:
type- The type declaring the methodname- The name the expression calls it byreturnType- The declared return typeparameterTypes- The declared parameter typesvarArgs- Whether the last parameter is of variable arity, which requires it to be an arrayinvocation- The invocation, which receives anullbase- Returns:
- This registry
-
constructor
public <A,T> ELMethodRegistry constructor(Class<T> type, Class<A> first, ELMethodRegistry.Fn1<A, T> call) Registers a constructor taking one argument, callable asType(argument).- Type Parameters:
A- The type of the argumentT- The type to construct- Parameters:
type- The type to constructfirst- The declared type of the argumentcall- The invocation- Returns:
- This registry
-
constructor
public ELMethodRegistry constructor(Class<?> type, Class<?>[] parameterTypes, boolean varArgs, ELMethodRegistry.Invocation invocation) Registers a constructor of any arity, callable asType(arguments).- Parameters:
type- The type to constructparameterTypes- The declared parameter typesvarArgs- Whether the last parameter is of variable arity, which requires it to be an arrayinvocation- The invocation, which receives anullbase- Returns:
- This registry
-
function
public ELMethodRegistry function(String prefix, String localName, Class<?> declaringType, String methodName, Class<?> returnType, Class<?>[] parameterTypes, boolean varArgs, ELMethodRegistry.Invocation invocation) Registers a function, callable asprefix:localName(arguments), or aslocalName(arguments)when the prefix is empty.A function registered here replaces the
jakarta.el.FunctionMapperlookup, which is defined in terms ofjava.lang.reflect.Methodand therefore needs reflection.- Parameters:
prefix- The namespace prefix, empty for a function without onelocalName- The name within the namespacedeclaringType- The type declaring the method, which the identity of the expression is built frommethodName- The name of the method, which the metadata of the expression reportsreturnType- The declared return typeparameterTypes- The declared parameter typesvarArgs- Whether the last parameter is of variable arity, which requires it to be an arrayinvocation- The invocation, which receives anullbase- Returns:
- This registry
-
function
public <A,R> ELMethodRegistry function(String prefix, String localName, Class<?> declaringType, String methodName, Class<R> returnType, Class<A> first, ELMethodRegistry.Fn1<A, R> call) Registers a function taking one argument.- Type Parameters:
A- The type of the argumentR- The return type- Parameters:
prefix- The namespace prefix, empty for a function without onelocalName- The name within the namespacedeclaringType- The type declaring the method, which the identity of the expression is built frommethodName- The name of the method, which the metadata of the expression reportsreturnType- The declared return typefirst- The declared type of the argumentcall- The invocation- Returns:
- This registry
-
functionalInterface
Registers how a lambda expression is presented as an instance of a functional interface the application declares, which is the coercion of the section 1.23.2 of the specification.The coercion needs the single abstract method of the target interface. Where the compiler resolves the method being called it implements the interface itself, and the functional interfaces of the platform are implemented without reflection, so neither reaches here. What does is an interface of the application reached through a method the resolver chain selects at evaluation time: nothing knows it before the call, and without a registration a
java.lang.reflect.Proxystands in for it.registry.functionalInterface(TextMapper.class, (context, lambda) -> value -> (String) lambda.invoke(context, value));- Type Parameters:
T- The functional interface- Parameters:
type- The functional interfacefactory- The invocation building an instance of it- Returns:
- This registry
-
build
Builds the executor dispatching everything registered so far.The registrations are indexed by type and name, and the methods a type inherits from its supertypes and interfaces are merged into it, so a method registered on an interface is callable on every implementation. A constructor is not inherited, since it constructs the type it was registered for. The executor is immutable; later registrations do not reach it.
- Parameters:
order- The order of the executor among the others, seeOrdered- Returns:
- The executor
-
isEmpty
public boolean isEmpty()Whether nothing has been registered.- Returns:
- Whether the registry is empty
-
functionalInterface
The registration presenting a lambda expression as the given functional interface.- Parameters:
type- The functional interface- Returns:
- The registration, or
nullwhen nothing registered one
-