mercredi 15 novembre 2017

How to replace relective method access by Java 1.8 functions?

Problem: We need to get a (String) key for different classes of objects. For expendability we want to configure the Method to use to get the key String – instead of implementing many if-else with intanceOf…

Naive solution (with example data) is:

public static String getKey(Object object, Map<Class<?>, Method> keySources) {
    Method source = keySources.get(object.getClass());

    if (source == null) {
        return null;
    }

    try {
        return (String) source.invoke(object);
    } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
        throw new RuntimeException("Error at 'invoke': " + e.getMessage(), e);
    }
}

public static void main(String[] args) {
    Map<Class<?>, Method> keySources = new HashMap<>();

    try {
        keySources.put(String.class, String.class.getMethod("toString"));
        keySources.put(Thread.class, Thread.class.getMethod("getName"));
    } catch (NoSuchMethodException | SecurityException e) {
        throw new RuntimeException("Error at 'getMethod': " + e.getMessage(), e);
    }

    System.out.println(getKey("test", keySources));
    System.out.println(getKey(new Thread("name"), keySources));
}

Desired solution would be like:

public static String getKey(Object object, Map<Class<?>, Function<Object, String>> keySources) {
    Function<Object, String> source = keySources.get(object.getClass());

    if (source == null) {
        return null;
    }

    return source.apply(object);
}

public static void main(String[] args) {
    Map<Class<?>, Function<Object, String>> keySources = new HashMap<>();

    keySources.put(String.class, String::toString);
    keySources.put(Thread.class, Thread::getName);

    System.out.println(getKey("test", keySources));
    System.out.println(getKey(new Thread("name"), keySources));
}

But String::toString is giving compilation error: The type String does not define toString(Object) that is applicable here

Constraints: We cannot modify the classes since they were generated.





Aucun commentaire:

Enregistrer un commentaire