我正在使用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并返回它。
如何编译此代码?
谢了。
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());
}
因为您不需要修改对象的引用,所以您可以将< 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字段,您可以稍后设置该字段。
我有一个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块内的文档。