Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
bgColor#ccccff
class MyVector {
  private int val = 1;
  private void doLogic() {
    int newValue;
    //...   
  }
}

Noncompliant Code Example (Method Shadowing)

Method shadowing in different scopes becomes possible when two or more packages are used. Method shadowing differs from method overloading in that subclasses are allowed to inherit overloadings defined in the base class. It differs from hiding because the methods do not need to be declared static. It is also distinct from method overriding, as exemplified in this noncompliant code example.

Code Block
bgColor#FFcccc

package x;
public class A {
  void doLogic() { // default accessibility
    // print 'A'  
  }  
  public static void main(String[] args) {
    A a = new y.C();
    a.doLogic(); // invokes doLogic() of class x.B and prints 'B'
  }
}
Code Block
bgColor#FFcccc

package x;
public class B extends A {
  void doLogic() { // default accessibility
    // print 'B'  
  } 
}
Code Block
bgColor#FFcccc

package y; // different package
public class C extends x.B { // public accessibility 
  public void doLogic() { 
    // print 'C'
  } 
}

Note that class y.C is accessible from the package x and so is its doLogic() method. However, if the main() method, defined in class A, tries to polymorphically invoke y.doLogic() as shown, the override corresponding to class B in package x takes precedence. This is because the doLogic() methods in classes x.A and x.B are not visible from class y.C due to the default access specifier. As a result, the class x.C is not considered a part of the overriding hierarchy. Note, however, that the code behaves as expected if the access specifiers of all of the methods are changed to public.

Compliant Solution (Method Shadowing)

Use a different name to indicate that the class residing in another package is not intended to be part of the overriding chain. A programmer can use dotted notation to explicitly specify which class defines the method to be invoked. Avoid reusing names even when all the relevant classes define the affected methods with a public access specifier; future evolution of one or more of the classes can reduce method accessibility, leading to unexpected results.

Code Block
bgColor#ccccff

package x;
public class A {
  void doLogic() { 
    // print 'A'  
  }  

  public static void main(String[] args) {
    // explicitly invokes doSequence() of class y.C and prints 'C'
    y.C.doSequence(); 
  }
}
Code Block
bgColor#ccccff

package x;
public class B { /* ... */ }
Code Block
bgColor#ccccff

package y; // different package
public class C extends x.B {  
  public void doSequence() { // now renamed
    // print 'C' 
  } 
}

Exceptions

SCP02-EX1: Reuse of names is permitted for trivial loop counter declarations in the same scope:

...