【问题标题】:Java: how does a component know its ownerJava:组件如何知道它的所有者
【发布时间】:2011-06-28 16:48:08
【问题描述】:

假设我有一个班级A 和一个班级B

public class A {

    private B b;

    public A() {
        this.b = new B();
    }

    public B getB() {
        return this.b;
    }
}

public class B {

    public String getSome() {
        return "Get some!";
    }
}

我知道我可以通过 A 获得 B,因为 A 拥有(或拥有)B:new A().getB()
但是如果我有B,我能得到A吗?

【问题讨论】:

    标签: java ownership


    【解决方案1】:

    当然,只需在 B 类中添加例程 getA(),并将构造函数中的行更改为

    public A() {
        this.b = new B(this);
    }
    

    这当然假设您的 B 类有一个接受 A 的构造函数,例如,

    public B(A a) {
        this.a = a;
    }
    

    【讨论】:

      【解决方案2】:

      B 需要明确引用其所有者:

      public class B {
        private final A owner;
      
        public B(A owner) {
          this.owner = owner;
        }
      
        public A getOwner() {
          return owner;
        }
      }
      

      A:

      public A() {
        b = new B(this);
      }
      

      【讨论】:

      • 如果多个对象拥有(引用)B 的实例怎么办?
      • B 的每个实例都必须跟踪对它的所有引用。
      【解决方案3】:

      不,这是不可能的。您正在寻找反向引用,但如果需要,我们必须在代码中创建它们。

      如果您想收集对 B 的所有引用,您可以使用构造函数或创建 B 的工厂(模式)来执行此操作。我将展示工厂:

      public class B {
      
         private static Set<? extends Object> referencers = new HashSet<? extends Object>();
         private B(){}  // no public constructor
         public static create(Object parent) {
           // cooperative approach, the caller should pass "this"
           referencers.add(parent);
         }
         public static remove(Object parent) {
           referencers.remove(parent);
         }
      }
      

      【讨论】:

        【解决方案4】:

        不,你不能。 B 没有引用 A。

        【讨论】:

          【解决方案5】:

          没有。

          A 类引用了 B 类,但 B 类没有引用 A 类。引用只是一种方式。

          【讨论】:

            【解决方案6】:

            如果您需要 B 始终绑定到 A 的实例,请将 B 设为 A 的内部类:

            class A {
            
                B b = new B();
            
                class B {
                    String getSome() {
                        // this will refer to the enclosing A
                        return A.this.toString();
                    }
                }
            }
            

            一个内部(非静态)类总是有一个对封闭实例的隐式引用,没有它就不能存在。为了从外部实例化 B,你需要一个讨厌的语法:B b = new A().new B();

            【讨论】:

              【解决方案7】:

              你也可以使用内部类

              封装测试;

              公开课 A {

              B b = null;
              
              public B getB()
              {
                  return b;
              }
              
              public class B {
              
                  public A getA()
                  {
                      return A.this;
                  }
              }
              
              public static void main(String[] args) {
                  B b = new A().new B();
              }
              

              }

              【讨论】:

                【解决方案8】:

                不。 Java中没有“所有者”这样的东西。任何对象都可以被任意数量的其他对象引用。

                【讨论】:

                  猜你喜欢
                  • 2011-08-06
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-03-28
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多