Can the JVM perform runtime optimization in the following scenario?
We've got the following situation, we have this interface:
public interface ECSResource {
default int getFor(final Entity entity) {
return ResourceRetriever.forResource(this).getFor(entity);
}
}
And a concrete implementation such as:
private static enum TestResources implements ECSResource {
TR1, TR2;
}
Would the JVM be able to figure out (at runtime) that an enum instance such as TestResources.TR1
belongs to a single ResourceRetriever
like ResourceRetriever.forResource(TestResources.TR1)
?
In the naive implementation every call to TestResources.TR1.getFor(...)
would create a new ResourceRetriever
instance.
In this case though, we know that (by code inspection) a call to ResourceRetriever.forResource(this)
will call the following:
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
}
Hence there is nothing that can change at runtime due to random results, rounding errors, etc.
Hence the question: Can the JVM map every enum ECSResource
instance to its unique corresponding ResourceRetriever.forResource(this)
instance?
Note that it is possible to do such thing by your own, via the following:
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);
}
}
The semantics of the new
keyword almost certainly prohibit what you're wanting to do. (See references both in The Java Language Specification and The Java Virtual Machine Specification.) Your forResource
method is always going to return a new object. I don't know of any JVMs that would do what you're trying to do, given that there is no mechanism to determine that only one ResourceRetriever
should be created for any given ECSResource
. This looks like a form of memoization to me, which would be handled by the language (e.g. Groovy, which has an annotation specifically for this) and not by the runtime (JVM). If Java had reified generics, you could possibly hack such a feature with something like ResourceRetriever<? extends ECSResource>
but I can't say whether that would actually work, much less whether it would be a good idea or not.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With