I tried to do:
public class HelloWorld {
public static void main(String... args){
final String string = "a";
final Supplier<?> supplier = string::isEmpty;
System.out.println(supplier);
}
}
I get:
HelloWorld$$Lambda$1/471910020@548c4f57
I would like to get the string isEmpty
. How can I do this?
EDIT: the code of the method I created is this one:
public class EnumHelper {
private final static String values = "values";
private final static String errorTpl = "Can't find element with value `{0}` for enum {1} using getter {2}()";
public static <T extends Enum<T>, U> T getFromValue(T enumT, U value, String getter) {
@SuppressWarnings("unchecked")
final T[] elements = (T[]) ReflectionHelper.callMethod(enumT, values);
for (final T enm: elements) {
if (ReflectionHelper.callMethod(enm, getter).equals(value)) {
return enm;
}
}
throw new InvalidParameterException(MessageFormat.format(errorTpl, value, enumT, getter));
}
}
The problem is I can't pass as parameter T::getValue, since getValue is not static. And I can't pass someEnumElem::getValue, since the get()
will return the value of that element. I could use inside the for loop:
Supplier<U> getterSupllier = enm:getValue;
if (getterSupllier.get().equals(value)) {
[...]
}
but in this way getValue
is fixed, I can't pass it as parameter. I could use some third-party library to do an eval()
, but I really don't want to open that Pandora vase :D
EDIT 2: Function
does work with no parameters methods, but only in Java
11. Unluckily I'm stuck with Java
8.
Method Class | getName() Method in Java Method class is helpful to get the name of methods, as a String. To get name of all methods of a class, get all the methods of that class object. Then call getName() on those method objects. Return Value: It returns the name of the method, as String.
getMethodName() method returns the name of the method containing the execution point represented by this stack trace element. Thread. currentThread().
util. function package which has been introduced since Java 8, to implement functional programming in Java. It represents a function which takes in one argument and produces a result.
Method Class | getName() Method in Java. The getName() method of java.lang.reflect.Method class is helpful to get the name of methods, as a String. To get name of all methods of a class, get all the methods of that class object. Then call getName() on those method objects. Syntax: Return Value: It returns the name of the method, as String.
Getting name of currently executing method is useful for handling exceptions and debugging purposes. Below are different methods to get currently executing method : Using Throwable Stack Trace : Using Throwable Class : In Java, Throwable class is the superclass of all exceptions and errors in java.lang package.
It uses examples to show how the apply (), andThen (), compose () & identity () methods of the Function interface are to be used. Function<T, R> is an in-built functional interface introduced in Java 8 in the java.util.function package.
The getName () method of java.lang.reflect .Method class is helpful to get the name of methods, as a String. To get name of all methods of a class, get all the methods of that class object.
It’s weird that you are asking about the opposite of what you actually need.
You have a method that receives a string and wants to execute a method with that name, but for some unknown reason, you ask for the opposite, to get the method name from an existing supplier.
And already written in a comment before knowing the actual code, you can solve the actual problem by replacing the String getter
parameter with Function<T,U> getter
.
You don’t need any Reflection tool here:
public class EnumHelper {
private final static String errorTpl
= "Can't find element with value `{0}` for enum {1} using getter {2}()";
public static <T extends Enum<T>, U> T getFromValue(
T enumT, U value, Function<? super T, ?> getter) {
final T[] elements = enumT.getDeclaringClass().getEnumConstants();
for (final T enm: elements) {
if(getter.apply(enm).equals(value)) {
return enm;
}
}
throw new IllegalArgumentException(
MessageFormat.format(errorTpl, value, enumT, getter));
}
}
The getter Function
can be implemented via method reference, e.g.
ChronoUnit f = EnumHelper.getFromValue(
ChronoUnit.FOREVER, Duration.ofMinutes(60), ChronoUnit::getDuration);
System.out.println(f);
I made the signature of the function parameter more generous compared to Function<T,U>
, to raise the flexibility regarding existing functions, e.g.
Function<Object,Object> func = Object::toString;
ChronoUnit f1 = EnumHelper.getFromValue(ChronoUnit.FOREVER, "Years", func);
System.out.println(f1.name());
If printing meaningful names in the erroneous case is really important, just add a name parameter just for reporting:
public static <T extends Enum<T>, U> T getFromValue(
T enumT, U value, Function<? super T, ?> getter, String getterName) {
final T[] elements = enumT.getDeclaringClass().getEnumConstants();
for (final T enm: elements) {
if(getter.apply(enm).equals(value)) {
return enm;
}
}
throw new IllegalArgumentException(
MessageFormat.format(errorTpl, value, enumT, getterName));
}
to be called like
ChronoUnit f = EnumHelper.getFromValue(
ChronoUnit.FOREVER, Duration.ofMinutes(60), ChronoUnit::getDuration, "getDuration");
That’s still better than using Reflection for the normal operations…
string::isEmpty
will be constructed by a method LambdaMetafactory.metafactory
which has implMethod
among its parameters.
final String methodName = implMethod.internalMemberName().getName();
would return a method name (here, "isEmpty"
) if we had access to the arguments passed to this factory method, and to implMethod
in particular. The arguments generated by up-calls from the JVM that provides very specific information for the java.lang.invoke
API.
For example, to initialise a DirectMethodHandle
which string::isEmpty
represents, the JVM will call the following method.
/**
* The JVM is resolving a CONSTANT_MethodHandle CP entry. And it wants our help.
* It will make an up-call to this method. (Do not change the name or signature.)
* The type argument is a Class for field requests and a MethodType for non-fields.
* <p>
* Recent versions of the JVM may also pass a resolved MemberName for the type.
* In that case, the name is ignored and may be null.
*/
static MethodHandle linkMethodHandleConstant(Class<?> callerClass, int refKind,
Class<?> defc, String name, Object type)
That name
(exactly what you requested) will be put there by the JVM, and there is no means for us to access it. For now.
To read:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With