В библиотеке one-nio есть возможность компилировать Java код на лету. Это может быть нужно, когда вы хотите дать пользователю возможность задавать формулы для вычисления значений. Как-то мне нужно было посчитать вес тасков для отдачи пользователям по сложной формуле, которая зависела от квалификации пользователя и типа таска. Я решил эту задачу используя встроенный в jvm движок Nashorn. Писал куски кода на Javascript, компилировал и запускал в программе.

Можно обойтись без Javascript, если писать и компилировать прямо Java код:

package ru.yamakarov.gen;

import one.nio.compiler.CompilationException;
import one.nio.compiler.Javac;
import one.nio.gen.BytecodeGenerator;

public class FunctionScript {

    public static void main(String[] args) throws CompilationException {
        String template =
                "package ru.yamakarov.gen;\n" +
                "\n" +
                "public class GeneratedScales extends Scales {\n" +
                "    public int weight (Context context) {\n" +
                "        return %s;\n" +
                "    }\n" +
                "}";

        String functionStr = "context.multiplier * 10";
        byte[] classData = new Javac().compile(
                String.format(template, functionStr)
        );
        Scales myScales = new BytecodeGenerator().instantiate(classData, Scales.class);

        System.out.println(myScales.weight(new Context(10)));
    }

}

Можно писать в файле или в базе данных код функции:

String functionStr = "context.multiplier * 10";

Подставлять его в шаблон, расширяющий класс Scales:

package ru.yamakarov.gen;

public class Scales {
    public int weight (Context context) {
        return 0;
    }
}

Итоговый экземпляр myScales можно сохранять для повторного использования, чтобы сократить время вызова. Также в context можно передавать и другие параметры, кроме использованного мною multiplier:

package ru.yamakarov.gen;

public class Context {
    public int multiplier;

    public Context(int multiplier) {
        this.multiplier = multiplier;
    }
}

Я не проверял, но такой способ должен работать быстрее использования javascript движка, будет поддерживать jit оптимизации, в случае частого вызова метода, который был получен от пользователя и больше мне нравится.