当前位置: 首页 > 知识库问答 >
问题:

Java8-“有效最终”

谭毅然
2023-03-14

我正在使用RxVertx,它是一种RxJava和Java8,我有一个编译错误。

这是我的代码:

public rx.Observable<Game> findGame(long templateId, GameModelType game_model, GameStateType state) {

return context.findGame(templateId, state)
    .flatMap(new Func1<RxMessage<byte[]>, rx.Observable<Game>>() {

        @Override
        public Observable<Game> call(RxMessage<byte[]> gameRawReply) {

            Game game = null;

            switch(game_model) {

                case SINGLE: {

                    ebs.subscribe(new Action1<RxMessage<byte[]>>() {

                        @Override
                        public void call(RxMessage<byte[]> t1) {

                            if(!singleGame.contains(0) {
                                game = new Game();       // ERROR is at this line
                                singleGames.put(0, game);
                            } else {
                              game = singleGames.get(0); // ERROR is at this line
                            }
                        }
                    });
                }
            }

            return rx.Observable.from(game);
        }
    });
}

编译错误是:“在封闭范围内定义的局部变量游戏必须是最终的或有效的最终的”

我无法将“game”定义为final,因为我在函数末尾执行分配\set并返回它。

如何编译此代码?

谢了。

共有3个答案

黄昊英
2023-03-14

Cyclops有Mutable和LazyImmutable对象来处理这个用例。Mutable是完全可变的,LazyImmutable设置一次。

 Mutable<Game> game = Mutable.of(null);

 public void call(RxMessage<byte[]> t1) {

                        if(!singleGame.contains(0) {
                           game.mutate(g -> new Game());       
                            singleGames.put(0, game.get());
                        } else {
                          game[0] = game.mutate(g->singleGames.get(0));
                        }
               }

LazyImmutable可以用来懒惰地设置一个值,一次:

LazyImmutable<Game> game = LazyImmutable.def();

public void call(RxMessage<byte[]> t1) {

     //new Game() is only ever called once
     Game g = game.computeIfAbsent(()->new Game());
}
邴和雅
2023-03-14

因为您不需要修改对象的引用,所以您可以将< code>Game包装在其他东西中。

最快的(但也是最糟糕的)修复方法是使用大小为1的数组,然后稍后设置数组的内容。这是可行的,因为数组实际上是最终的,数组中包含的内容不一定是最终的。

@Override
    public Observable<Game> call(RxMessage<byte[]> gameRawReply) {

        Game[] game = new Game[1];

        switch(game_model) {

            case SINGLE: {

                ebs.subscribe(new Action1<RxMessage<byte[]>>() {

                    @Override
                    public void call(RxMessage<byte[]> t1) {

                        if(!singleGame.contains(0) {
                            game[0] = new Game();       
                            singleGames.put(0, game[0]);
                        } else {
                          game[0] = singleGames.get(0);
                        }
                    }
                });
            }
        }

        return rx.Observable.from(game[0]);
    }

另一个类似的选项是创建一个新的类,它有一个< code>Game字段,您可以稍后设置该字段。

冀俊良
2023-03-14

我有一个Holder类,用于这种情况。

/**
 * Make a final one of these to hold non-final things in.
 *
 * @param <T>
 */
public class Holder<T> {
  private T held = null;

  public Holder() {
  }

  public Holder(T it) {
    held = it;
  }

  public void hold(T it) {
    held = it;
  }

  public T held() {
    return held;
  }

  public boolean isEmpty() {
    return held == null;
  }

  @Override
  public String toString() {
    return String.valueOf(held);
  }

}

然后,您可以执行如下操作:

final Holder<Game> theGame = new Holder<>();
...

theGame.hold(myGame);
...
{
  // Access the game through the `final Holder`
  theGame.held() ....
 类似资料:
  • 问题内容: 我正在尝试将java8 forEach循环内的布尔变量更改为true,这是非最终的。但是我遇到了以下错误:在封闭范围内定义的必需局部变量必须是final或有效的final。 如何解决这个错误? 代码: 这是我在函数中创建的变量。 现在,当我尝试更改它时: 我收到错误消息:封闭范围中定义的必需局部变量必须是final或有效的final。 为什么会出现此错误,以及如何解决? 问题答案: 您

  • 我有一个Java8中的多线程Http服务器,它每秒获得数千个请求,并且必须创建需要字符串连接的响应。这个问题最好(最快)的解决方案是什么? 我知道,通常比操作符具有更好的性能,我认为StringBuilder将是最好的解决方案,但在这种情况下,我必须为每个请求初始化新的StringBuilder。 而且,在我的问题中,串联总是需要3个字符串-其中两个是final字符串,中间一个是变量。该变量可以从

  • 我正在玩Java 8,遇到了一个基本的场景,它展示了一个第22条军规,即修复一个编译错误会导致另一个编译错误。场景(这只是一个从更复杂的东西简化而来的例子): 我收到编译错误: 封闭范围中定义的局部变量结果必须是最终的或有效的最终结果 如果我将第一行更改为: 最后一行出现编译错误: 局部变量结果可能尚未初始化 似乎这里唯一的方法是将我的结果预先初始化为ArrayList,我不想这样做,或者不使用l

  • 到目前为止,我认为有效的final和final或多或少是等价的,如果在实际行为中不完全相同,JLS会将它们视为相似的。然后我发现了这个人为的场景: 显然,JLS在这两者之间产生了重要的区别,我不知道为什么。 我阅读其他线程,如 最终和有效最终之间的差异 有效的最终变量vs最终变量 变量“有效最终”是什么意思 但他们并没有详细说明。毕竟,在更广泛的层面上,它们似乎几乎相当。但深入研究,他们显然有所不

  • 我的问题是,这个问题有没有更好的解决办法?多谢.

  • 因此,我开始使用Java8streams/lambda表达式,遇到了一些有趣的问题,我不知道如何解决这些问题。所以我在这里,请求你的帮助。 现在我得到编译器错误“在lambda表达式中使用的变量应该有效地是final”。 怎么做? 方法createNewDocument和createOldDocument引发异常,因此调用必须在try/catch块内。我还需要关闭finally块内的文档。