不可避免的非法转发引用
Unnavoidable Illegal Forward Reference
我遇到了这个似乎无法解决的问题:
我正在尝试创建 'Location' 个对象的网络。每个位置都有一个名称,并与其他位置相连 'adjacentLocations'。但是,因为它引用了 adjacentLocations,所以我无法完全初始化每个 Location 对象,因为 adjacentLocations 仍然需要初始化。
我在 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
。
我已经尝试在主方法中声明所有位置并进行初始化,但它抱怨 townSquare may have not been initialized
。
我已经尝试了上面的代码,它抱怨 illegal forward reference
我知道我可以尝试用空的相邻 Locations 初始化我的所有 Locations,然后将它们添加到 post,但这看起来很不优雅,而且很麻烦。我错过了一些明显的东西吗?我尝试查找所有这些错误代码,但没有找到对我的问题有用的解决方案。
你显然不能构造依赖于还不存在的东西的对象。您创建的是一个很难用任何语言解决的先有鸡还是先有蛋的问题。
一个不错的选择是在外部管理邻接关系,例如通过邻接表:
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
}
通过适当的可见性规则和模块设置,没有人可以进一步操纵这些对象。
我遇到了这个似乎无法解决的问题: 我正在尝试创建 'Location' 个对象的网络。每个位置都有一个名称,并与其他位置相连 'adjacentLocations'。但是,因为它引用了 adjacentLocations,所以我无法完全初始化每个 Location 对象,因为 adjacentLocations 仍然需要初始化。
我在 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
。
我已经尝试在主方法中声明所有位置并进行初始化,但它抱怨 townSquare may have not been initialized
。
我已经尝试了上面的代码,它抱怨 illegal forward reference
我知道我可以尝试用空的相邻 Locations 初始化我的所有 Locations,然后将它们添加到 post,但这看起来很不优雅,而且很麻烦。我错过了一些明显的东西吗?我尝试查找所有这些错误代码,但没有找到对我的问题有用的解决方案。
你显然不能构造依赖于还不存在的东西的对象。您创建的是一个很难用任何语言解决的先有鸡还是先有蛋的问题。
一个不错的选择是在外部管理邻接关系,例如通过邻接表:
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
}
通过适当的可见性规则和模块设置,没有人可以进一步操纵这些对象。