All 2 entries tagged Pet

No other Warwick Blogs use the tag Pet on entries | View entries tagged Pet at Technorati | There are no images tagged Pet on this blog

May 09, 2006

A better explanation than mine :)

Follow-up to Java Pet Peeves #3:Lack of use of the final keyword from Colin's blog

This guys goes into the ins and outs of the final keyword. Not sure he is saying anything that I didn't, but he does say it better and as my wife keeps stating "it's not what you say, it is the way that you say it" :) :)

link


February 06, 2006

Java Pet Peeves #3:Lack of use of the final keyword

Seeing as how I am on a roll ;)

The use of the final keyword is so important within Java; I fully believe that the function of the code should be readable without comments, even if the reason for the code needs commenting (this will be explained in another Pet Peeve ;)), and appropriate use of the "final" keyword is another way of documenting your code. The side effect of allowing the JDK to help you, is of course a bonus :) :)

Objects; how are they passed?

The "final" keyword in java doesn't mean (as some think) "do not change the state of this object", it means "do not change the variable containing the reference to this object". This is a subtle, but extremely important distinction. Generally speaking, objects can be passed in one of two ways, by value, or by reference. By value means a copy of the object is passed, leaving the original intact. By reference means a pointer to the same object is passed. Java manages to combine the two by passing a copy of the reference. For example:


  public class ClassA {
    public void doSomething(List myList) {
    }

    public static void main(String args[]) {
      List myList = new ArrayList();
      doSomething(l);
    }
  }

When doSomething() is called with a reference to myList the JDK will provide a copy of the reference to myList. This means that the doSomething method can manipulate myList, but it cannot reassign the reference to myList:


  public class ClassA {
    public void doSomething(List myList) {
      myList = new ArrayList();
      myList.add("hi");
      System.out.println("doSomething contains " + myList.size() + " elements");
    }

    public static void main(String args[]) {
      List myList = new ArrayList();
      doSomething(l);
      System.out.println("MyList still points to the same list as before, with " + myList.size() + " elements");
    }
  }

will result in the following statements:


doSomething contains 1 elements
MyList still points to the same list as before, with 0 elements

This is because the myList variable that doSomething method is modifying is a copy of the myList variable in the main method. Hence; Java passed objects by a copy of the reference!

The two copies of myList reference the same bit of memory though, so:


  public class ClassA {
    public void doSomething(List myList) {
      myList.add("hi");
      System.out.println("doSomething contains " + myList.size() + " elements");
    }

    public static void main(String args[]) {
      List myList = new ArrayList();
      doSomething(l);
      System.out.println("MyList still points to the same list as before, with " + myList.size() + " elements");
    }
  }

will result in the following statements:


doSomething contains 1 elements
MyList still points to the same list as before, with 1 elements

So if you wanted to prevent access to myList, how would you do it? In short; you can't. Making the method parameter final prevents you modifying the the reference, not the object the reference is to:


  public class ClassA {
    public void doSomething(final List myList) {      
      myList.add("hi");  // I can still modify myList
      myList = new ArrayList(); // won't compile.  Cannot change where myList points to
    }

    public static void main(String args[]) {
      List myList = new ArrayList();
      doSomething(l);
      System.out.println("MyList still points to the same list as before, with " + myList.size() + " elements");
    }
  }

Final; so what does it do?

What does making a method or a class final do? It prevents you extending the class:


public class ClassCanBeExtended {
  public void methodWhichCanBeExtended() {
  }

  public final void methodCannotBeExtended() {
  }
}

public final class ClassCannotBeExtended {
}

results the following scenarios:


public class ExtendingClass extends ClassCanBeExtended { // fine.
  public void methodWhichCanBeExtended() { // fine
  }

  public final void methodCannotBeExtended() {  // fails because the super class is final.
  }
}

public class WontCompileClass extends ClassCannotBeExtended {  // won't compile.
}

Making a static, member, method or local variable final (as discussed) prevents you assigning more than one copy to it.

So why use it?

The reason you would use the final depends upon where you would use it:

[classes, methods]
Use it to prevent others from changing the behaviour of your code.

[member variables]
Use it to indicate that the class requires access to a collaborator and the class cannot handle changing that collaborator once it has been instantiated:


public class ClassWithCollaborator {
  private final Collaborator collaborator;
  public ClassWithCollaborator(Collaborator myCollaborator) {
    super();
    this.collaborator = myCollaborator;
  }
 
  public void setCollaborator(final Collaborator a) {
    this.collaborator = a; // won't compile!
  }
}

[method or local parameters]
Use this if you want to prevent name space clashes:


public void doSomething(final List myList) {
  myList = new ArrayList();  // won't compile!
  final List anotherList = new ArrayList();
  anotherList = new ArrayList(); // won't compile either.

}

So; if you are still reading ;) Please think carefully about:

a) Can your class handle changing the reference to something once it has been initialised? If not, make the initialisation final.
b) Are you trying to prevent access to an object passed into a method? If so, don't use final because it won't do what you think :)

HTH someone ;)


July 2020

Mo Tu We Th Fr Sa Su
Jun |  Today  |
      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
27 28 29 30 31      

Search this blog

Tags

Galleries

Most recent comments

  • Interesting… While I'm not completely convinced in such microbenchmarks, I'm pretty sure that 1ms … by Alexander Snaps on this entry
  • Hello. I bought the book yesterday. I was trying to find the source code for chapter 11 and chapter … by Suleman on this entry
  • http://woosight.net/account/login?username=demo by live mashup demo on this entry
  • Thanks mate ….. This blog was really helpful. by Maaz Hurzuk on this entry
  • Ty. Not directly helpful for my problem, but pointed me in the right direction. You will also get th… by Mike E. on this entry

Blog archive

Loading…
RSS2.0 Atom
Not signed in
Sign in

Powered by BlogBuilder
© MMXX