Why can’t this static inner class call a non-static method on its outer class?

Robin Dos Anjos :

I'm currently reading Effective Java by Joshua Bloch and I love it! But on page 112 (Item 24) Bloch writes:

A static member class is the simplest kind of nested class. It is best thought of as an ordinary class that happens to be declared inside another class and has access to all of the enclosing class’s members, even those declared private.

And that really confuses me. I would rather say:

A static member class is the simplest kind of nested class. It is best thought of as an ordinary class that happens to be declared inside another class and has access to all of the enclosing class’s static members, even those declared private.

Here is a snippet that illustrates my understanding of the quote:

public class OuterClass {

    public void printMessage(String message) {
        System.out.println(message);
    }

    private static class InnerClass {

        public void sayHello() {
            printMessage("Hello world!"); //error: Cannot make a static reference to the non-static method printMessage(String)
        }

    }
}

You can see that InnerClass's sayHello method does not have access to OuterClass's printMessage method as it is declared in a static inner class while the printMessage method is an instance method. It looks like the author suggests that a static member class can access nonstatic fields of the enclosing class. I am convinced that I have misunderstood something in his last sentence but I cannot figure out what. Any help will be appreciated!

edit: I changed the visibility of the two methods because it is irrelevant to my question. I'm interested in static members, not private members.

Andreas :

Just because InnerClass is static, doesn't mean it couldn't obtain a reference to an instance of OuterClass through other means, most commonly as a parameter, e.g.

public class OuterClass {

    private void printMessage(String message) {
        System.out.println(message);
    }

    private static class InnerClass {

        private void sayHello(OuterClass outer) {
            outer.printMessage("Hello world!"); // allowed
        }

    }
}

If InnerClass had not been nested inside OuterClass, it would not have had access to the private method.

public class OuterClass {

    private void printMessage(String message) {
        System.out.println(message);
    }

}

class InnerClass {

    private void sayHello(OuterClass outer) {
        outer.printMessage("Hello world!"); // ERROR: The method printMessage(String) from the type OuterClass is not visible
    }

}

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=428091&siteId=1