2

I am still fighting with Java's references. I am not sure if I will ever understand them. Can anybody help me?

A non static inner class can access the enclosing class via Outer.this. But how can the outer class access the inner this?

See this example:

class cycle
{
  abstract static class Entity
  {
    abstract static class Attribute
    {
      abstract static class Value
      {
        abstract Attribute attribute ();
      }

      abstract Entity entity ();
      abstract Value value ();
    }
  }

  static class Person extends Entity
  {
    class FirstName extends Attribute
    {
      class StringValue extends Value
      {
        Attribute attribute () { return FirstName.this; }
      }

      Entity entity () { return Person.this; }
      Value value () { return this.StringValue.this; }
    }
  }

  public static void main (String[] args)
  {
    Person p = new Person();
  }
}

StringValue can access FirstName and FirstName can access Person. But how can FirstName access StringValue?

I get the error <identifier> expected in the implementation of value()? What is the correct syntax?

ceving
  • 21,900
  • 13
  • 104
  • 178
  • 3
    There is no _inner.this_. You simply create an instance of it. – Sotirios Delimanolis Oct 02 '13 at 16:07
  • Hmm, this seems to put your [previous question](http://stackoverflow.com/q/19135938/1667004) into better context... – ppeterka Oct 02 '13 at 16:16
  • I'm guessing, but if you are trying to find the equivalent relation of saying "an object has a something" then you are after **instance variables**. An Entity **has** aattributes, and an attribute **has** a value, is that you want to formulate? – ppeterka Oct 02 '13 at 16:33

2 Answers2

7

An Inner class is a member of the Outer class, but it is not a field, ie. there isn't only maximum of one.

You can do

Outer outer = new Outer();
Outer.Inner inner1 = outer.new Inner();
Outer.Inner inner2 = outer.new Inner();
Outer.Inner inner3 = outer.new Inner();
... // ad nauseam

Although each Inner object is related to its outer instance, the Outer instance knows nothing about the Inner instances unless you tell it, ie. keep a reference to them.

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • Ok I understand. It was an error to declare `FirstName` as a class, because this makes it possible to have more than one first name per person, which does not make any sense. Instead first name must be a member. This makes sure, that there is only one and makes it possible to reference it by its name. – ceving Oct 02 '13 at 16:49
  • @ceiving Right. I'm not seeing the bigger picture of your examples. For example, why have an inner class `Attribute`? Just make a field. – Sotirios Delimanolis Oct 02 '13 at 16:51
  • The classes are necessary to give them some functionality, which is not shown in the example. The example is reduced to the question of the relations. – ceving Oct 02 '13 at 16:56
  • @ceving Ah, ok. The point stands that you need to keep a reference to the inner class instances if you want to access them. – Sotirios Delimanolis Oct 02 '13 at 16:57
1

Thanks to Sotirios this is the corrected version of the code from my question.

class cycle
{
  abstract static class Entity
  {
    abstract static class Attribute
    {
      abstract static class Value
      {
        abstract Attribute attribute ();
      }

      abstract Entity entity ();
      abstract Value value ();
    }
  }

  static class Person extends Entity
  {
    Attribute firstname = new Attribute()
      {
        Value value = new Value()
          {
            Attribute attribute () { return firstname; }
          };

        Entity entity () { return Person.this; }
        Value value () { return value; }
      };
  }

  public static void main (String[] args)
  {
    Person p = new Person();
  }
}
Community
  • 1
  • 1
ceving
  • 21,900
  • 13
  • 104
  • 178
  • I'm happy it works. An observation: it's going to be a headache to create `Value` instances without proper importing: `Entity.Attribute.Value = ...;` Consider refactoring :). – Sotirios Delimanolis Oct 02 '13 at 17:10
  • @SotiriosDelimanolis A value can exist only in an attribute. Instead of refactoring it I consider making it private. ;-) – ceving Oct 02 '13 at 17:13