首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Rx-java通过引用传递还是通过值传递?

Rx-java通过引用传递还是通过值传递?
EN

Stack Overflow用户
提问于 2015-08-18 04:23:43
回答 1查看 1.1K关注 0票数 1

在java方法中everything is passed-by-value so i can change the object attributes passed to the method and expect that the original object attributes are changed。但在这种方法中,我得到了不同的结果:

我有这样的方法:

代码语言:javascript
复制
public Observable<Menu> makeMenu(Menu menu, NumberSettingChanges.MenuChanges changes) {
    // Start flow with added and edited extensions
    return Observable.from(changes.added.entrySet())
            .mergeWith(Observable.from(changes.edited.entrySet()))
                    //Upload announcement voices or do nothing if extension is not an announcement
            .flatMap(e -> {
                        if (AppTypeContract.APP_TYPE_ANNOUNCEMENT.equals(e.getValue().type)) {
                            return mMediaManager.uploadAsync(e.getValue().config.localPrompt)
                                    .doOnNext(response -> {
                                        //Update extension prompt with the storage path.
                                        menu.config.extensions.get(e.getKey()).config.prompt = response.mPath;
                                        menu.config.extensions.get(e.getKey()).config.localPrompt = "";
                                    })
                                    .flatMap(response -> Observable.just(e));
                        } else {
                            return Observable.just(e);
                        }
                    }
            )
}

我在平面图中操作菜单属性:

代码语言:javascript
复制
menu.config.extensions.get(e.getKey()).config.localPrompt = "";

我在同一个类中调用该方法:

代码语言:javascript
复制
public Observable<NumberSetting> saveSettings(NumberSetting o, NumberSetting n) {
    NumberSettingChanges changes = compareNumberSetting(o, n);

    return makeMenu(n.day, changes.day)
            .mergeWith(makeMenu(n.night, changes.night));
    }

最后:

代码语言:javascript
复制
saveSettings(ns, mNumberSettingNew).subscribe();

我所期望的是,mNumberSettingNew.menu.config.extensions.get(e.getKey()).config.prompt被更改了,但是在这个调用之后没有发生任何更改,而且mNumberSettingNew也没有任何变化。

请注意,我确信在调试中已经完成了更改提示符行。

EN

回答 1

Stack Overflow用户

发布于 2015-08-18 08:17:38

我不认为我能更好地解释Java的参数语义(甚至是第一段中引用的链接的一半),所以我不会尝试。要点是: Java中的所有内容都是通过值(即复制)传递的,但是对于对象,复制的不是对象本身,而是对对象的引用。换句话说,引用是通过值传递的。

因此,关于您的特定问题:是的,如果将对可变对象的引用传递给某些rx代码,则引用将指向该对象的同一个实例。如果您改变了实例,那么调用方代码也将能够看到更改,因为它们是在同一个实例上进行的。这是因为rx仍然只是Java,不能在该级别上更改语言语义。

没有看到整个代码,我不知道这里会有什么问题.您何时检查mNumberSettingsNew是否实际对doOnNext进行了更改?如果在saveSettings(ns, mNumberSettingNew).subscribe();之后立即检查,您的uploadAsync可能还没有返回。您可以尝试在您的Subscriber中添加一个实际的subscribe并检查那里的结果。

总的来说,我认为在使用rx时,您应该尽量避免这样的副作用。您的情况--以一个输入对象为例,对该对象应用一组(可能是异步的)更改,并等待更改的输出对象--有点棘手,但我认为可以用scan来完成。也许是这样模糊的东西:

代码语言:javascript
复制
Observable.from(changes.added.entrySet())
    .mergeWith(Observable.from(changes.edited.entrySet()))
    .scan(menuBeforeAnyChanges, new Func2<Menu, Change, Menu>() {

        public Menu call(final Menu previousVersionOfTheMenu, final Change nextChange) {
            // since I don't know of a version of scan that can return 
            // an Observable you would I think you would have to adapt
            // your code in here to be fully synchronous - but of
            // course the scan itself could run asynchronously
            final newVersionOfTheMenu = previousVersionOfTheMenu.applyChange(nextChange);
            return newVersionOfTheMenu;
        }
     )

这将使用菜单的原始版本,连续应用来自addededited的所有更改,并/emit/每个更新的菜单版本。因此,您不会有任何副作用,只需使用Subscriber<Menu>订阅可观察到的内容,然后接受last()菜单,这将是应用所有更改的菜单。

编辑:哦,我刚刚看到了另一个叫做reduce的方法,它就是这样做的:首先是scan,然后是lasttakeLast

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32063496

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档