Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get a Java 8 Lambda from a generic, a clazz and an interface?

I have a class that accepts a generic

public class Publisher<T extends Storable> {
    ...
} 

Objects of classes that extends Storable can be "published" (processed by this class).

In the constructor I also get information about the specific class that this instance if Publisher must handle

public Publisher(Class<T> clazz) {
    ...
}

In this constructor I check if the class also implements "Localized". If it does I want to store a lambda to a method defined in the Localized interface (in this example "getLocale()") The reason I want a lambda is for backward compatibility reasons, let's not focus on that design decision.

public class Publisher<T extends Storable> {

    private Function<T, Locale> localeGetter;

    public Publisher(Class<T> clazz) {
        if (Localized.class.isAssignableFrom(clazz)) {
            this.localeGetter = ???????;
        }
    }
}

All information should be there i think in order to set my lambda, but I cannot figure out how to code it. Is it possible?

Best Regards, Andreas

like image 663
Andreas Lundgren Avatar asked Jul 23 '26 17:07

Andreas Lundgren


1 Answers

Just recall how you would perform the operation with ordinary code, then put that code into a lambda expression:

if (Localized.class.isAssignableFrom(clazz)) {
    this.localeGetter = t -> ((Localized)t).getLocale();
}

Due to type erasure, you can’t utilize the fact the class has been parametrized with a type for T which implements Localized, however, that doesn’t hurt much, even if you could, the resulting code would contain the same type cast on the byte code level.

The only way to circumvent it would be to let the caller of the constructor provide the function (add a Function<T, Locale> parameter). But depending on the number of different callers that would not necessarily be a simplification.

like image 161
Holger Avatar answered Jul 26 '26 17:07

Holger