Access method of outer anonymous class from inner anonymous class

Rulle :

I instantiate an anonymous class with a method that instantiates another anonymous class, and from this inner anonymous class I want to call a method belonging to the outer anonymous class. To illustrate it, suppose I have this interface:

interface ReturnsANumber {
    int getIt();
}

And then, somewhere in my code, I do this:

    ReturnsANumber v = new ReturnsANumber() {
            int theNumber() {
                return 119;
            }

            public int getIt() {

                // In a modern version of Java, maybe I could do
                //   var a = this;
                // and then call a.theNumber();

                ReturnsANumber w = new ReturnsANumber() {
                        int theNumber() {
                            return 1;
                        }

                        public int getIt() {
                            return this.theNumber();
                        }
                    };

                return w.getIt();
            }
        };
    System.out.println("The number is " + v.getIt());

Question: In the innermost method getIt, I want to call theNumber() belonging to the outermost anonymous class. How can I accomplish that without using the Java 10 var feature (as hinted in the code).

Clarification: Ideally, the outer anonymous class should not need to know that the inner class wants to call its theNumber method. The idea is to come up with some code that lets the inner class unambiguously call any method on the outer class.

In other words, how can I make this code display: The number is 119 (instead of displaying The number is 1)

Motivation: Someone might ask why I want to do this anyway: I am writing some sort of code generator and want to be sure that the code that I am generating is not ambiguous.

ETO :

Since Java 8 the solution is pretty easy. Just store the method reference in a variable.

ReturnsANumber v = new ReturnsANumber() {
        int theNumber() {
            return 119;
        }

        public int getIt() {

            Supplier<Integer> supplier = this::theNumber;

            ReturnsANumber w = new ReturnsANumber() {
                int theNumber() {
                    return 1;
                }

                public int getIt() {
                    return supplier.get();
                }
            };

            return w.getIt();
        }
    };

Storing outer object could also do the trick. But for inherited methods only:

interface ReturnsANumber {
    int theNumber();
    int getIt();
}

public int getIt() {
    ReturnsANumber outer = this;

    ReturnsANumber w = new ReturnsANumber() {
        public int theNumber() {
            return 1;
        }

        public int getIt() {
            return  outer.theNumber();
        }
     };

     return w.getIt();
 }

You can store the method reference or the outer object as a field also.

Update

@Holger proposed another workaround. You can pass your outer object to a lambda:

ReturnsANumber v = new ReturnsANumber() {
    ...
    @Override
    public int getIt() {
        ReturnsANumber w = Optional.of(this).map(outer ->
                new ReturnsANumber() {
                    int theNumber() {
                        return 1;
                    }
                    public int getIt() {
                        return outer.theNumber();
                    }
                }).get();
        return w.getIt();
    }
};

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=35176&siteId=1