【问题标题】:Can an attribute object reach the object for which it is an attribute?属性对象可以到达它作为属性的对象吗?
【发布时间】:2015-12-23 15:05:01
【问题描述】:

很抱歉这个问题可能很奇怪,但前段时间我使用了 python 的内省,我想知道 Java 1.8 中是否有类似的东西。

假设我在这种情况下有一个来自 A 类的对象 a

class A{ B b; }
class B{ public void f(){} }

我的问题是“f() 可以知道a 吗?”

显然,如果我添加一个反向链接,它可以:

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

class B {
    A father; 
    public B(A a){ this.father = a; } 
    public void f(){} 
}

但我的问题是,在一般情况下,没有像father 这样的背面,是否有任何内省机制可以让f() 了解a?

【问题讨论】:

  • A a = new A; B b2 = a.b; 现在你会期待什么结果?
  • 为什么需要这种场景
  • 简短回答:不。长答案:noooo。
  • A 和 B 没有任何共同之处。你想让f 知道一个与它所在的类无关的类的什么?
  • 即使有可能,您如何确切知道拥有B 实例的A 的多个潜在实例中的哪一个是您想要的?可能有很多。

标签: java introspection


【解决方案1】:

您希望访问调用堆栈中上层函数的参数。在 vanilla Java 中你无法做到这一点,但是你可以使用一些 AOP 框架,它可以维护一个影子堆栈,所以你可以自省它。

或者你可以使用内部类。内部类包含外部类实例的隐藏字段。可以使用 OuterClass.this 语法访问它。

class A{
  public class B{ 
    public void f() {
      System.out.println(A.this.aField);
    }    
  }
  String aField;
  B b = new B(); // Passes a hidden `this` parameter
}

【讨论】:

  • 这不是他说的场景——他说的是 A 和 B 完全不相关的情况,而不是 B 是 A 中的内部类的情况
【解决方案2】:

如果 A 和 B 在同一个包中,B 知道 A 中的字段 b 暴露给 B。这是可能的,因为您在 A 中声明了字段 b 具有默认可见性,即“包私有”。

否则,如果你把A换成

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

那么你只能像这样使用反射从A访问字段B(假设这段代码在B中的一个方法中:

Field privateStringField = A.class.getDeclaredField("b");
privateStringField.setAccessible(true);

B value = (B) privateStringField.get(this);

现在这是一个坏主意,因为您更改了 A 中字段“b”的名称,然后您破坏了代码,编译器不会告诉您。

【讨论】:

    【解决方案3】:

    你不能那样做。如果 B 是 A 的成员,则意味着 A“知道”B,但反之则不然。您只能从 A 访问 B,反之则不行。

    【讨论】:

      【解决方案4】:

      (我自己删除了这条评论,问题解决了)

      【讨论】:

        猜你喜欢
        • 2013-12-17
        • 2020-11-20
        • 2020-01-21
        • 2015-11-29
        • 2019-03-27
        • 1970-01-01
        • 2011-03-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多