2013-10-29 46 views
1

請考慮以下語句並將日誌級別設置爲ERROR。正在使用的記錄API是log4j。 根據以上信息將創建多少個字符串?常量池中將創建多少個字符串對象

if (logger.isDebugEnabled()) { 
    logger.debug("Executing SQL query [" + sql + "]"); 
} 

另一個問題是

if (logger.isDebugEnabled()) { 
    StringBuilder sBuilder = new StringBuilder("Executing SQL query ["); 
    sBuilder.append(sql); 
    sBuilder.append("]"); 
    logger.debug(sBuilder.toString()); 
} 

多少字符串將在上述情況下產生的呢?

我的問題是編譯器會創建字符串,即使記錄器未啓用調試?

回答

2
logger.debug("Executing SQL query [" + sql + "]"); 

兩串

"Executing SQL query [" 

"]" 

在編譯時創建的。

,然後在運行時,

"Executing SQL query [" + sql + "]" 

(+)運算符JVM返回新的StringBuilder(字符串...)。的toString(),它創建於堆內存新的String實例。

如果調試啓用,則追加操作將與StringBuilder.toString發生。

+0

這些也會在運行時加載嗎? – Jabir

+0

@Jabir Ofcourse,這是一個簡單的Java線,天氣它是記錄器或什麼。至少我相信如此。 –

+0

@Suresh我稍微修改了一下問題,你可以請現在檢查 – Jabir

2

如果你在源代碼中有引號,那麼無論代碼有多複雜,編譯器都會將字符串常量放在池中。除非能夠清楚地看到代碼無法訪問(如if(false)),否則編譯器不會做出許多假設。

你可能想看看SLF4J使用的logback允許你寫

log.debug("Executing SQL query [{}]", sql); 

注意在運行時,它仍然會創建一個StringBuilder,並建立從模式和參數的結果,但SLF4J會爲你做if。這將使你的代碼保持清潔和快速,而不需要付出很大的努力。

你可能想看看project Lombok和他們的@Log annotation,使它更容易和更緊湊。