[英]Passing this in constructor
我遇到了一些JMS調用代碼,這些代碼在其構造函數內部初始化JMS會話。 調用代碼實現ExceptionListener接口,並將對此的引用傳遞給連接工廠對象,如下所示:
public class JmsCode implements ExceptionListener {
private static final Logger logger = LoggerFactory.getLogger(JmsCode.class);
public JmsCode(String url, String username, String password, String trustStorePath, char[] trustStorePassword) throws JMSException {
ActiveMQSslConnectionFactory connectionFactory = new ActiveMQSslConnectionFactory(url);
connectionFactory.setUserName(username);
connectionFactory.setPassword(password);
connectionFactory.setTrustStore(trustStorePath);
connectionFactory.setTrustStorePassword(new String(trustStorePassword));
connectionFactory.setExceptionListener(this);
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
@Override
public void onException(JMSException e) {
logger.error("Unexpected JMS exception caught", e);
}
}
我想知道從JmsCode構造函數傳遞對此的引用是否安全,因為該對象尚未完全構建。 我遇到了一個類似的問題 ,使我閱讀了IBM關於在構建期間不發布此文章的文章 。 盡管我同意他們的推理,但我不確定它是否適用於這種情況,因為異常偵聽器唯一要做的就是通過靜態成員和最終成員進行記錄。 上面的代碼是否安全(忽略其他人試圖更改異常偵聽器方法以使用對象的某些實例狀態)?
這實際上是不安全的發布,並且從理論上講,另一個對象可能會看到該對象處於不一致狀態。
這就是說,雖然這不是一個很好的模式(它只是這里用來證實ExceptionListener
),構造函數的邏輯表明,類實際上是在通過的時候完全構造,以致this
參考逃逸(因為它沒有任何關系構造),因此在這種情況下,不會出現任何錯誤。
無論是安全與否取決於地方,提及this
可以躲過去 。 如果作為此調用的結果, this
可以被另一個線程讀取,那么它是不安全的。
如果要確保實例完全初始化后可以安全發布, 並且要發布實例,則構造函數不是發布它的正確位置。 相反,您需要創建一個Factory對象或靜態工廠方法,這些方法可以安全地構造該對象,然后在將其返回給調用者之前將其發布。
這是完全安全的。 您只是傳遞了this
引用,而不在this
范圍內使用任何東西。
如果.setExceptionListener(this)
方法執行的不是設置方法,那會出問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.