views:

623

answers:

3

I'm using the Apache Commons EqualsBuilder to build the equals method for a non-static Java inner class. For example:

import org.apache.commons.lang.builder.EqualsBuilder;

public class Foo {
    public class Bar {
        private Bar() {}

        public Foo getMyFoo() {
            return Foo.this
        }

        private int myInt = 0;

        public boolean equals(Object o) {
            if (o == null || o.getClass() != getClass) return false;

            Bar other = (Bar) o;
            return new EqualsBuilder()
                .append(getMyFoo(), other.getMyFoo())
                .append(myInt, other.myInt)
                .isEquals();
        }
    }

    public Bar createBar(...) {
        //sensible implementation
    }

    public Bar createOtherBar(...) {
        //another implementation
    }

    public boolean equals(Object o) {
        //sensible equals implementation
    }
}

Is there syntax by which I can refer to other's Foo reference apart from declaring the getMyFoo() method? Something like other.Foo.this (which doesn't work)?

+1  A: 

No.

The best way is probably what you suggested: add a getFoo() method to your inner class.

+2  A: 

No, not possible without a getter. The 'this' keyword will always point to the current instance. I'm quite curious why you would want to do this... seems like you are doing composition in the wrong way.

public class Foo {

  public Bar createBar(){
    Bar bar = new Bar(this)
    return bar;
  }
}

public class Bar {
  Foo foo;
  public Bar(Foo foo){
    this.foo = foo;
  }

  public boolean equals(Object other) {
    return foo.equals(other.foo);
  }
}

Since using Foo.this limits creation of the inner class (Foo myFoo = new Foo(); myFoo.new Bar(); to an instance I'd say this is much cleaner.

p3t0r
Assume that Bar's constructor is private and instances are created by factory methods defined on Foo; also, each instance of Bar should be bound to an instance of Foo. It's possible to do this with static inner classes, but the whole point of the language feature is to simplify such usage.
Kris Nuttycombe
Oh, and both classes need to be able to refer to each others' private members.
Kris Nuttycombe
In my particular case, Bar is abstract and the factory methods return objects of anonymous classes extending Bar which implement a public method defined as abstract in Bar; the implementations close over the scope of the arguments passed to the respective factory methods.
Kris Nuttycombe
And of course overriding equals without overriding hashcode breaks the contract of Object; Bar needs to have public int hashcode() { return foo.hashcode(); }
Software Monkey
A: 

yes:

public class Foo {
    public class Bar {
        public Foo getMyFoo() {
            return Foo.this;
        }
    }
    public Foo foo(Bar bar) {
        return bar.getMyFoo();
     }
    public static void main(String[] arguments) {
        Foo foo1=new Foo();
        Bar bar1=foo1.new Bar();
        Foo foo=(new Foo()).foo(bar1);
        System.out.println(foo==foo1);
    }
}
Ray Tayek
This doesn't answer the question. In fact, it's pretty much what he was trying to avoid.
Michael Myers