【问题标题】:How to check ownership of inner classes in Java如何在 Java 中检查内部类的所有权
【发布时间】:2014-07-16 12:13:19
【问题描述】:

我有以下结构:

public class Outer {
    public /*non-static*/ final class Inner {
        // to prevent instantiating other than in method `create`
        private Inner(/* ... */) { /* ... */ }
        /* ... */
    }

    Inner create(/* ... */) {
        return new Inner(/* ... */);
    }

    void operateOn(Inner inner) {
        // TODO check if inner for this Outer instance
    }
}

和这样的用法:

Outer manager = new Outer();
Inner state = manager.create(/* ... */);

还有其他地方

manager.operateOn(state);

我想创建一个万无一失的实用程序类,这意味着Outer.operateOn 将只接受自己拥有的Inner 实例

我知道所有非静态内部类都通过其类体内的Outer.this 引用(所有)外部类。

我想知道是否有比向Inner 添加任何方法(如isOwnedBy(Outer outer) { return outer == Outer.this; }getOwner() { return Outer.this })更好的检查方法。

【问题讨论】:

  • 可能是void create(...) { this.inner = new Inner(); }void operateOn() { this.inner.doSomething(); }
  • "意思是 Outer.operateOn 只接受自己拥有的 Inner 实例" 如何传递任何其他 Inner 类型?
  • @assylias 您可以使用 create 创建多个实例,这不是 1:1 的关系
  • @JamesB 我想防止这种情况发生:Outer manager2 = new Outer(); Inner state2 = manager2.create(...); manager.operateOn(state2); 接受的答案就是这样做的。

标签: java class inner-classes


【解决方案1】:

我想创建一个万无一失的....

这总是比你想象的要难。

manager.operateOn(state);

如果你知道它必须与状态关联的经理,我不会提供经理。

试试吧

state.operate();

state 知道它应该使用哪个manager。这样就无法指定不正确的经理,因为您无法更改经理。

【讨论】:

  • 嗯,我会接受这一点,但是我可能犯了一个错误,将我当前的设计转换为 SO 问题。我可能会发布另一个与此类似的。
  • @Keerthivasan +1 谢谢,我将把它作为一般性声明;)
【解决方案2】:

正如彼得所说的

class Inner{
     private Inner(Outer manager){
        this.manager = manager;
     }

     public void operate(){
          manager.operate(this);
     }

}    

并且管理器中的operate 方法应该是私有的。

【讨论】:

  • 重点是我有一个内部类,并且管理器引用是由编译器自动生成的。对于我的代码,Peter 建议的 operate 看起来像 Outer.this.operate(this)。注意:Outer.this. 是可选的,编译器会根据参数和上下文解析正确的operate 方法。
  • Outer 需要使用不同的名称,否则 operate(this); 将无法编译。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-03
相关资源
最近更新 更多