Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make `this` point to the outer class where the inner class has the same method name

Tags:

java

Let's say I have the following code:

abstract class MyStream
{
    public abstract Iterable<Integer> getIterable();

    public MyStream append(final int i)
    {
        return new MyStream()
        {
            @Override
            public Iterable<Integer> getIterable()
            {
                return cons(/*outer class's*/getIterable(), i);
            }
        };
    }

    public static Iterable<Integer> cons(Iterable<Integer> iter, int i) { /* implementation */ }
}

How can I reference getIterable of the outer class from the inner class with the same name?

MyStream.this should point to the inner class here, right? How to show an outer class with the same name?

like image 261
Jason Hu Avatar asked Jan 06 '15 18:01

Jason Hu


People also ask

How do you access the outer class method of an inner class?

To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax: OuterClass outerObject = new OuterClass(); OuterClass. InnerClass innerObject = outerObject.

Can we call outer class method in inner class?

You're first question (whether the inner class holds an instance of the outer class) was the relevant question; but the answer is yes, always.

Which modifier is applicable for both inner and outer classes?

Public Access Modifier in Java 1. Public access modifier can apply to instance variables, constructors, inner classes, outer class, methods but not with local variables.

How do you access methods in an inner class?

As the inner class exists inside the outer class we must instantiate the outer class in order to instantiate the inner class. Hence, to access the inner class, first create an object of the outer class after that create an object of the inner class.


2 Answers

If you call MyStream.this from the anonymous class it will point to the outer class so the code below should work as you expect:

return const(MyStream.this.getIterable(), i);

(if it did not you would get a StackOverflowError).

The reason why it works is that an anonymous class is an inner class.


Simplified example that prints outer 1:

public static void main(String args[]) {
  MyClass c = new MyClass() {
    @Override public String get() { return "outer"; }
  };
  System.out.println(c.append(1).get());
}

static abstract class MyClass {
  public abstract String get();

  public MyClass append(final int i) {
    return new MyClass() {
      @Override public String get() {
        return cons(MyClass.this.get(), i);
      }
    };
  }

  public static String cons(String iter, int i) { return iter + " " + i; }
}
like image 151
assylias Avatar answered Nov 15 '22 18:11

assylias


MyStream.this does not point to the inner class. The inner class is anonymous. It may confuse you because you used new MyStream() {...}, but in fact it's a new inner class, which has an internal name, and the new MyStream() {...} syntax simply serves to replace the SomeClass extends MyStream syntax.

It is worth noting that the inner class both extends MyClass and is nested in it. This means that both super and MyClass.this exist and are MyClass references, but they are two distinct object instances. super points to the inner class instance itself, but looks at it as if it was MyClass, while MyClass.this is the enclosing object.

like image 27
RealSkeptic Avatar answered Nov 15 '22 19:11

RealSkeptic