# Java Notes

# Shadow variables are evil

Methods and inner classes are declared in other classes. This allows the inner structures to reference variables in the outer structure. This is very useful, except for one dangerous case. When the inner structure, eg a method, declares its own local variables, what happens if a local variable has the same name as an outer instance variable?

The inner variable shadows the outer variable. This is almost always a bad idea, and leads to a lot of confusion. My advice is never shadow a variable.

## Setter methods

The one case where this is commonly used is in setter methods. These are methods which simply set instance variables. The reason to make them methods rather than simply public variables is so that in new value can be checked or the implementation may later be changed, and this change can be hidden in the method. However, the majority of these methods simply pass a value directly to/from an instance variable.

        int width;
        . . .
        public void setWidth(int width) {
            this.width = width;
        }

It is common to name the parameter the same as the instance variable. To refer to the instance variable rather than the parameter, it's necessary to qualify it with `this`.

## Example

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
    // Shadow.java -- Illustrate variable shadowing.
    // Fred Swartz - 2003 - Jun

    class Shadow {
        static int x = 1;
        public static void main(String[] args) {
            int x = 10;
            //--- prints local, not class variable.
            System.out.println("main  : x = " + x);
            //--- prints class, not local variable.
            System.out.println("main  : Shadow.x = " + Shadow.x);
            printa();
            printb(100);

        }//end main

        static void printa() {
            //--- prints x in enclosing scope, not x in caller.
            System.out.println("printa: x = " + x);
        }//end printa

        static void printb(int x) {
            //--- Parameters are like local variables.
            System.out.println("printb: x = " + x);
        }//end printb
    }//end class Shadow

Produces the following output.

    main  : x = 10
    main  : Shadow.x = 1
    printa: x = 1
    printb: x = 100