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是否能够(在运行时)弄清楚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
}
的调用会调用以下内容:
ECSResource
因此,由于随机结果,舍入错误等原因,没有任何内容可以在运行时发生变化。
因此问题:JVM是否可以将每个枚举 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);
}
}
实例?
请注意,您可以通过以下方式自行完成此操作:
{{1}}
答案 0 :(得分:2)
new
关键字的语义几乎肯定会禁止您想要做的事情。 (请参阅The Java Language Specification和The Java Virtual Machine Specification中的参考文献。)您的forResource
方法总是会返回一个新对象。我不知道任何JVM会做你想要做的事情,因为没有机制来确定只应为任何给定的ResourceRetriever
创建一个ECSResource
。这看起来像memoization的一种形式,它将由语言处理(例如Groovy,它具有专门针对此的注释)而不是运行时(JVM)。如果Java已经确定了泛型,你可能会用ResourceRetriever<? extends ECSResource>
之类的东西破解这样的功能,但是我不能说这是否真的有用,更不用说它是否是一个好主意。