#1032 ImmutableField Rule: Private field in inner class gives false positive

PMD-5.0.3
closed
pmd (542)
PMD
3-Major
Bug
2014-08-25
2012-10-03
Tommy
No

PMD proposes that "Private field i could be made final; it is only initialized in the declaration or constructor." in line 3 in the following example. (ImmutableField rule.) This is incorrect; the inner class field (Bar.i) is changed by the outer class (Foo) so it cannot be made final.
(For me it was slightly surprisingly that private fields in a static inner class can be accessed by the outer class, but they can, cf. e.g. http://stackoverflow.com/questions/1801718/why-can-outer-java-classes-access-inner-class-private-members)

    public class Foo {
        private static class Bar {
            private int i;
            Bar(final int i) {
                this.i = i;
            }
        }

        public int foo() {
            final Bar b = new Bar(1);
            b.i=0;
            return b.i;
        }
    }

Discussion

  • Andreas Dangel
    Andreas Dangel
    2012-10-04

    Thank you for your bug report.
    I could reproduce this bug with the latest PMD version and will try to fix it soon.

     
  • Andreas Dangel
    Andreas Dangel
    2012-10-21

    • milestone: PMD-5.1.x --> PMD-Backlog
     
  • Andreas Dangel
    Andreas Dangel
    2013-03-15

    • summary: Private field in inner class gives false positive --> ImmutableField Rule: Private field in inner class gives false positive
    • Description has changed:

    Diff:

    --- old
    +++ new
    @@ -1,17 +1,21 @@
     PMD proposes that "Private field i could be made final; it is only initialized in the declaration or constructor." in line 3 in the following example. (ImmutableField rule.) This is incorrect; the inner class field (Bar.i) is changed by the outer class (Foo) so it cannot be made final. 
     (For me it was slightly surprisingly that private fields in a static inner class can be accessed by the outer class, but they can, cf. e.g. http://stackoverflow.com/questions/1801718/why-can-outer-java-classes-access-inner-class-private-members)
    
    -public class Foo {
    -   private static class Bar {
    -       private int i;
    -       Bar(final int i) {
    -           this.i = i;
    -       }
    -   }
    
    -   public int foo() {
    -       final Bar b = new Bar(1);
    -       b.i=0;
    -       return b.i;
    -   }
    -}
    +~~~~~
    +:::java
    +    public class Foo {
    +        private static class Bar {
    +            private int i;
    +            Bar(final int i) {
    +                this.i = i;
    +            }
    +        }
    +        
    +        public int foo() {
    +            final Bar b = new Bar(1);
    +            b.i=0;
    +            return b.i;
    +        }
    +    }
    +~~~~~
    
    • status: open --> in-progress
    • module: --> PMD
    • milestone: PMD-Backlog --> PMD-5.0.3
    • priority: 5 --> 3-Major
    • type: --> Bug
    • affects_version: -->
     
  • Andreas Dangel
    Andreas Dangel
    2013-03-15

    • status: in-progress --> closed