Easy to Learn Java: Programming Articles, Examples and Tips

Start with Java in a few days with Java Lessons or Lectures

Home

Code Examples

Java Tools

More Java Tools!

Java Forum

All Java Tips

Books

Submit News
Search the site here...
Search...
 
Search the JavaFAQ.nu
1000 Java Tips ebook

1000 Java Tips - Click here for the high resolution copy!1000 Java Tips - Click here for the high resolution copy!

Java Screensaver, take it here

Free "1000 Java Tips" eBook is here! It is huge collection of big and small Java programming articles and tips. Please take your copy here.

Take your copy of free "Java Technology Screensaver"!.

Easy Learn Java: Programming Articles, Examples and Tips - Page 362


Previous 1060 Stories (530 Pages, 2 Per Page) Next

Final Newsletter

Go to all tips in Story by Dr. Kabutz
New Page 3

The Java Specialists' Newsletter [Issue 025] - Final Newsletter

Author: Dr. Heinz M. Kabutz

JDK version:

Category: Language

You can subscribe from our home page: http://www.javaspecialists.co.za (which also hosts all previous issues, available free of charge Smile

Welcome to the 25th issue of "The Java(tm) Specialists' Newsletter". I hope that for at least *some* of you, your heart sank when you saw the title of this newsletter. No, your mailbox is not getting lighter, I just thought I'd write a bit about how I use the "final" keyword. Incidentally, on Monday we broke through the 1000th reader barrier (on an upward trend) so thanks to all of you who promoted this newsletter and sent it to friends and colleagues. Please remember to forward this newsletter to as many Java enthusiasts as you know who might be interested in receiving such a newsletter.

The last few newsletters where quite heavy, so this week I would like to look at style, specifically on uses of the "final" keyword. It is not a newsletter on how to abuse the "final" keyword, which might surprise some of the more loyal readers of this newsletter.

I would like to thank Carl Smoritcz from Germany for hosting an archive of my newsletters at http://www.smotricz.com/kabutz. Please let me know if you would like to include an archive on your website. I am currently in discussion with a designer to put together a website for my company, which will include the newsletters and information about the type of work my company does.

Final

The keyword "final" in Java is used in different ways depending on the context. We can have final methods, final classes, final data members, final local variables and final parameters. A final class implicitely has all the methods as final, but not necessarily the data members. A final class may not be extended, neither may a final method be overridden.

