Storing Objects in Java
by Thomas Paul
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Cindy's Segment - a Whimsical View of the World Segment 7: Asserting Yourself in Public Or - Testing Your Skills
Copyright ? 2002. Cindy Glass. All rights reserved. Graphics by Pauline McNamara and Stephanie Grasson Next month - "Abnormal Psychology"- or - "Volitile and Transient Moods" ? ? Return to Top |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Assertions - Debugging in J2SE 1.4by Thomas PaulIntroductionAssertions are new to Java and are included in the SCJP 1.4 exam. Anyone planning to take the exam should understand the concepts behind the assert keyword. In fact, all Java developers should understand assertions so they can determine if using them can be helpful in their development projects. In order to make assertions work, a new keyword, assert, has been added to Java. This means that a class written using assertions can not be compiled using older versions of J2SE. It also means that classes compiled with the assert keyword can not be run in earlier versions of the JRE. What is the purpose of the assert keyword? The purpose of assertions is to test your assumptions about the state of your program during execution. For example, if variable employee should never be null, you can test this assumption and stop your program if it occurs. Assertions are designed to be a development aid. You should not use assertions with the idea of testing conditions during production runs. Your class may be executed with assertions turned off so that if your program relies on assertions to run correctly then it may fail.
The BasicsThe simple format of the assert statement is:
The BooleanExpression is any expression that returns either a true or false. Assuming that we are running with assertions turned on, Java will terminate with an AssertionError if this statement returns a false. The second format of the assert statement is:
The ValueExpression can be any expression that returns a value. The value (normally a String) will be added to the error message returned when the assertion fails. Let's look at a very simple program using an assertion.
This program will always terminate with an AssertionError if assertions are turned on. To compile this program we need to add a parameter (-source) to the compile statement. If we don't add the -source, use of the assert keyword will generate a compile error:
Here's the javac command to compile our assertion test class:
After successfully compiling, if you want to execute your program with assertions turned on then you must us the -enableassertions (or -ea) switch. To execute our assertion test program we would do the following:
This will give us this result:
Using AssertionsSo why do we use assertions? The purpose of an assertion is to test to see if something that should never happen happens! So if we calculate a value and that value should only contain an even number, we can test that assertion and throw an AssertionError if the test fails. For example:
The result of running this class will depend on the input. At times it will run normally and other times it will throw an AssertionError. This gives you an opportunity to test your assumption (the getEvenNumber method always returns an even number) without having to write if...else logic and having to remove the code for production. It also helps to document your assumptions as the next person to work on this class will see that you are asserting that the getEvenNumber method always returns an even number. However, you do not want to code your programs as if assertions are always turned on. Remember, assertions must be specifically activated at runtime or they will not be executed. As an example, the following code may look like a good way to validate input to your method but it should be avoided.
If the class is executed without assertions being turned on, the validation will not occur. Instead of using assertions for this case, you should use normal if...else constructs. You should use assertions (1) during development and (2) while in production to debug production problems. Testing such as the example above where we are verifying the input prior to executing the method's logic is called precondition verification. Never use assertions for precondition verification unless it is in a private method where you control the input. In that case, you can verify that your code is giving the correct input to your method. Assertions can be used for postcodition verification in private or public methods. Postcondition verification is where we test the output of our method to insure that the result we are returning is correct. An example of postcondition verification:
Another way to use assertions is to test for class invariants. A class invariant is a condition that should always be true about a class. Imagine we have a class representing a deck of cards. Once the class is instantiated it should contain an array of 52 entries each with a different random number between 1 and 52 without duplicates. We can create a method to test this assumption and then execute this method to verify that the class is working correctly. For example:
Final ThoughtsSun has an excellent tutorial on using assertions. You can see it at: http://java.sun.com/j2se/1.4/docs/guide/lang/assert.html According to Sun, the runtime cost of using assertions when they are turned off is negligible. This means that we can leave our assertions in our code for production without paying a price for skipping over them. Using assertions should help to improve the quality of the code you produce. We can now test all of our assumptions easily, insuring that our code is as bullet-proof as we think. So give assertions a try. Return to Top |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Sun Certified Java Programmers Exam for JDK 1.4
Marcus Green August 2002
When is it available/can I take the beta?
How have the objectives changed?
Assertions
The wrapper classes
Using hashcode
Which version of the exam should I take?
How hard will the 1.4 exam be?
Are the new objectives a ?good thing??
What free study materials are available for the new exam?
Return to Top |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
An Introduction to
by Dirk Schreckmann
|
String input = "She sells sea shells by the sea shore." ; // Create a Pattern object. A Pattern is a // compiled representation of a regular expression. Pattern pattern = Pattern.compile( "shells" ); // Create a Matcher object. A Matcher is an engine that // performs match operations on a character sequence by // interpreting a Pattern. Matcher matcher = pattern.matcher( input ); System.out.println( matcher.matches() ); // Prints false. matcher.matches() attempts to // match the entire input sequence against the pattern. // The match would have succeeded, if the pattern described // the entire input String. System.out.println( matcher.lookingAt() ); // Prints false. matcher.lookingAt() attempts to // match the input sequence, starting at the beginning, // against the pattern. The match would have succeeded, // if the pattern were "She". System.out.println( matcher.find() ); // Prints true. matcher.find() attempts to find // the next subsequence of the input sequence that // matches the pattern. |
Matcher
and Pattern
objects have methods to return
the parts of an input String
matched against a pattern. The String
group()
method of the Matcher
class returns the input
subsequence matched by the previous match4.
The String[] split( CharSequence )
method of the Pattern
class splits the specified input character sequence around matches of a pattern3.
(Since Java 1.4, String
objects also have two split methods that
take a regular expression as a parameter and split the String
object
around matches of the regular expression, returning a String
array
of the result.)
// The Matcher must be reset and searched again after // failed attempts at matching. The Matcher would // otherwise not be in a proper state to get the // information related to the last match and methods // that query for such information would throw an // IllegalStateException. Note that the find() method // resets the Matcher if previous attempts at matching // failed. System.out.println( matcher.find() ); // Prints true. System.out.println( matcher.group() ); // Prints shells. String[] splits = pattern.split( input ); System.out.println( splits.length ); // Prints 2. for ( int i = 0 ; i < splits.length ; i++ ) // Prints { // She sells sea System.out.println( splits[ i ] ); // by the sea shore. } |
Note that regular expression patterns in Java are by default case sensitive. So, using the same input, a search for "Shells" would have failed.
pattern = Pattern.compile( "Shells" ); // Since a new Pattern is to be used, a new Matcher // must also be used. matcher = pattern.matcher( input ); System.out.println( matcher.find() ); // Prints false. |
Meta characters, in regular expressions, are characters that allow the description of more flexible text patterns than exact text (such as "shells" or "shore"). Meta characters are not interpreted literally. Meta characters used in describing Java regular expressions include "." , "?" , "+" , "*" , "{" , "}" , "(" , ")" , "[" , "]" , "$" , "^" , "|" , "&&" , "<" , "!" , "=" , ":" , and "\" . Some of these meta characters and their uses are introduced in this lesson. Further meta characters and their uses will be covered in following lessons.
Characters such as "?" , "+" , "*" , and "{}" provide the ability to match a pattern element multiple (or zero) times.
? | Matches the preceding element zero or one times. |
+ | Matches the preceding element one or more times. |
* | Matches the preceding element zero or more times. |
{n} | Matches the preceding element n number of times. |
{min,max} | Matches the preceding element a specified number of times from min to max inclusive. |
{min,} | Matches the preceding element min or more times. |
These elements must be prefixed by another pattern element to be matched.
input = "Some say, ABBA is a grooooovy music group." ; pattern = Pattern.compile( "is?" ); // Matches the "i" character or the "i" character // followed by an "s". matcher = pattern.matcher( input ); System.out.println( matcher.find() ); // Prints true. System.out.println( matcher.group() ); // Prints is. pattern = Pattern.compile( "x?" ); // Matches the "x" character or nothing. matcher = pattern.matcher( input ); System.out.println( matcher.find() ); // Prints true. System.out.println( matcher.group() ); // Prints the empty String. pattern = Pattern.compile( "AB+A" ); // Matches the sequence of characters that begins // and ends with "A" with one or more "B" characters // in the middle. matcher = pattern.matcher( input ); System.out.println( matcher.find() ); // Prints true. System.out.println( matcher.group() ); // Prints ABBA. pattern = Pattern.compile( "AB*C*A" ); // Matches the sequence of characters that begins // and ends with "A" and has zero or more "B" // characters followed by zero or more "C" characters // in the middle. matcher = pattern.matcher( input ); System.out.println( matcher.find() ); // Prints true. System.out.println( matcher.group() ); // Prints ABBA. pattern = Pattern.compile( "gro{2,}vy" ); // Matches the sequence of characters that begins // "gr" , ends with "vy" , and has two or more "o" // characters in the middle. matcher = pattern.matcher( input ); System.out.println( matcher.find() ); // Prints true. System.out.println( matcher.group() ); // Prints grooooovy. pattern = Pattern.compile( "gro?vy" ); // Matches the sequence of characters that begins // "gr" , ends with "vy" , and has zero or one "o" // characters in the middle. matcher = pattern.matcher( input ); System.out.println( matcher.find() ); // Prints false. |
Square brackets, "[]" , allow the description of a set of characters (known as a character class), of which one and only one character must match.
pattern = Pattern.compile( "[Rr]egular" ); // Matches "Regular" or "regular". input = "I like regular expressions." ; matcher = pattern.matcher( input ); System.out.println( matcher.find() ); // Prints true. System.out.println( matcher.group() ); // Prints regular. input = "Regular expressions are great." ; matcher.reset( input ); // Since the same Pattern is to be used to match // against a new input, the Matcher need only // be reset using the new input sequence // (a new Matcher need not be obtained.) System.out.println( matcher.find() ); // Prints true. System.out.println( matcher.group() ); // Prints Regular. |
To match any single lowercase letter of the english alphabet, it's possible to specify such a pattern as:
Fortunately, a few "shortcut" regular expression constructs are available. To match a range of characters, the "-" character can be used. So, "[a-z]" describes the same range of characters above.
The regular expression syntax allows two styles to describe the union of two or more character classes. "[a-c[f-h]]" and "[a-cf-h]" both describe the character class "[abcfgh]".
Other "shortcut" constructs include these often used predefined character classes3:
. | matches a single character (may or may not match line terminators) |
\d | matches a digit: [0-9] |
\D | matches a non-digit: [^0-9] * |
\s | matches a whitespace character: [ \t\n\x0B\f\r] (see footnote on characters) |
\S | matches a non-whitespace character: [^\s] * |
\w | matches a word character: [a-zA-Z_0-9] |
\W | matches a non-word character: [^\w] * |
* "^" is the NOT operator and is covered further down on this page. |
Note that the backslash character must be escaped (quoted) when used in a Java String in order for it to be interpreted as a String literal. So, when specifying a predefined character to use, don't forget to escape the backslash with another backslash. For example, to match the word eat surrounded by whitespace, the pattern \seat\s must be specified as "\\seat\\s".
pattern = Pattern.compile( "\\seat\\s" ); // Matches "eat" surrounded by whitespace. input = "When do we eat?" ; matcher = pattern.matcher( input ); System.out.println( matcher.find() ); // Prints false. input = "We eat when we're hungry." ; matcher.reset( input ); System.out.println( matcher.find() ); // Prints true. System.out.println( matcher.group() ); // Prints " eat ". |
"|" is the OR operator. When used outside of a character class, it allows the matching of one or the other pattern. Inside of a character class, "|" is interpreted as a literal character and serves no meta character function.
pattern = Pattern.compile( "apple|orange" ); // Matches "apples" or "oranges". input = "I ate my orange." ; matcher = pattern.matcher( input ); System.out.println( matcher.find() ); // Prints true. System.out.println( matcher.group() ); // Prints orange. input = "I ate my apple." ; matcher.reset( input ); System.out.println( matcher.find() ); // Prints true. System.out.println( matcher.group() ); // Prints apple. input = "I don't have any more fruit." ; matcher.reset( input ); System.out.println( matcher.find() ); // Prints false. |
"^" is the NOT operator when prefixed inside a character class. "[^b]" would match any character other than a "b". Note that it does not match the empty string. Outside a character class, "^" takes on a different meaning and is covered in a later lesson.
pattern = Pattern.compile( "[^b]lop" ); // Matches any four characters, of which the first // cannot be "b" and the last three must be "lop". input = "blop" ; matcher = pattern.matcher( input ); System.out.println( matcher.find() ); // Prints false. input = "flop" ; matcher.reset( input ); System.out.println( matcher.find() ); // Prints true. System.out.println( matcher.group() ); // Prints flop. input = "lop" ; matcher.reset( input ); System.out.println( matcher.find() ); // Prints false. // The empty String does // not match "^b". |
"&&" is the AND operator. It allows the definition of two conditions for a pattern element to match.
pattern = Pattern.compile( "[a-z&&[^aeiou]].{5}" ); // Matches any six characters where the first character // is a lower case letter that is not a vowel. input = "Every lamb counts fish." ; matcher = pattern.matcher( input ); while ( matcher.find() ) { System.out.println( matcher.group() ); // Prints "very l" // "mb cou" // "nts fi" } |
Note that the default behavior of the regular expression elements presented so far is to be greedy (hungry) and match as much of the input as possible (a maximal match).
input = "1001 0101 0011 1100" ; pattern = Pattern.compile( "1.*1" ); // Matches the sequence of characters where the first // and last character is "1" with zero or more characters // in between. matcher = pattern.matcher( input ); System.out.println( matcher.find() ); // Prints true. System.out.println( matcher.group() ); // Prints 1001 0101 0011 11. |
A minimal match, also known as a reluctant match, would match as little of the input sequence as possible in order to satisfy the entire regular expression. In this example, such a match would have matched the input sequence four times, the first matching subsequence being "1001". To specify a minimal match, follow the appropriate repetition quantifier construct with a "?" . "?" modifies the behavior of the repetition quantifier to match reluctantly.
input = "1001 0101 0011 1100" ; pattern = Pattern.compile( "1.*?1" ); // Matches the sequence of characters where the first // and last character is "1" with as few as possible // characters in between to make the pattern match. matcher = pattern.matcher( input ); while ( matcher.find() ) // Prints { // 1001 System.out.println( matcher.group() ); // 101 } // 11 // 11 |
?? | Matches the preceding element up to one time, as few times as possible.* |
+? | Matches the preceding element one or more times, as few times as possible.* |
*? | Matches the preceding element zero or more times, as few times as possible.* |
{min,max}? | Matches the preceding element from min to max inclusive, as few times as possible.* |
{min,}? | Matches the preceding element min or more times, as few times as possible.* |
* Note that "as few times as possible" means "as few times as possible in order to satisfy the entire regular expression being matched." |
Notes and Resources | |
1 | The Regular Expressions Tutorial at JavaRegex.com |
2 | java.lang.CharSequence is a new Interface in Java 1.4.
A CharSequence is a readable sequence of characters. This
interface provides uniform, read-only access to many different kinds of
character sequences. String and StringBuffer
both implement CharSequence . -- CharSequence
API Documentation |
3 | java.util.regex.Pattern
API Documentation |
4 | java.util.regex.Matcher
API Documentation |
5 | java.util.regex
Package API Documentation |
6 | From The
Pattern Class Documentation: Valid Characters in regular expressions x - The character x \\ - The backslash character \0n - The character with octal value 0n (0 <= n <= 7) \0nn - The character with octal value 0nn (0 <= n <= 7) \0mnn - The character with octal value 0mnn (0 <= m <= 3, 0 <= n <= 7) \xhh - The chara cter with hexadecimal value 0xhh \uhhhh - The character with hexadecimal value 0xhhhh \t - The tab character ('\u0009') \n - The newline (line feed) character ('\u000A') \r - The carriage-return character ('\u000D') \f - The form-feed character ('\u000C') \a - The alert (bell) character ('\u0007') \e - The escape character ('\u001B') \cx - The control character corresponding to x |
7 | The Regular Expression Library |
8 | For further reading on regular expressions, take a look at Mastering Regular Expressions by Jeffrey Friedl. A sample chapter from O'Reilly is available on-line. |
9 | The code examples in this article were formatted using the JavaCodeSyntaxHighlighter filter created by John Sun for use with Jive Software's Jive Forums application. |
A special thank you to (in alphabetical order) Cindy Glass, Mapraputa Is, Thomas Paul, Matthew Phillips, Mark Spritzler, Janet Wilson, and Jim Yingst for their valuable feedback and help in improving this lesson from its first draft edition.
There are articles all over the internet comparing C# and Java so why am I writing one? I started programming in
Java in 1996 after several years of developing applications in C++. Since April of 2002, I have been writing programs
in C#. That means over the last 10 years I have developed real life production applications in C++, Java, and C#.
I also don't have any ax to grind. I think I can be fair in an evaluation of C#, something that seems to be missing
in many of the evaluations I have read.
The question of why C# was invented has more to do with the politics between Sun and Microsoft than anything else.
Once Microsoft was excluded from the Java world, the development of C# was virtually assured. Microsoft needed
a new language to go with their .Net environment and C++ and VB were simply too complicated or too limited for
this new environment.
So is C#, Microsoft's brand of Java? To put it simply, yes. C# is a lot like Java and a Java developer will find
the transition between the two languages to be very simple. You will find that many things in the language are
identical, some other things are very similar, while a few others are very different. Rather than do a complete
comparison of the two languages, I would like to discuss those things that Java programmers (in my opinion) will
either wish Java had or will hate.
This was in C++ and I hated it in that language. For those who are unfamiliar with the idea behind operator overloading,
I will give you an example out of Java. The String class has the plus sign overloaded so that you can concatenate
two Strings. This is a convenience so that we can code s1 = s2 + s3 instead of s1 = s2.concat(s3). However, when
operator overloading is unlimited, we end up with odd constructs. In C#, you can overload any operator including
==, !=, < , and >. So instead of using an equals method to compare two objects, you can overload the equals
operator to compare any two objects. This might sound nice, but can easily cause confusion. Is obj1 == obj2 a reference
compare or an object contents compare? There's no way to know unless you look at the API. Of course, we have the
same problem with the equals method in Java since it may or may not be overridden but at least we always know that
== is a reference compare. In C#, if == is overloaded, there is no way to do a reference compare! You might think
that this isn't too bad but what about other operators? What does it mean if I do employee1 = employee2 + employee3?
Although there may be times when it is useful (date1 = date2 - date3) , it tends to create more confusion than
it is worth.
One capability with operator overloading that is very nice is the ability to create castings between classes. C#
allows you to create explicit or implicit casts between classes that would not normally be permitted. For example,
let's say that we have an Employee class that is the parent of ExemptEmployee and NonExemptEmployee. In Java there
is no way to cast a NonExemptEmployee to be an ExemptEmployee. C# allows you to set up a method to do just that.
The method will take in a NonExemptEmployee and return an ExemptEmployee. The method gets executed automatically
when casting is needed (implicit) or when a cast is made (explicit). This can be very useful if you have a method
that takes in ExemptEmployee objects but all you have is a NonExemptEmployee object.
We all know by now that properties should be kept private and then accessed through public get and set methods.
The makers of C# agree with this concept but rather than use Java-like public get and set methods, they designed
a way to make it look like you are accessing public properties even though you are really running get and set methods.
In this way you can code office1.DeptNum = 101 and actually be running a set method. The code looks like this:
public int DeptNum { get { return deptNum; } set { deptNum = value; } } |
Just as in Java, C# uses pass by value. But C# also allow the programmer to pass by reference. Although parameters
passed by reference must be clearly identified, the whole concept of pass by reference seems very anti-OO to me
because you are accepting side effects as being desirable. Methods should return values, not replace values passed
to them. This isn't a terrible thing, but I could have easily lived without it.
C# does not require you to catch exceptions. I don't understand why this is the case because forcing exceptions
to be caught makes for cleaner, more reliable code. In Java, if you fail to catch an exception, you get a nice
compile error that let's you know what exceptions a method can throw. This makes it easy to write reliable code
without having to check the API every time you make a method call. C# does not give any warnings when you fail
to code a catch around a method call. This forces you to check the API to figure out what exceptions might be thrown.
A definite pain in the neck. The end result is that try...catch isn't used nearly as often as it should be in C#.
C# uses the C++ model for polymorphism which means you must take positive action to make a method eligible to take
part in polymorphism. What does this mean exactly? In Java, you can override a method in your parent class and
as long as the parent method isn't final there isn't a problem. You get runtime method binding which is very powerful.
C# prefers to use compile-time binding unless you specifically tell it otherwise. C# adds three keywords to make
this all work; virtual, override, and new. Since programmers tend to not code their classes with the next programmer's
concern in mind, it is very unlikely that the original programmer will write the necessary code to insure that
programmers extending their class will be able to override their methods. Java wins hands down in this area.
The foreach statement is one of the most convenient ways to iterate through a collection or an array. It allows
you to process an entire collection and cast the objects to the correct type in one handy little statement. Here's
an example:
public void AMethod(ArrayList list) { foreach (Employee emp in list) { Console.WriteLine(emp.Name); } } |
This is something that really belongs in Java. It helps create more reliable code by insuring type safety at compile
time. For example, if you have a field that should only contain the days of the week, to insure type safety at
compile time, you would have to create a special class to insure that only the days of the week can end up in the
field. This can only be tested at runtime. Using an Enumerator, you can test what is being moved to the field at
compile time. How do we do this?
First we create an enumerator which contains the days of the week:
enum DayOfTheWeek { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday } |
DayOfTheWeek day; day = DayOfTheWeek.Sunday; |
You have an int and you want to stick it into a collection. Or you have a float and you want to convert it into
a string. In C# this is a breeze. Whenever you use a primitive in a place that requires an object, C# automatically
turns the primitive into an object. This is called "boxing". basically it means that you can treat all
your primitives as if they were objects without paying the overhead of having them always be objects. So you can
do something like this:
int i = 50; arrayList.Add(i); string s = i.ToString( ); |
One of the nice things about C++ is the ability to use function pointers. Delegates give you a very similar functionality.
In many ways it is similar to the event model used in Java but it has the added advantage of not tying you to a
particular method name. One of the problems with Java's event model is that if you use one class to receive event
notifications from different objects (let's say one class is handling the action event for three Buttons) then
all the notifications will go to the same method. The method has to figure out which Button caused the method to
be triggered. The delegate model allows you to have different methods for each Button object if you wish. Instead
of passing just an object to be notified, the delegate model allows you to pass a method to be called when the
event is triggered.
OKButton.Click += new System.EventHandler(buttonHandler.OKButton_Click); CancelButton.Click += new System.EventHandler(buttonHandler.CancelButton_Click); |
Notice that setting up a delegate involves using operator overloading. In this case, when the OKButtum is clicked, the OKButton_Click method of the buttonHandler object will be invoked. When the CancelButton is clicked, the CancelButton_Click method will be invoked. The actual method has to have a certain signature that is determined by the delegate model that is used. For button clicks, the method signature looks like this:
private void OKButton_Click(object sender, System.EventArgs e) { } |
Although the delegate model is used for events, it can be used for any situation where a callback is useful.
There are two nice improvements in the switch. First, you can use a string in your case. Second, there is no way
to accidentally fall through from one case to another. If you want to fall through you have to specifically tell
the compiler.
C# provides direct support for multi-dimensional arrays. It also supports the jagged arrays found in Java. You
can code this kind of construct:
string[,] cityState = new string[25,2]; |
C# has the "is" keyword which is basically the same as instanceof. You can code something like: if (a is Animal).
But C# also has the "as" keyword which is used for casting.
Look at this piece of Java code (assume that Animal is the parent class of Dog):
Dog d; Animal a = new Animal(); d = (Dog)a; // ClassCastException |
Dog d; Animal a = new Animal(); d = a as Dog; |
So which is the better language? They are both great languages and I enjoy working in both of them. Both languages
have all the features that you expect in a modern object oriented language. Knowledge of one of these is easily
transferred to the other. Thebest part is that C# has opened the Microsoft world to Java developers. By removing
the reliance on C++ and Visual Basic, .Net has created an opportunity for Java programmers to take their skills
into a job market that was previously closed to them.
By the way, some of the things I pointed out as things I like about C# are planned to be added to Java at some
point. You can take a look at the "From Mantis
to Tiger" site for a look at some of the proposed enhancements in J2SE 1.5.
The Cattle Drive forum is where the drivers get together to complain, uh rather, discuss their assignments and encourage each other. Thanks to the enthusiastic initiative of Johannes de Jong, you can keep track of your progress on the drive with the Assignment Log. If you're tough enough to get through the nitpicking, you'll start collecting moose heads at the Cattle Drive Hall of Fame.
Gettin' them doggies...
This month finished with 17 drivers busy testin' the waters and pickin' on them
po' nitpickers. The Say assignment alone's been keepin' four of them from watchin'
too much of that color TV while more than half of the drivers are busy with
Servlets and JDBC.
Another moose on the wall
for...
Yep, that's right, you make it through, you get yerself a nice
little moose to hang on the wall. Well, OK, so it's a virtual moose
on a virtual wall, but you can be right proud of 'em! Thanks to the
efforts of Marilyn deQueiroz, you can now proudly admire your
codin' accomplishments at the recently opened Cattle Drive Hall of Fame. Check it out, pardner, it's
worth a wink.
This month Peter Berquist bagged his first moose on the Java Basics trail of the drive. Way to go Peter! Louise Haydu, Manju Jain, and Dirk Schreckmann each hung their third moose head up on the wall after pokin' at them nitpickers on the Servlets trail. All them poor meese... what would the WWF say?
Saddle sore...
So close and yet so far, that's how it feels when you're just about to get through
one of the Cattle Drive sections. Long time driver, Carol Murphy, is
about set to bag her third moose and order up some sarsaparilla at the saloon.
Hang in there, cowpoke, yer almost there!
Back from being out on the range...
Sometimes long lost Cattle Drivers untangle themselves from the sagebrush and
actually make it back to the Drive. Pauline McNamara found some time
between nitpickin' and bicycling through Europe to take another shot at those
Servlets assignments. Good luck pardner!
Nitpicking is hard work too...
We know they're workin' reeeeeally hard, after all, we've seen what those assignments
look like once the nitpickers have combed through 'em. Hats off to Marilyn deQueiroz and Pauline McNamara for their dedication and patience with the pesky
vermin that always manage to make their way into those assignments.
Tips for the Trail...
Java's only ternary operator - sometimes called the query-colon operator - condition
? exp1 : exp2
- just might be the thing to use in order to keep that
code nice and easy to read. Like we've mentioned time and again, readability
is one of the most important goals of the Cattle Drive, and for writing code
in general!
Content and format adapted from Ol' Timer Pauline McNamara's original column by Dirk Schreckmann.
JSTL in Action by Shawn Bayern |
||
A nicely written book about JSTL (JSP Standard Tag Library). Its expected audience consists of HTML and JSP developers who can be unfamiliar with Java, as well as experienced Java programmers.
A reader without programming experience will probably benefit most. The book is beginner-friendly on all levels of organization. Terminology is relaxed without being sloppy: correspondence to both formal lexicon and "field jargon" is given. Every important word and concept is explained, often with vivid (or bizarre, depending on your taste) metaphors. It will be long time before I forget author's definition of "scope" that compared it to flying rats... The words "in action" in the book's title aren't just words, it is a methodological principle. The discussion concentrates on practice rather than theory and specifications; each JSTL tag comes with examples - from "elementary" tasks - how to set encoding or print numbers in assorted formats, to parsing XML and performing SQL queries. There are more complex projects, like writing an online survey, message board and a simple web portal from scratch - toys that look so real and their code so simple that you want to try it out. The last part is targeted at Java programmers and deals with issues like performance improving, configuration, and developing custom tags - JSTL supports even this! And if all this is not enough, then you should know: there are jokes scattered throughout the book, so you do not want to skip pages for not to miss one! (Margarita Isayeva (Map)- Sheriff, August 2002) More info at Amazon.com || More info at Amazon.co.uk |
Starting Date | Book | Author(s) | Publisher | JavaRanch Forum |
Sept 3 | iPlanet Application Server: Designing and Building J2EE Solutions | David Ogren | Wiley | Sun[tm] ONE Application Server |
Sept 10 | Professional JSP Tag Libraries | Simon Brown | Wrox | JSP |
Sept 17 | RefactorIT | Tanel Alumae | Aqris | OO, Patterns, UML and Refactoring |
Sept 24 | TBD |
For more information on JavaRanch's Giveaways see Book Promotion Page.
As always JavaRanch is dedicated to providing you with the best source of information on Java Programming and Engineering.
by Carl Trusiak
Managing Editor: Carl Trusiak
Comments or suggestions for JavaRanch's NewsLetter can be sent to the NewsLetter Staff
For advertising opportunities contact NewsLetter Advertising Staff