有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java反向/反向引用

我试图将一个类实例传递给另一个类的构造函数,反之亦然。我想这样做:

static Map map = new Map(hero);
static Hero hero = new Hero(map);

我在游戏类中运行这些代码。如何正确地实现上述代码?有没有更好的办法

编辑:

我想我真正想要的是延迟加载,比如如果map为null,那么就进行加载;否则,就别做了。如何在Java中实现这一点


共 (5) 个答案

  1. # 1 楼答案

    您可能会通过两阶段初始化来完成

    例如

    static Map map = new Map();
    static Hero hero = new Hero();
    
    map.setHero(hero);
    hero.setMap(map);
    

    然后向相关函数添加保护,如果在setMap/setHero

  2. # 2 楼答案

    我强烈建议不要使用循环引用
    您可能会遇到序列化问题(例如,如果希望通过网络发送地图并将其存储在文件中)。
    我建议你为你的地图和你的英雄物品设置一个唯一的ID
    例如,您可以在其地图上为Hero保留一个“parentId”
    将人和英雄对象存储在一些缓存中(可能是基于HashMap的单例缓存),这将允许您按id检索对象,这样,给定一个英雄,您将能够非常轻松地获取其映射
    如果您仍然坚持循环引用,请参见@logical chimp提供的答案

  3. # 3 楼答案

    基本上,我这样做是为了我永远不会在任何其他类中创建一个世界类,如果需要的话,我的世界类会实例化其他类

    谢谢大家的帮助

  4. # 4 楼答案

    你拥有的是cyclic/circular dependency。因此,您只需要在一个对象内初始化对象。最好的地方是一个对象的Constructor

    class Map {
        Hero hero = null;
    
        public Map() {
            hero = new Hero(this);
        }
    
        public Hero getHero() {
            return hero;
        }
    }
    
  5. # 5 楼答案

    嗯,上面的语法不会编译,您会得到一个illegal forward reference编译错误

    你能做的就是构造两个对象,然后设置参考,例如

    static Map map = new Map();
    static Hero hero = new Hero();
    // and then ...
    map.hero(hero);
    hero.map(map);
    

    当然,您命名setter的方式取决于您,如果这些setter的行为与真正的JavaBean setter类似,那么您可能应该遵守该命名约定(即setX()getX())。如果Map\Hero类在使用该setter之前不可用,那么Builder Design Pattern可能就是这种情况

    另一种选择是使用一些依赖项注入库,在幕后为您处理上述事情

    第三个选项是使用嵌套类(如果它适合您的设计),例如

    class Map {
        class Hero { ... }
    }
    

    这样,每个英雄都可以通过Map.this获得对Map的引用

    HTH,
    埃尔姆斯