O
- the receiver type of the executableR
- the return type of the executablepublic class ExecutableToken<O,R> extends java.lang.Object implements MemberToken<O,ExecutableToken<O,R>>
A type safe wrapper around Executable
instances, with proper handling
of generic methods, and methods on generic classes.
executable members
may be created over types which
mention inference variables, or even over inference variables themselves.
Modifier | Constructor and Description |
---|---|
protected |
ExecutableToken(java.lang.Class<?> instance,
java.lang.reflect.Constructor<?> constructor) |
protected |
ExecutableToken(java.lang.Class<?> instance,
java.lang.reflect.Method method) |
Modifier and Type | Method and Description |
---|---|
ExecutableToken<O,R> |
asVariableArityInvocation() |
static ExecutableToken<java.lang.Void,?> |
forConstructor(java.lang.reflect.Constructor<?> constructor)
Create a new
ExecutableToken instance from a reference to a
Constructor of an outer or static class. |
static ExecutableToken<?,?> |
forExecutable(java.lang.reflect.Executable executable) |
static ExecutableToken<?,?> |
forInnerConstructor(java.lang.reflect.Constructor<?> constructor)
Create a new
ExecutableToken instance from a reference to a
Constructor of an inner class. |
static ExecutableToken<?,?> |
forMethod(java.lang.reflect.Method method)
Create a new
ExecutableToken instance from a reference to an instance
Method . |
static ExecutableToken<java.lang.Void,?> |
forStaticMethod(java.lang.reflect.Method method)
Create a new
ExecutableToken instance from a reference to a static
Method . |
BoundSet |
getBounds() |
java.lang.reflect.Executable |
getMember() |
java.lang.String |
getName() |
java.util.stream.Stream<ExecutableToken<O,? super R>> |
getOverridden() |
<U> ExecutableToken<U,R> |
getOverride(TypeToken<U> type)
Get the overriding method in the given type, or the same method if there is
no override.
|
java.util.Optional<TypeToken<?>> |
getOwningDeclaration() |
java.util.stream.Stream<ExecutableParameter> |
getParameters() |
java.util.List<ExecutableParameter> |
getParametersImpl() |
TypeToken<? super O> |
getReceiverType()
This is the exact receiver type which this member should be accessed from or
invoked upon.
|
TypeToken<? extends R> |
getReturnType() |
java.util.stream.Stream<TypeArgument<?>> |
getTypeArguments() |
int |
getTypeParameterCount() |
java.util.stream.Stream<TypeParameter<?>> |
getTypeParameters() |
ExecutableToken<? extends O,R> |
infer()
If the invocation is raw, the target type and method are parameterized with
inference variables.
|
R |
invoke(O receiver,
java.util.List<? extends java.lang.Object> arguments)
Invoke the wrapped
Executable on the given receiver and with the
given parameters. |
R |
invoke(O receiver,
java.lang.Object... arguments)
Invoke the wrapped
Executable on the given receiver and with the
given parameters. |
protected R |
invokeImpl(O receiver,
java.lang.Object[] arguments) |
R |
invokeSafely(O receiver,
java.util.List<? extends TypedObject<?>> arguments)
As
invoke(Object, Object...) , but with arguments passed with their
exact types, meaning full type checking can be performed at runtime. |
R |
invokeSafely(O receiver,
TypedObject<?>... arguments)
As
invoke(Object, Object...) , but with arguments passed with their
exact types, meaning full type checking can be performed at runtime. |
boolean |
isAbstract() |
boolean |
isConstructor() |
boolean |
isGeneric() |
boolean |
isMethod() |
boolean |
isNative() |
boolean |
isRaw() |
boolean |
isStrict() |
boolean |
isSynchronized() |
boolean |
isVariableArityDefinition() |
boolean |
isVariableArityInvocation()
Check whether the executable is flagged to be invoked with varargs.
|
ExecutableToken<? extends O,R> |
parameterize()
If the declaration is raw, parameterize it with its own type parameters,
otherwise return the declaration itself.
|
ExecutableToken<O,R> |
resolve()
Derived a new
ExecutableToken instance with generic method parameters
inferred, and if this is a member of a generic type, with generic type
parameters inferred, too. |
static java.util.stream.Stream<ExecutableToken<java.lang.Void,?>> |
staticMethods(java.lang.Class<?> declaringClass)
Find which methods can be invoked on this type, whether statically or on
instances.
|
java.lang.String |
toString() |
ExecutableToken<O,R> |
withAllTypeArguments(java.util.List<java.lang.reflect.Type> typeArguments)
Derive a new
DeclarationToken instance with the given type argument
parameterization. |
ExecutableToken<? extends O,R> |
withAllTypeArguments(java.lang.reflect.Type... typeArguments) |
ExecutableToken<O,R> |
withBounds(BoundSet bounds)
Derive a new
ExecutableToken instance, with the given bounds
incorporated into the bounds of the underlying resolver. |
ExecutableToken<O,R> |
withLooseApplicability(java.util.Collection<? extends TypeToken<?>> arguments)
Derive a new
ExecutableToken instance with inferred invocation type
such that it is compatible with the given arguments in a loose invocation
context. |
ExecutableToken<O,R> |
withLooseApplicability(TypeToken<?>... arguments)
Derive a new
ExecutableToken instance with inferred invocation type
such that it is compatible with the given arguments in a loose invocation
context. |
ExecutableToken<?,R> |
withReceiverType(java.lang.reflect.Type type)
|
<U> ExecutableToken<U,R> |
withReceiverType(TypeToken<U> type)
Derive a new instance of
MemberToken with the given owner type. |
ExecutableToken<O,R> |
withStrictApplicability(java.util.Collection<? extends TypeToken<?>> arguments)
Derive a new
ExecutableToken instance with inferred invocation type
such that it is compatible with the given arguments in a strict invocation
context. |
ExecutableToken<O,R> |
withStrictApplicability(TypeToken<?>... arguments)
Derive a new
ExecutableToken instance with inferred invocation type
such that it is compatible with the given arguments in a strict invocation
context. |
<S> ExecutableToken<O,S> |
withTargetType(java.lang.Class<S> target)
As @see
withTargetType(TypeToken) . |
ExecutableToken<O,?> |
withTargetType(java.lang.reflect.Type target) |
<S> ExecutableToken<O,S> |
withTargetType(TypeToken<S> target)
Derive a new instance of
ExecutableToken with the given target type. |
ExecutableToken<O,R> |
withTypeArguments(java.util.Collection<? extends TypeArgument<?>> arguments)
Derive a new
ExecutableToken instance from this, with types
substituted according to the given arguments. |
ExecutableToken<? extends O,R> |
withTypeArguments(java.util.List<java.lang.reflect.Type> typeArguments)
As @see
DeclarationToken.withAllTypeArguments(List) , but only providing arguments for
the parameters occurring directly on the declaration. |
ExecutableToken<? extends O,R> |
withTypeArguments(java.lang.reflect.Type... typeArguments) |
protected ExecutableToken<O,R> |
withTypeSubstitution(BoundSet bounds,
TypeSubstitution typeSubstitution) |
ExecutableToken<O,R> |
withVariableArityApplicability(java.util.Collection<? extends TypeToken<?>> arguments)
Derive a new
ExecutableToken instance with inferred invocation type
such that it is compatible with the given arguments in a variable arity
invocation context. |
ExecutableToken<O,R> |
withVariableArityApplicability(TypeToken<?>... arguments)
Derive a new
ExecutableToken instance with inferred invocation type
such that it is compatible with the given arguments in a variable arity
invocation context. |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
getDeclaringClass, getVisibility, isFinal, isStatic
getAllTypeArguments, getAllTypeParameterCount, getAllTypeParameters, resolveTypeArgument, resolveTypeArgument, withTypeArguments
protected ExecutableToken(java.lang.Class<?> instance, java.lang.reflect.Constructor<?> constructor)
protected ExecutableToken(java.lang.Class<?> instance, java.lang.reflect.Method method)
public static ExecutableToken<java.lang.Void,?> forConstructor(java.lang.reflect.Constructor<?> constructor)
ExecutableToken
instance from a reference to a
Constructor
of an outer or static class.
If the method is generic it will be parameterized with its own type variables.
constructor
- the constructor to wrappublic static ExecutableToken<?,?> forInnerConstructor(java.lang.reflect.Constructor<?> constructor)
ExecutableToken
instance from a reference to a
Constructor
of an inner class.
If the constructor or the enclosing class are generic they will be parameterized with their own type variables.
constructor
- the constructor to wrappublic static ExecutableToken<java.lang.Void,?> forStaticMethod(java.lang.reflect.Method method)
ExecutableToken
instance from a reference to a static
Method
.
If the method is generic it will be parameterized with its own type variables.
method
- the method to wrappublic static ExecutableToken<?,?> forMethod(java.lang.reflect.Method method)
ExecutableToken
instance from a reference to an instance
Method
.
If the method or its declaring class are generic they will be parameterized with their own type variables.
method
- the method to wrappublic static ExecutableToken<?,?> forExecutable(java.lang.reflect.Executable executable)
public ExecutableToken<? extends O,R> infer()
If the invocation is already parameterized, the existing arguments are substituted according to their type. Bounds are incorporated according to those present on the type variables each argument instantiates.
public boolean isRaw()
isRaw
in interface DeclarationToken<ExecutableToken<O,R>>
isRaw
in interface MemberToken<O,ExecutableToken<O,R>>
public ExecutableToken<? extends O,R> parameterize()
public java.lang.reflect.Executable getMember()
getMember
in interface MemberToken<O,ExecutableToken<O,R>>
Member
object backing the MemberToken
.public java.util.Optional<TypeToken<?>> getOwningDeclaration()
getOwningDeclaration
in interface DeclarationToken<ExecutableToken<O,R>>
public java.lang.String getName()
getName
in interface MemberToken<O,ExecutableToken<O,R>>
public BoundSet getBounds()
getBounds
in interface MemberToken<O,ExecutableToken<O,R>>
MemberToken
public java.lang.String toString()
toString
in class java.lang.Object
public boolean isAbstract()
public boolean isNative()
public boolean isConstructor()
public boolean isMethod()
public boolean isStrict()
public boolean isSynchronized()
public boolean isGeneric()
isGeneric
in interface DeclarationToken<ExecutableToken<O,R>>
public boolean isVariableArityDefinition()
public boolean isVariableArityInvocation()
invocation
will be made by putting trailing
arguments into an array as per Java variable arity method invocation rules.public ExecutableToken<O,R> asVariableArityInvocation()
ExecutableToken
flagged to be invoked with
variable arity
public TypeToken<? super O> getReceiverType()
MemberToken
For non-static members, this type will be identical to the
owning type
.
For constructors and static members, if they are declared on a non-static inner class then the receiver type should be a subtype of the enclosing class, otherwise the receiver type should be void.
getReceiverType
in interface MemberToken<O,ExecutableToken<O,R>>
void.class
if the member has no receiver typepublic TypeToken<? extends R> getReturnType()
public java.util.stream.Stream<ExecutableParameter> getParameters()
public java.util.List<ExecutableParameter> getParametersImpl()
public ExecutableToken<O,R> withBounds(BoundSet bounds)
ExecutableToken
instance, with the given bounds
incorporated into the bounds of the underlying resolver. The original
ExecutableToken
will remain unmodified.withBounds
in interface MemberToken<O,ExecutableToken<O,R>>
bounds
- The new bounds to incorporate.ExecutableToken
.public ExecutableToken<? extends O,R> withTypeArguments(java.lang.reflect.Type... typeArguments)
withTypeArguments
in interface DeclarationToken<ExecutableToken<O,R>>
DeclarationToken.withTypeArguments(List)
public ExecutableToken<? extends O,R> withAllTypeArguments(java.lang.reflect.Type... typeArguments)
withAllTypeArguments
in interface DeclarationToken<ExecutableToken<O,R>>
DeclarationToken.withTypeArguments(List)
public ExecutableToken<? extends O,R> withTypeArguments(java.util.List<java.lang.reflect.Type> typeArguments)
DeclarationToken
DeclarationToken.withAllTypeArguments(List)
, but only providing arguments for
the parameters occurring directly on the declaration.withTypeArguments
in interface DeclarationToken<ExecutableToken<O,R>>
public ExecutableToken<O,R> withAllTypeArguments(java.util.List<java.lang.reflect.Type> typeArguments)
DeclarationToken
DeclarationToken
instance with the given type argument
parameterization.
The types in the given list correspond, in order, to the
type parameters
of this declaration. The current
parameterization of the declaration is substituted for that given.
Each substitution will only succeed if it is compatible with the bounds on
that type variable, and if it is more specific than the current argument,
whether it is an InferenceVariable
, a TypeVariableCapture
, or
another kind of Type
.
This behavior is different from DeclarationToken.withTypeArguments(Collection)
, which
performs a substitution for arbitrary type variables rather than
re-instantiating every parameter on the declaration.
withAllTypeArguments
in interface DeclarationToken<ExecutableToken<O,R>>
typeArguments
- a list of arguments for each generic type parameter of the
underlying declarationDeclarationToken
instance with the given
instantiations substituted for each generic type parameter, in orderpublic ExecutableToken<?,R> withReceiverType(java.lang.reflect.Type type)
MemberToken
withReceiverType
in interface MemberToken<O,ExecutableToken<O,R>>
public <U> ExecutableToken<U,R> withReceiverType(TypeToken<U> type)
MemberToken
MemberToken
with the given owner type.
The new MemberToken
will always have a owner type which is as or more
specific than both the current receiver type and the given type.
This means that the new owner will be assignment compatible with the given
type, but if the given type contains wildcards or inference variables which
are less specific that those implied by the current receiver type,
new type arguments will be inferred in their place, or further bounds may be
added to them.
If the receiver type is not generic, the method will always return the same token, or will throw an exception if the given type is not a subtype of the receiver.
This may result in unsafe transformations when we convert from a raw receiver to a parameterized receiver, but declarations of those types should give a raw type warning from the Java compiler and this is considered sufficient.
withReceiverType
in interface MemberToken<O,ExecutableToken<O,R>>
type
- The new owner type. The raw type of this type must be a subtype of
the raw type of the current receiver type.MemberToken
compatible with the given owner type.
The new owner type will not be effectively more specific than the intersection type of the current owner type and the given type. That is, any type which can be assigned to both the given type and the current owner type, will also be assignable to the new type.
public <S> ExecutableToken<O,S> withTargetType(java.lang.Class<S> target)
withTargetType(TypeToken)
.public ExecutableToken<O,?> withTargetType(java.lang.reflect.Type target)
public <S> ExecutableToken<O,S> withTargetType(TypeToken<S> target)
ExecutableToken
with the given target type.
The new ExecutableToken
will always have a target type which is as or
more specific than both the current target type and the given type.
This means that the new target will be assignment compatible with the given
type, but if the given type contains wildcards or inference variables which
are less specific that those implied by the current target type, new
type arguments will be inferred in their place, or further bounds may be
added to them.
S
- The derived ExecutableToken
must be assignment compatible
with this type.target
- The derived ExecutableToken
must be assignment compatible
with this type.ExecutableToken
compatible with the given target type.
The new target type will not be effectively more specific than the intersection type of the current target type and the given type. That is, any type which can be assigned to both the given type and the current target type, will also be assignable to the new type.
public <U> ExecutableToken<U,R> getOverride(TypeToken<U> type)
U
- the type possibly containing the overridetype
- the type possibly containing the overridepublic java.util.stream.Stream<ExecutableToken<O,? super R>> getOverridden()
public ExecutableToken<O,R> resolve()
ExecutableToken
instance with generic method parameters
inferred, and if this is a member of a generic type, with generic type
parameters inferred, too.resolve
in interface MemberToken<O,ExecutableToken<O,R>>
ExecutableToken
with inferred invocation type.public ExecutableToken<O,R> withStrictApplicability(TypeToken<?>... arguments)
ExecutableToken
instance with inferred invocation type
such that it is compatible with the given arguments in a strict invocation
context. Where necessary, the derived ExecutableToken
may infer new
bounds or instantiations on type parameters.arguments
- The argument types of an invocation of this ExecutableToken
.ExecutableToken
.public ExecutableToken<O,R> withStrictApplicability(java.util.Collection<? extends TypeToken<?>> arguments)
ExecutableToken
instance with inferred invocation type
such that it is compatible with the given arguments in a strict invocation
context. Where necessary, the derived ExecutableToken
may infer new
bounds or instantiations on type parameters.arguments
- The argument types of an invocation of this ExecutableToken
.ExecutableToken
.public ExecutableToken<O,R> withLooseApplicability(TypeToken<?>... arguments)
ExecutableToken
instance with inferred invocation type
such that it is compatible with the given arguments in a loose invocation
context. Where necessary, the derived ExecutableToken
may infer new
bounds or instantiations on type parameters.arguments
- The argument types of an invocation of this ExecutableToken
.ExecutableToken
.public ExecutableToken<O,R> withLooseApplicability(java.util.Collection<? extends TypeToken<?>> arguments)
ExecutableToken
instance with inferred invocation type
such that it is compatible with the given arguments in a loose invocation
context. Where necessary, the derived ExecutableToken
may infer new
bounds or instantiations on type parameters.arguments
- The argument types of an invocation of this ExecutableToken
.ExecutableToken
.public ExecutableToken<O,R> withVariableArityApplicability(TypeToken<?>... arguments)
ExecutableToken
instance with inferred invocation type
such that it is compatible with the given arguments in a variable arity
invocation context. Where necessary, the derived ExecutableToken
may
infer new bounds or instantiations on type parameters.arguments
- The argument types of an invocation of this ExecutableToken
.ExecutableToken
.public ExecutableToken<O,R> withVariableArityApplicability(java.util.Collection<? extends TypeToken<?>> arguments)
ExecutableToken
instance with inferred invocation type
such that it is compatible with the given arguments in a variable arity
invocation context. Where necessary, the derived ExecutableToken
may
infer new bounds or instantiations on type parameters.arguments
- The argument types of an invocation of this ExecutableToken
.ExecutableToken
.public java.util.stream.Stream<TypeParameter<?>> getTypeParameters()
getTypeParameters
in interface DeclarationToken<ExecutableToken<O,R>>
Executable
, or their inference variables if not yet
instantiated.public java.util.stream.Stream<TypeArgument<?>> getTypeArguments()
getTypeArguments
in interface DeclarationToken<ExecutableToken<O,R>>
Executable
, or their inference variables if not yet
instantiated.public int getTypeParameterCount()
getTypeParameterCount
in interface DeclarationToken<ExecutableToken<O,R>>
public ExecutableToken<O,R> withTypeArguments(java.util.Collection<? extends TypeArgument<?>> arguments)
DeclarationToken
ExecutableToken
instance from this, with types
substituted according to the given arguments.
More specifically, each of the given arguments represents a type variable and an instantiation for that type variable. Occurrences of those type variables in the declaration will be substituted for their instantiations in the derived declaration.
The substitution will only succeed if it results in a valid parameterization of the declaration.
For example, the following method could be used to derive instances of
TypeToken over different parameterizations of List<?>
at runtime.
public TypeToken<List<T>> getListType(TypeToken<T> elementType)} {
return new TypeToken<T>()} {}.withTypeArguments(new TypeParameter<T>() {}.as(elementType));
}
withTypeArguments
in interface DeclarationToken<ExecutableToken<O,R>>
arguments
- the type variable instantiationsExecutableToken
instance with the given
instantiation substituted for the given type variableprotected ExecutableToken<O,R> withTypeSubstitution(BoundSet bounds, TypeSubstitution typeSubstitution)
public R invoke(O receiver, java.lang.Object... arguments)
Executable
on the given receiver and with the
given parameters. The receiver will be ignored for static methods or
constructors. Variable arity invocation is not attempted.
Due to erasure of the types of the arguments, there is a limit to what type
checking can be performed at runtime. For type safe invocation, wrap
arguments in TypedObject
instances and use an overload of
invokeSafely(Object, TypedObject...)
instead.
receiver
- the receiving object for the invocation. This parameter will be
ignored in the case of a constructor invocation or other static
method invocationarguments
- the argument list for the invocationpublic R invoke(O receiver, java.util.List<? extends java.lang.Object> arguments)
Executable
on the given receiver and with the
given parameters. The receiver will be ignored for static methods or
constructors. Variable arity invocation is not attempted.
Due to erasure of the types of the arguments, there is a limit to what type
checking can be performed at runtime. For type safe invocation, wrap
arguments in TypedObject
instances and use an overload of
invokeSafely(Object, TypedObject...)
instead.
receiver
- the receiving object for the invocation. This parameter will be
ignored in the case of a constructor invocation or other static
method invocationarguments
- the argument list for the invocationprotected R invokeImpl(O receiver, java.lang.Object[] arguments) throws java.lang.InstantiationException, java.lang.IllegalAccessException, java.lang.IllegalArgumentException, java.lang.reflect.InvocationTargetException
java.lang.InstantiationException
java.lang.IllegalAccessException
java.lang.IllegalArgumentException
java.lang.reflect.InvocationTargetException
public R invokeSafely(O receiver, TypedObject<?>... arguments)
As invoke(Object, Object...)
, but with arguments passed with their
exact types, meaning full type checking can be performed at runtime. Also,
here it is possible to determine whether the invocation is intended to be
variable arity, and if so an attempt is made to invoke as such.
If the expected parameter types of this executable member contain inference variables or type variable captures, an attempt will be made to satisfy their bounds according to the given argument types.
receiver
- the receiving object for the invocation. This parameter will be
ignored in the case of a constructor invocation or other static
method invocationarguments
- the typed argument list for the invocationpublic R invokeSafely(O receiver, java.util.List<? extends TypedObject<?>> arguments)
As invoke(Object, Object...)
, but with arguments passed with their
exact types, meaning full type checking can be performed at runtime. Also,
here it is possible to determine whether the invocation is intended to be
variable arity, and if so an attempt is made to invoke as such.
If the expected parameter types of this executable member contain inference variables or type variable captures, an attempt will be made to satisfy their bounds according to the given argument types.
receiver
- the receiving object for the invocation. This parameter will be
ignored in the case of a constructor invocation or other static
method invocationarguments
- the typed argument list for the invocationpublic static java.util.stream.Stream<ExecutableToken<java.lang.Void,?>> staticMethods(java.lang.Class<?> declaringClass)
declaringClass
- the declaring class for which to retrieve the methodsMethod
objects applicable to this type, wrapped in
ExecutableToken
instances