2012-01-16 100 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个呼叫之间更新,那么用户名和连接将不再匹配。

的另一个问题是,如果有人提取从设置的特定值对象,并把它们存储在另一个变量或一类,他们将无法知道它改变的方式。

它使得这些类的使用方式非常严格且容易出错。