【问题标题】:Unnavoidable Illegal Forward Reference不可避免的非法前向引用
【发布时间】:2021-03-11 20:45:41
【问题描述】:

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

我正在使用 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});
}

在整个“地图”初始化之前,我不打算访问相邻位置的内容。 我尝试将代码放在 main 方法中,它抱怨它cannot resolve symbol townSquare。 我曾尝试在主方法中声明所有位置并进行初始化,但它抱怨 townSquare may have not been initialized. 我已经尝试了上面抱怨illegal forward reference

的代码

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

【问题讨论】:

    标签: java oop initialization forward-reference


    【解决方案1】:

    您显然不能构造依赖于尚不存在的东西的对象。您创建的是一个鸡与蛋的问题,任何语言都难以解决。

    一个不错的选择是在外部管理邻接,例如通过邻接表:

    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
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-06-05
      • 2011-08-06
      • 2015-11-02
      • 1970-01-01
      • 2015-09-18
      • 2021-12-17
      相关资源
      最近更新 更多