title: Can a non-changing enum method be optimized by the JVM at runtime?
body: <p>Can the JVM perform runtime optimization in the following scenario?</p>
  
  <p>We've got the following situation, we have this interface:</p>
  
  <pre><code>public interface ECSResource {
      default int getFor(final Entity entity) {
          return ResourceRetriever.forResource(this).getFor(entity);
      }
  }
  </code></pre>
  
  <p>And a concrete implementation such as:</p>
  
  <pre><code>private static enum TestResources implements ECSResource {
      TR1, TR2;
  }
  </code></pre>
  
  <p>Would the JVM be able to figure out (at runtime) that an enum instance such as <code>TestResources.TR1</code> belongs to a single <code>ResourceRetriever</code> like <code>ResourceRetriever.forResource(TestResources.TR1)</code>?</p>
  
  <p>In the naive implementation every call to <code>TestResources.TR1.getFor(...)</code> would create a new <code>ResourceRetriever</code> instance.</p>
  
  <p>In this case though, we know that (by code inspection) a call to <code>ResourceRetriever.forResource(this)</code> will call the following:</p>
  
  <pre><code>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
  }
  </code></pre>
  
  <p>Hence there is nothing that can change at runtime due to random results, rounding errors, etc.</p>
  
  <p><strong>Hence the question: Can the JVM map every <em>enum</em> <code>ECSResource</code> instance to its unique corresponding <code>ResourceRetriever.forResource(this)</code> instance?</strong></p>
  
  <p>Note that it is possible to do such thing by your own, via the following:</p>
  
  <pre><code>private static enum TestResources implements ECSResource {
      TR1, TR2;
  
      private static final Map&lt;TestResources, ResourceRetriever&gt; retrieverMapping;
      static {
          retrieverMapping = Arrays.stream(TestResources.values())
              .collect(Collectors.toMap(res -&gt; res, ResourceRetriever::forResource));
      }
  
      @Override
      public int getFor(final Entity entity) {
          return retrieverMapping.get(this).getFor(entity);
      }
  }
  </code></pre>