5

I never realized this until today, but in Java private fields are not really private on inner classes. You can instantiate a class and access the fields as though they were public. My question is why was this done in Java? What design decisions led to what seems like a break in encapsulation? Are there any advantages to allowing this?

public class test {
    public static void main(String[] args) {
        Inner inner = new Inner();
        inner.data = "TEST";
        System.out.println(inner.data);

        Inner1 inner1 = new Inner1();
        inner1.data = "TEST";
        System.out.println(inner1.data);

        new test();
    }

    public test() {
        Inner2 inner2 = new Inner2();
        inner2.data = "TEST";
        System.out.println(inner2.data);

        Inner3 inner3 = new Inner3();
        inner3.data = "TEST";
        System.out.println(inner3.data);
    }

    private final class Inner3 {
        private String data;

        public String getData() {
            System.out.println("Inner3.getData()");
            return data;
        }

        public void setData(String data) {
            System.out.println("Inner3.setData(String)");
            this.data = data;
        }
    }

    private class Inner2 {
        private String data;

        public String getData() {
            System.out.println("Inner2.getData()");
            return data;
        }

        public void setData(String data) {
            System.out.println("Inner2.setData(String)");
            this.data = data;
        }
    }

    private static class Inner1 {
        private String data;

        public String getData() {
            System.out.println("Inner1.getData()");
            return data;
        }

        public void setData(String data) {
            System.out.println("Inner1.setData(String)");
            this.data = data;
        }
    }

    private static final class Inner {
        private String data;

        public String getData() {
            System.out.println("Inner.getData()");
            return data;
        }

        public void setData(String data) {
            System.out.println("Inner.setData(String)");
            this.data = data;
        }
    }
}
  • 1
    That is a language design decision... No one can really answer that except Mr Gosling, maybe. – fge Jul 26 '13 at 12:36
  • Duplicate of: http://stackoverflow.com/questions/1801718/why-can-outer-java-classes-access-inner-class-private-members – kiheru Jul 26 '13 at 12:40
  • 3
    @kiheru Not exactly. That question is asking how is this possible, I'm asking why this was done this way. What (dis)advantages it offers, etc. –  Jul 26 '13 at 12:41
  • @fge I guess from the "why" part, it is only truly answerable from the developers of the language, but of course there could be some obscure article someone that I was unable to find that clarifies this decision or it could be some common thing in programming language design. –  Jul 26 '13 at 12:43
  • 1
    @GlennNelson Members marked private can't be accessed by code in any class other than the class in which the private member was declared. Thinking that inner classes are considered, as Deisgn choice, part of the class where they are declared, they are at the same level as a private method, so they can access to the private field. – araknoid Jul 26 '13 at 12:50
  • If [this](http://docstore.mik.ua/orelly/java-ent/jnut/ch03_13.htm) is to be trusted, it is an implementation detail that became codified to the language spec. They got added to java 1.1 in a way that was compatible with the 1.0 JVM, which resulted in the behaviour we have now. – kiheru Jul 26 '13 at 13:06

1 Answers1

0

It helps with anonymous classes. They gain access to the class around (like with final variables in methods). Thus avoids a lot of setters/getters which you else had to make at least package private and thus sharing with more than the private class.

If you do not like that behaviour (like me most of the times), just use static private classes who then only have access to private static members which leaves me with a better gut feeling.

Matthias
  • 3,582
  • 2
  • 30
  • 41