Final primitive data members cannot be changed once they are assigned, neither may final object handle data members (Vector, String, JFrame, etc.) be reassigned to new instances, but if they are mutable (meaning they've got methods that allow us to change their state), their contents may be changed. Since String is immutable, once a handle to it is final, we *could* consider it as a constant, if we ignore the effects of newsletter 14. So how do we use this construct in the real world?


Final Methods

I personally try to avoid making a method final, unless there is a very good reason for it to be final. There are typically two reasons to make a method final, performance and design. Let's look at performance first:

When a method is final, it may be inlined. Before HotSpot compiling (JDK 1.1.x), these methods were usually inlined at compile time, whereas with HotSpot they are inlined at runtime, unless the compiler can guarantee that the inlined method will always be compiled together with the code that uses it.

// somebody else's class
public class A {
  public static final void f() {
    System.out.println("A's f()");
  }
}

// our class
public class B {
  public void g() {
    A.f();
  }
}

In the past, at compile time our class would be turned into:

// compiled class
public class B {
  public void g() {
    System.out.println("A's f()");
  }
}

The effect of this was that we had to make one less method call, and since method calls produce extra overhead, we saved some clock cycles. The disadvantage of this, made clear to me by an old (ok, experienced) COBOL programmer during one of my courses, was that whenever somebody else's class changed we would have to remember to recompile our class!

In JDK 1.[234].x with HotSpot(tm), Sun changed this so that the methods were no longer inlined at compile time, but rather by the HotSpot compiler at run time, IFF the performance measurements suggested that it would improve the overall performance of our code.

There are quite a few factors which will affect whether a method will be inlined or not, and we cannot assume that just because we make something final that it will definitely be inlined. As we saw in newsletter 21, it is a good idea anyway to always recompile all your code when you get a new version of someone else's library, so this is not necessarily a reason to NOT use final methods.

When you make a method final, no-one else will be able to override it again. You thus limit extensibility of your code by choosing to make the method or, even worse, your class final. I have been utterly frustrated in the past when I wanted to extend code where the developer had tried to add optimizations in the form of final. I thus never make a method or class final unless I specifically want to stop do others from overriding them.

So, when do I use final methods? If I have performance values that prove that final makes a difference then I would consider using it for performance reasons, otherwise I would only ever use it for design reasons.

This is all old hat for you I'm sure, so let's look at final data members:

Final data members

One of the difficulties in programming is coming up with good names for "things". (there, that just proves my point, doesn't it?) I remember an experienced (ok, old) C programmer who was programming in Java and decided to use very long names for everything, for example:

public class SessionConnectorWithRetryAtLeastThreeTimes {
  private String connectionNameReceivedFromInternet;
  private int numberOfTimesThatWeShouldRetryAtLeast;
}

Alright, I'm exaggerating a little bit, but I hope you get the idea. The beauty of good names is that comments become very easy to write, sometimes even partly redundant. In Java, we can then write a constructor that takes the state for the object and assigns the correct data members. For example:

public class SessionConnectorWithRetryAtLeastThreeTimes {
  private String connectionNameReceivedFromInternet;
  private int numberOfTimesThatWeShouldRetryAtLeast;
  public SessionConnectorWithRetryAtLeastThreeTimes(
	String c, int n) {
    connectionNameReceivedFromInternet = c;
    numberOfTimesThatWeShouldRetryAtLeast = n;
  }
}

The problem with our constructor is that we have to explain in our documentation what c and n represent. It would be much better to use the same names in the parameters of the constructor as we use for the data members, as it reduces the confusion. The standard way in Java of solving this problem is to use the same names for the parameters as we do for the data members and then to explicitely specify what we are referring to, using the "this" keyword.

public class SessionConnectorWithRetryAtLeastThreeTimes {
  private String connectionNameReceivedFromInternet;
  private int numberOfTimesThatWeShouldRetryAtLeast;
  public SessionConnectorWithRetryAtLeastThreeTimes(
	String connectionNameReoeivedFromInternet,
	int numberOfTimesThatWeShouldRetryAtLeast) {
    this.connectionNameReceivedFromInternet =
	connectionNameReceivedFromInternet;
    this.numberOfTimesThatWeShouldRetryAtLeast =
	numberOfTimesThatWeShouldRetryAtLeast;
  }
}

The above code will compile and run, but not correctly. Take a few minutes to figure out what could possible be wrong with it...

.

.

.

.

I hope you didn't find the mistake. The first parameter of the constructor is spelt differently to the data member, thanks to a simple spelling mistake. When we thus say

  this.connectionNameReceivedFromInternet =
    connectionNameReceivedFromInternet;

both the names refer to the data member, so the data member will always null!

This is the reason why some companies try to pursuade their staff to augment their data members with strange characters (m_ or _) to differentiate them from parameters, rather than use the "this" trick. I know of at least two companies where such coding standards are used. The effect is that either the data members look ugly, or the parameters look ugly.

A simple way of preventing such mistakes, besides learning to touch type 100% correctly, is to make the data members final, where possible. When we do that, the code below will no longer compile, and we can find our mistakes much easier.

public class SessionConnectorWithRetryAtLeastThreeTimes {
  private final String connectionNameReceivedFromInternet;
  private final int numberOfTimesThatWeShouldRetryAtLeast;
  public SessionConnectorWithRetryAtLeastThreeTimes(
	String connectionNameReoeivedFromInternet,
	int numberOfTimesThatWeShouldRetryAtLeast) {
    this.connectionNameReceivedFromInternet =
	connectionNameReceivedFromInternet;
    this.numberOfTimesThatWeShouldRetryAtLeast =
	numberOfTimesThatWeShouldRetryAtLeast;
  }
}

As a matter or habit, I make all data members final wherever that is possible. Mistakes that would have taken me days to find now pop out at the next compile.

Final local variables

There are two reasons I know for making a local variable or a parameter final. The first reason is that you don't want your code changing the local variable or parameter. It is considered by many to be bad style to change a parameter inside a method as it makes the code unclear. As a habit, some programmers make all their parameters "final" to prevent themselves from changing them. I don't do that, since I find it makes my method signature a bit ugly.

The second reason comes in when we want to access a local variable or parameter from within an inner class. This is the actual reason, as far as I know, that final local variables and parameters were introduced into the Java language in JDK 1.1.

public class Access1 {
  public void f() {
    final int i = 3;
    Runnable runnable = new Runnable() {
	public void run() {
	  System.out.println(i);
	}
    };
  }
}

Inside the run() method we can only access i if we make it final in the outer class. To understand the reasoning, we have to look at what the compiler does. It produces two files, Access1.class and Access1$1.class. When we decompile them with JAD, we get:

public class Access1 {
  public Access1() {}
  public void f() {
    Access1$1 access1$1 = new Access1$1(this);
  }
}

and

class Access1$1 implements Runnable {
  Access1$1(Access1 access1) {
    this$0 = access1;
  }
  public void run() {
    System.out.println(3);
  }
  private final Access1 this$0;
}

Since the value of i is final, the compiler can "inline" it into the inner class. It perturbed me that the local variables had to be final to be accessed by the inner class until I saw the above.

When the value of the local variable can change for different instances of the inner class, the compiler adds it as a data member of the inner class and lets it be initialised in the constructor. The underlying reason behind this is that Java does not have pointers, the way that C has.

Consider the following class:

public class Access2 {
  public void f() {
    for (int i=0; i<10; i++) {
	final int value = i;
	Runnable runnable = new Runnable() {
	  public void run() {
	    System.out.println(value);
	  }
	};
    }
  }
}

The problem here is that we have to make a new local data member each time we go through the for loop, so a thought I had today while coding, was to change the above code to the following:

public class Access3 {
  public void f() {
    Runnable[] runners = new Runnable[10];
    for (final int[] i={0}; i[0]0]++) {
	runners[i[0]] = new Runnable() {
	  private int counter = i[0];
	  public void run() {
	    System.out.println(counter);
	  }
	};
    }
    for (int i=0; ipublic static void main(String[] args) {
    new Access3().f();
  }
}

We now don't have to declare an additional final local variable. In fact, is it not perhaps true that int[] i is like a common C pointer to an int? It took me 4 years to see this, but I'd like to hear from you if you have heard this idea somewhere else.

I always appreciate any feedback, both positive and negative, so please keep sending your ideas and suggestions. Please also remember to take the time to send this newsletter to others who are interested in Java.

Heinz


Errata
In newsletter 23, I relied on hearsay for some information without checking it out myself. Yes, the amount of memory used by each Thread for its stack was incorrect. According to new measurements, it seems that each stack takes up approximately 20KB, not the 2MB stated in the original newsletter, so for 10000 threads we will need about 200MB. Most operating systems cannot handle that many threads very well anyway, so we want to avoid creating that many. Thanks to Josh Rehman for pointing out this mistake.

It seems that with JDK 1.1.8 each thread takes up 145KB, I'm not sure whether the stacks grow dynamically. Under the JDK 1.2.2 that comes with JBuilder 3, the stacks grow, so I managed to have 100 threads take up roughly 100 MB of memory, or 1MB each. After 1 MB is used up, the VM mysteriously returns without any message so I had to experiment a bit to get this information. Under JDK 1.3.0 I got DrWatsons when I tried to make the stack of each thread grow to any real size. It is unrealistic to expect our program to have stack depths of 10000 method calls, so we could probably quite safely use 50KB as a realistic stack size for each thread.


Copyright 2000-2004 Maximum Solutions, South Africa

Reprint Rights. Copyright subsists in all the material included in this email, but you may freely share the entire email with anyone you feel may be interested, and you may reprint excerpts both online and offline provided that you acknowledge the source as follows: This material from The Java(tm) Specialists' Newsletter by Maximum Solutions (South Africa). Please contact Maximum Solutions for more information.

Java and Sun are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States and other countries. Maximum Solutions is independent of Sun Microsystems, Inc.

15134 bytes more | 3 comments | Printer Friendly Page  Send to a Friend | Score: 0
Posted by jalex on Sunday, May 22, 2005 (00:00:00) (2209 reads)

Iterative/Incremental Development -II

Go to all tips in Java Notes by Fred Swartz

Advantages of waterfall development

Not everything is bad about this approach.
  • By writing the entire program first, you are become aware of problem areas, and take corrective action.
  • It may simply suit your personality better.
  • If the problem is very well understood, this may be the most efficient solution. However, experience has shown that it is frequently inferior to iterative programming.

Iterative and Incremental DevelopmentWaterfall steps

  • Start with a very small version of the program. So small that maybe it doesn't too much besides show some part of the graphical user interface, but doesn't do anything. Test it to make sure it runs ok.
  • Analysis. Decide which improvement should be made next. Make a small change.
  • Design how you will will code the change.
  • Code it and compile to make sure your coding is correct. Often I type only a couple of lines of code before recompiling. Some IDEs, such as NetBeans, does continuous compilation which shows your errors without the need for an explicit compilation request.
  • Testing. Run the program, using test data if necessary. If it doesn't run, the program must be debugged and either the coding or design should be changed. Because the last change should have been small, it's usually easy to identify the source of the problem.
  • Continue around this loop until the program is finished, or you've run out of resources (time). Using the iterative appoach means that there's a running program at the end of each iteration. It doesn't to everything, but it is something you can turn in. For a company this means that it may be able to use the program for some work and get value out of it before it is finished. It also means that the project can be terminated as soon as the program is "good enuf".

It's often hard for students to restrict themselves to small changes, and they write many, many lines of code. Or to think of it another way, many bugs. The more simultaneous bugs a program has, the harder it is to debug, so keep the number of new bugs to a minimum.

Making very small changes, compiling and testing means that you are much less likely to be faced with a long list of error messages with no idea how to find the problem. A single missing left brace can produce many error messages. If you've only entered a few lines of code before recompiling, you know the error is in those few lines of code and it's much easier to track it down.

Advantages of iterative development

  • You always have a running version of the program, eg, if you run out of time, you can deliver the last iteration, which may not have all functionality, but it does something. This is usually worth more to your instructor than a program which doesn't even compile yet.
  • It helps identify the source of the last error (compilation or execution), because you know it's in the code you just added in this iteration. This makes finding bugs much faster.
  • It's psychologically more satisfying to get positive feedback on your work, ie, a running program.
  • Corrections early in development generally take less time than later in the development process.

Disadvantages of iterative development

  • The iterative approach tempts you to start coding too early. You should have a good idea of what the final program should look like before starting. Unless you're clear on what you want, it's likely that many extra iterations will be required.

4136 bytes more | 4 comments | Printer Friendly Page  Send to a Friend | Score: 3
Posted by jalex on Sunday, May 22, 2005 (00:00:00) (8580 reads)

Previous 1060 Stories (530 Pages, 2 Per Page) Next

530| 529| 528| 527| 526| 525| 524| 523| 522| 521| 520| 519| 518| 517| 516| 515| 514| 513| 512| 511| 510| 509| 508| 507| 506| 505| 504| 503| 502| 501| 500| 499| 498| 497| 496| 495| 494| 493| 492| 491| 490| 489| 488| 487| 486| 485| 484| 483| 482| 481| 480| 479| 478| 477| 476| 475| 474| 473| 472| 471| 470| 469| 468| 467| 466| 465| 464| 463| 462| 461| 460| 459| 458| 457| 456| 455| 454| 453| 452| 451| 450| 449| 448| 447| 446| 445| 444| 443| 442| 441| 440| 439| 438| 437| 436| 435| 434| 433| 432| 431| 430| 429| 428| 427| 426| 425| 424| 423| 422| 421| 420| 419| 418| 417| 416| 415| 414| 413| 412| 411| 410| 409| 408| 407| 406| 405| 404| 403| 402| 401| 400| 399| 398| 397| 396| 395| 394| 393| 392| 391| 390| 389| 388| 387| 386| 385| 384| 383| 382| 381| 380| 379| 378| 377| 376| 375| 374| 373| 372| 371| 370| 369| 368| 367| 366| 365| 364| 363|
362
| 361| 360| 359| 358| 357| 356| 355| 354| 353| 352| 351| 350| 349| 348| 347| 346| 345| 344| 343| 342| 341| 340| 339| 338| 337| 336| 335| 334| 333| 332| 331| 330| 329| 328| 327| 326| 325| 324| 323| 322| 321| 320| 319| 318| 317| 316| 315| 314| 313| 312| 311| 310| 309| 308| 307| 306| 305| 304| 303| 302| 301| 300| 299| 298| 297| 296| 295| 294| 293| 292| 291| 290| 289| 288| 287| 286| 285| 284| 283| 282| 281| 280| 279| 278| 277| 276| 275| 274| 273| 272| 271| 270| 269| 268| 267| 266| 265| 264| 263| 262| 261| 260| 259| 258| 257| 256| 255| 254| 253| 252| 251| 250| 249| 248| 247| 246| 245| 244| 243| 242| 241| 240| 239| 238| 237| 236| 235| 234| 233| 232| 231| 230| 229| 228| 227| 226| 225| 224| 223| 222| 221| 220| 219| 218| 217| 216| 215| 214| 213| 212| 211| 210| 209| 208| 207| 206| 205| 204| 203| 202| 201| 200| 199| 198| 197| 196| 195| 194| 193| 192| 191| 190| 189| 188| 187| 186| 185| 184| 183| 182| 181| 180| 179| 178| 177| 176| 175| 174| 173| 172| 171| 170| 169| 168| 167| 166| 165| 164| 163| 162| 161| 160| 159| 158| 157| 156| 155| 154| 153| 152| 151| 150| 149| 148| 147| 146| 145| 144| 143| 142| 141| 140| 139| 138| 137| 136| 135| 134| 133| 132| 131| 130| 129| 128| 127| 126| 125| 124| 123| 122| 121| 120| 119| 118| 117| 116| 115| 114| 113| 112| 111| 110| 109| 108| 107| 106| 105| 104| 103| 102| 101| 100| 99| 98| 97| 96| 95| 94| 93| 92| 91| 90| 89| 88| 87| 86| 85| 84| 83| 82| 81| 80| 79| 78| 77| 76| 75| 74| 73| 72| 71| 70| 69| 68| 67| 66| 65| 64| 63| 62| 61| 60| 59| 58| 57| 56| 55| 54| 53| 52| 51| 50| 49| 48| 47| 46| 45| 44| 43| 42| 41| 40| 39| 38| 37| 36| 35| 34| 33| 32| 31| 30| 29| 28| 27| 26| 25| 24| 23| 22| 21| 20| 19| 18| 17| 16| 15| 14| 13| 12| 11| 10| 9| 8| 7| 6| 5| 4| 3| 2| 1|


Home Code Examples Java Forum All Java Tips Books Submit News, Code... Search... Offshore Software Tech Doodling

RSS feed Java FAQ RSS feed Java FAQ News     

    RSS feed Java Forums RSS feed Java Forums

All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest 1999-2006 by Java FAQs Daily Tips.

Interactive software released under GNU GPL, Code Credits, Privacy Policy