6 Replies Latest reply: May 1, 2012 2:08 PM by 934135 RSS

    A problem about public and private

    934135
      public class outer {
      public int i = 1;
      private int j = 1;

      public static void main(String[] args) {
      new outer().new inner().Test();
      }

      class inner {
      public void Test() {
      i+=i+=1;
      j+=j+=1;

      System.out.println("i = " + i);
      System.out.println("j = " + j);
      }
      }
      }

      The results are below:
      i = 3
      j = 4

      Why do i not equal to j ????
        • 1. Re: A problem about public and private
          baftos
          I compiled and decompiled and the code inside Test() amazingly is:
          i += ++i;
          j+= = j+= = 1;
          Compiler bug? The second line does not even compile back, but I assume it's equivalent to:
           j+= (j+=1);
          • 2. Re: A problem about public and private
            rp0428
            Very good question.
            >
            Why do i not equal to j ????
            >
            Because 'j' is declared private.

            References from a member class ('inner' is a member class of 'outer') to private variables of the containing class ('outer' is the containing class) actually use an access method.

            You can see this if you use the JD-GUI decompiler

            This
            i+=i+=1;
            gets translated to something like this
            outer.this.i += ++outer.this.i;
            The above does a prefix increment of i (giving 2), then increments it (giving 3) and assigns it to 'i'

            But this
            j+=j+=1;
            gets translated to something like this
            outer.access$012(outer.this, outer.access$012(outer.this, 1));
            The above uses an accessor method to increment 'j' by 1 resulting in a 2, and then uses an accessor method again to add 'j' to itself resulting in 4. This results in the second computation using the new value of 'j' while the computation of 'i' used the original value of 'i'.

            See 'How Inner Classes Work' in 'Java In a Nutshell'
            http://docstore.mik.ua/orelly/java-ent/jnut/ch03_13.htm

            The second paragraph of section '3.13.1. Static Member Class Implementation' has the details
            In particular this sentence
            >
            the compiler automatically generates non-private access methods and converts the expressions that access the private members into expressions that access these specially generated methods.
            >
            and then section '3.13.2. Member Class Implementation' describes how member classes are implemented the same way.

            Others may be able to add additional information or explanation.
            In particular while the Java Language Specification defines what the language rules are it does not necessarily define how those rules must be implemented.

            So it is not clear to me if all compilers will implement private field access using a similar access method.

            The spec can be found at
            http://docs.oracle.com/javase/specs/jls/se7/html/index.html
            • 3. Re: A problem about public and private
              baftos
              Q: What is the value of i after:
              i = 1;
              i+=i+=1;
              A: It depends if i is a private or public member of an enclosing class or something else.

              Sorry, I can't buy it. I see it as a bug (implementation or design, who cares). According to operators precedence and associativity table, it should be 4, I believe.
              Maybe I am wrong, but it should be the same regardless of where and how i is declared.

              Edited by: baftos on Apr 30, 2012 7:47 PM
              • 4. Re: A problem about public and private
                rp0428
                >
                Sorry, I can't buy it.
                >
                Correct - it isn't for sale. No one was asking you to buy it.

                OP asked for an explanation so I provided it.
                >
                According to operators precedence and associativity table, it should be 4, I believe.
                >
                Your belief is wrong - please provide a citation for 'According to operators precendence and associativity table'

                The spec (see link I provided) has an example which demonstrates why 3 is correct.
                >
                Example 15.26.2-2. Value Of Left-Hand Side Of Compound Assignment Is Saved Before Evaluation Of Right-Hand Side
                >
                This excerpt
                        int k = 1;
                        k += (k = 4) * (k + 2);
                gives an answer of 25 for the final value of k since the initial value of 1 is 'saved' as explained in the doc.
                >
                The value 1 of k is saved by the compound assignment operator += before its right-hand operand (k = 4) * (k + 2) is evaluated. Evaluation of this right-hand operand then assigns 4 to k, calculates the value 6 for k + 2, and then multiplies 4 by 6 to get 24. This is added to the saved value 1 to get 25, which is then stored into k by the += operator.
                • 5. Re: A problem about public and private
                  aksarben
                  I hope this is just curiosity on your part. If you're using code like this for a real project, you're asking for trouble. It's so convoluted & hard to understand that you're just asking for a bug to bite you.
                  • 6. Re: A problem about public and private
                    934135
                    Are the public or private only for access attributes?