【问题标题】:Update all references to an object when the object is updated(reference to a reference)更新对象时更新对对象的所有引用(对引用的引用)
【发布时间】:2012-01-16 15:45:05
【问题描述】:

我想在java中声明一个对象,它就像一个指向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中可能吗?如何做呢 ?

【问题讨论】:

  • 如果你传递同一个对象,它将引用内存中的同一个对象,实际上它是一个指针。
  • 您可以做的是使用单例模式来确保您使用一个设置对象,或者使用观察者模式将观察者更新为您的可观察对象(设置类)
  • 即使单例模式也不能保证有效,这取决于 DatabaseConnector 和 Logger 的构造函数的作用。如果他们从配置中复制字段,那么即使您更新配置,这些对象也永远不会看到更改。在这种情况下,唯一的选择就是观察者。

标签: java object pointers reference


【解决方案1】:

在 Java 中,您只有对对象的引用。要获得对引用的引用,您需要某种间接方式。例如

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

refDatabaseSettings.set(dbSettings);

DatabaseSettings dbSettings = refDatabaseSettings.get();

您可以传递 ref 并在一个地方更改它。但是,这不会通知任何引用它已更改,只是允许所有引用在下次检查时看到相同的内容。

【讨论】:

    【解决方案2】:

    好吧,与其在应用程序中设置新设置,不如更新现有设置。

    或者只是记录这些设置可能会更改的事实,并且任何有兴趣拥有新设置的代码必须始终通过Application.getSettings()

    【讨论】:

    • +1 第一个陈述是我要写的作为这个问题的答案。
    【解决方案3】:

    您需要使用某种形式的通知系统来完成您正在尝试做的事情。具有对更改感兴趣的侦听器的观察者/可观察对象或某些基于事件的系统确实是唯一的出路。

    您当然可以创建可以更新的线程安全设置对象(如 DatabaseSettings),因此对象的使用者将获得新值,但这仅适用于最简单的情况。这种方法的问题是多次调用设置实例的结果会变得不一致。假设设置对象中有多个设置相互关联,如果检索到一个设置,更新对象,然后检索下一个设置,你无法知道这两个调用产生了不一致的 (彼此)价值观。

    例如:

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

    如果在这 2 次调用之间更新了 dbSettings,则用户名和连接将不再匹配。

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

    这使得这些类的使用方式非常僵化且容易出错。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-07-07
      • 2015-07-25
      • 2021-06-26
      • 1970-01-01
      • 2021-05-25
      • 2011-06-19
      • 2013-01-14
      相关资源
      最近更新 更多