不可撤销的非法转发引用

nzrxty8p  于 2021-07-03  发布在  Java
关注(0)|答案(1)|浏览(345)

我遇到了一个似乎无法解决的问题:我正在尝试创建一个由“location”对象组成的网络。每个位置都有一个名称,并连接到其他“相邻位置”。但是,由于它引用了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});
}

在整个“Map”初始化之前,我不打算访问相邻位置的内容。我试过把代码放在一个main方法中,它抱怨 cannot resolve symbol townSquare . 我尝试过在main方法中声明所有的位置并进行初始化,但它抱怨 townSquare may have not been initialized . 我试过上面的代码 illegal forward reference 我知道我可以尝试用空的相邻位置初始化我的所有位置,然后将它们添加到post中,但这看起来一点也不优雅,而且很麻烦。我是不是漏掉了什么明显的东西?我试图查找所有这些错误代码,但没有找到解决问题的有效方法。

fv2wmkja

fv2wmkja1#

很明显,你不能构造依赖于不存在的东西的对象。你所创造的是一个用任何语言都很难解决的鸡和蛋的问题。
一个好的选择是从外部管理邻接关系,例如通过邻接列表:

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
}

通过设置适当的可见性规则和模块,没有人可以进一步操纵这些对象。

相关问题