2014-11-05 24 views
10

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能夠找出(在運行時)像TestResources.TR1這樣的枚舉實例屬於像ResourceRetriever.forResource(TestResources.TR1)一樣的單個ResourceRetriever

在天真的實現中,每次調用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的地圖每枚舉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); 
    } 
} 

回答

2

new關鍵字的語義幾乎肯定禁止你想要做的事。 (請參閱The Java Language SpecificationThe Java Virtual Machine Specification中的參考資料。)您的forResource方法始終會返回一個新對象。我不知道任何JVM可以做你想做的事情,因爲沒有機制可以確定只有一個ResourceRetriever應該爲任何給定的ECSResource創建。對於我來說,這看起來像是一種形式memoization,它將由語言(例如Groovy,專門爲此提供註釋)而不是由運行時(JVM)處理。如果Java已經泛化了泛型,那麼你可能會用類似ResourceRetriever<? extends ECSResource>的方式攻擊這樣的功能,但我不能說這是否會起作用,更不用說這是否是一個好主意。

相關問題