2012-01-16 95 views
1

我要聲明在java中的對象,就像AA指針在C++中的指針,讓我告訴你一個例子(參照參考)對象的所有引用:更新當對象被更新

//*** At the application startup 

//Initialize a settings container class 
Settings settings = //Load settings 

//Declaring static Application class that contain a reference to the settings container 
Application.setSettings(settings); 

//Get sub settings from settings container class 
DatabaseSettings dbSettings = settings.getDbSettings(); 
LogSettings logSettings = settings.getLogSettings(); 

//Initialize components 
DatabaseConnector dbConn = new DatabaseConnector(dbSettings); 
Logger logger = new Logger(logSettings); 

在上面的代碼中,我已創建了含有我的應用程序組件的所有設置的設置容器類,然後我有程序的執行過程中分配每個子設置類現有部件,在這一點我要更新的設置,讓應用程序的組件看到更新的設置,所以例如在執行期間我可以用這種方式更新設置容器:

//Update settings through Application static class 
Settings newSettings = //assign updated settings 
Application.setSettings(newSettings); 

現在的問題是,當我在運行時更新設置容器應用靜態類將包含更新參考newSettings實例,同時各子設置實例保持引用舊子設置,因此:

dbConn  ---> settings.getDbSettings() 
logSettings ---> settings.getLogSettings() 

雖然我想,兩個參考自動參考的設置新實例,所以:

dbConn  ---> newSettings.getDbSettings() 
logSettings ---> newSettings.getLogSettings() 

它就像一個指針,指針......是否有可能在Java中?如何做呢 ?

+0

如果你傳遞相同的對象,它會引用內存中的同一個對象,實際上它是一個指針。 – 2012-01-16 15:48:48

+1

你可以做的是使用單例模式來確保你使用一個設置對象或者一個觀察者模式來將觀察者更新到你的observable(設置類) – 2012-01-16 15:49:53

+1

即使singleton模式不能保證工作,它依賴於DatabaseConnector和Logger的構造函數是做什麼的。如果他們從配置中複製字段,那麼即使更新配置,這些對象也不會看到更改。在這種情況下,唯一的選擇是觀察員。 – Hiro2k 2012-01-16 16:03:25

回答

2

在Java中,您只能引用對象。要參考引用,您需要某種間接性。例如

AtomicReference<DatabaseSettings> refDatabaseSettings = new AtomicReference<DatabaseSettings>(); 

refDatabaseSettings.set(dbSettings); 

DatabaseSettings dbSettings = refDatabaseSettings.get(); 

你可以傳遞ref並在一個地方改變它。但是,這不會通知任何引用它已更改,只是允許所有引用在下次檢查時看到相同的內容。

2

好,而不是在應用程序中設置新的設置,更新現有的。

或者乾脆記錄的事實,這些設置可以改變,並且有意讓新設置的任何代碼必須經過Application.getSettings()

+0

+1第一個說法就是我要寫作這個問題的答案。 – 2012-01-16 15:54:45

0

您需要使用某種形式的通知系統來完成您正在嘗試執行的操作。一個觀察者/可觀察者或一些基於事件的系統,聽衆對這些變化感興趣是真正的唯一途徑。

您當然可以創建可更新的線程安全設置對象(如DatabaseSettings),因此對象的使用者將獲得新值,但這隻適用於最簡單的情況。這種方法的問題是多次調用設置實例的結果會變得不一致。假設設置對象中有多個設置是相互關聯的,如果檢索到一個設置,則更新對象,然後檢索下一個設置,但無法知道這兩個調用產生了不一致(彼此)值。

例如:

dbSettings.getConnectionUrl(); 
dbSettings.getUsername(); 

如果dbSettings在這些2個呼叫之間更新,那麼用戶名和連接將不再匹配。

的另一個問題是,如果有人提取從設置的特定值對象,並把它們存儲在另一個變量或一類,他們將無法知道它改變的方式。

它使得這些類的使用方式非常嚴格且容易出錯。