无法避免的非法正向引用



我遇到了一个似乎无法解决的问题:我正在尝试创建一个"Location"对象网络。每个位置都有一个名称,并连接到其他"相邻位置"。但是,因为它引用了相邻的Location,所以我无法完全初始化每个Location对象,因为相邻的Location仍然需要初始化。

我正在用Java进行编码,我的意思示例如下:

public class Location{
private String name;
private Location[] adjacentLocations;
public Location(String name, Location[] adjacentLocations){
this.name = name;
this.adjacentLocations = adjacentLocations;
}
Location bar = new Location("bar",new Location[]{townSquare, dock});
Location townSquare = new Location("town square",new Location[]{dock, bar});
Location dock = new Location("dock", new Location[]{bar, townSquare});
}

我不打算访问相邻位置的内容;地图";已初始化。我试着把代码放在一个主方法中,它抱怨它是cannot resolve symbol townSquare。我已经尝试在一个主方法中声明所有的Locations并初始化,但它抱怨townSquare may have not been initialized。我已经尝试了上面的代码,它抱怨illegal forward reference

我知道我可以尝试用空的相邻位置初始化我的所有位置,然后在帖子中添加它们,但这看起来一点也不优雅,而且很痛苦。我是不是错过了一些显而易见的东西?我试着查找所有这些错误代码,但没有找到解决问题的有用方法。

很明显,您无法构建依赖于尚未存在的内容的对象。你所创造的是一个鸡和蛋的问题,用任何语言都很难解决。

一个好的选择是从外部管理邻接,例如通过邻接列表:

class TownMap {
Map<Location, List<Location>> adjacency = new HashMap<>();
public void addLocation(Location location) {
adjacency.putIfAbsent(location, new ArrayList());
}
public void addNeighbor(Location a, Location b) {
adjacency.computeIfAbsent(a, new ArrayList<>()).add(b);
adjacency.computeIfAbsent(b, new ArrayList<>()).add(a);
}
public List<Location> getNeighbours(Location location) {
return Collections.immutableList(adjacency.get(location));
}
}

当然,您也可以将adjacentLocations初始化为空,并在以后将其设置为空,一旦这些相邻的位置确实被构造好了。

您可以通过创建一个接口来向调用者隐藏该机制:

public interface Location {
public String name();
public List<Location> neighbours(); 
}
private class LocationImpl implements Location {
private String name;
private List<Location> neighbours;
protected void addNeighbour(Location location) {
neighbours.add(location);
}

public List<Location> neighbours() {
return Collections.immutableList(this.neighbours);
}

}
public static void main(String[] args) {
List<Location> locations = new ArrayList<>();
LocationImpl bar = new LocationImpl("bar");
LocationImpl docks = new LocationImpl("docks");
LocationImpl townsquare = new LocationImpl("townsquare");
bar.addNeighbour(docks);
docks.setNeighbour(bar);
// etc.
locations.Add(bar);
locations.add(docks);
locations.add(townsquare);
// give whomever you want the List<Location> which they can't manipulate further
}

如果设置了适当的可见性规则和模块,任何人都无法进一步操作这些对象。

相关内容

  • 没有找到相关文章

最新更新