Подтвердить что ты не робот

Может ли оптимизационный метод перераспределения быть оптимизирован JVM во время выполнения?

Может ли JVM выполнять оптимизацию времени выполнения в следующем сценарии?

У нас есть следующая ситуация: у нас есть этот интерфейс:

public interface ECSResource {
    default int getFor(final Entity entity) {
        return ResourceRetriever.forResource(this).getFor(entity);
    }
}

И конкретная реализация, такая как:

private static enum TestResources implements ECSResource {
    TR1, TR2;
}

Может ли JVM определить (во время выполнения), что экземпляр enum, такой как TestResources.TR1, принадлежит к одному ResourceRetriever, как ResourceRetriever.forResource(TestResources.TR1)?

В наивной реализации каждый вызов TestResources.TR1.getFor(...) создаст новый экземпляр ResourceRetriever.

В этом случае мы знаем, что (при проверке кода) вызов ResourceRetriever.forResource(this) вызывает следующее:

public class ResourceRetriever {
    private final ECSResource resource;

    ResourceRetriever(ECSResource resource) {
        this.resource = resource;
    }

    public static ResourceRetriever forResource(ECSResource resource) {
        return new ResourceRetriever(resource);
    }

    //lots of methods
}

Следовательно, во время выполнения ничего не может измениться из-за случайных результатов, ошибок округления и т.д.

Следовательно, возникает вопрос: может ли JVM отображать каждый экземпляр enum ECSResource в его уникальный соответствующий экземпляр ResourceRetriever.forResource(this)?

Обратите внимание, что это можно сделать самостоятельно, используя следующее:

private static enum TestResources implements ECSResource {
    TR1, TR2;

    private static final Map<TestResources, ResourceRetriever> retrieverMapping;
    static {
        retrieverMapping = Arrays.stream(TestResources.values())
            .collect(Collectors.toMap(res -> res, ResourceRetriever::forResource));
    }

    @Override
    public int getFor(final Entity entity) {
        return retrieverMapping.get(this).getFor(entity);
    }
}
4b9b3361

Ответ 1

Семантика ключевого слова new почти наверняка запрещает то, что вы хотите сделать. (См. Ссылки как Спецификация языка Java и Спецификация виртуальной машины Java.) Ваш метод forResource всегда будет возвращать новый объект. Я не знаю никаких JVM, которые будут делать то, что вы пытаетесь сделать, учитывая, что нет никакого механизма, чтобы определить, что для любого заданного ECSResource необходимо создать только один ResourceRetriever. Это выглядит как форма memoization для меня, который будет обрабатываться языком (например, Groovy), который имеет аннотацию специально для это), а не временем выполнения (JVM). Если Java обновила дженерики, вы могли бы взломать такую ​​функцию с чем-то вроде ResourceRetriever<? extends ECSResource>, но я не могу сказать, действительно ли это будет работать, и тем более, будет ли это хорошей идеей или нет.