Feed Up With JavaCopyright (c)1999, Walt StoneburnerAll Rights Reserved. This content may not be reproduced in whole or part for anything other than personal use. All publication rights remain with the author until futher written notice. The author may be contacted at <wls@wls.wwco.com>. chapter 1 - Feed Up with Java "That’s it! I’ve had enough," was the first clue of frustration. Around the room were scattered opened books that dealt with one topic only: Java. Core Java, Java for Dummies, Java in a Nutshell, Java Quick References, Patterns in Java, 60 Minute Guide to Java, Presenting Java, Java!, …it just didn’t seem to matter. Nothing was helping. The self-reflecting dialog continued, "I’m a smart guy. I picked up BASIC, Pascal, Assembly Language, C, then C++. I understood Awk, Perl, and Python. Why even CORBA makes some conceptual sense. I just can’t seem to get the hang of this bloody language." The clock on the wall indicated that it was well past 2:AM, setting the perfect stage for something strange to happen. And not so necessarily by chance, it did. A voice from behind the discouraged programmer spoke up, startling him. "It would seem you’re in the need of some help, my friend." "Who are you?" inquired the developer, pinching himself to see if this was just a delusion. "I’m Ralph, your fairy godmother, kid. Man, you’ve put on weight since I last saw you." "Great. You look like the kind of fair godmother I’d get." "Look kid, it’s just a title. Don’t go grouping me with those stereotypes. You need help understanding Java, I can help you. You wanna go to the ball wearing glass slippers, you’re on your own." The developer sat up in his chair. "A Java savvy fairy godmother…" he was beginning to like the idea as it started to sink in. "Your problem is that you aren’t thinking in an pure object oriented manner," explained the five foot nine fairy. "Perhaps you weren’t given all the background information, but I do know C++ and have been using it for years" retorted the developer, having just been insulted. The fairy continued. "You see, all your life you dealt with procedural code. Writing instructions, passing data back and forth. When you learned C++ you learned all about object oriented programming, but it was the way you used that knowledge that is getting in your way." "Getting in my way?" "Yes, what you’d do is model things with your objects." "That’s what you’re supposed to do!" "But," continued Ralph, "you still primarily programmed procedurally. You wrote functions, but just used objects to simplify the task. You used third-party libraries, you even had quite a success with STL. But if it wasn’t for wizards, you’d never ever have touched a framework." The developer’s eyes dropped. It was true. Application frameworks were kind of a murky mystery. It wasn’t the fact it was complex code, he was a systems engineer after all. It was just that there was so much to learn, the naming conventions, the methodologies. Without a wizard holding your hand each step, nothing made sense. Even with a wizard, it was hard to understand how a program worked. It just did. Most of his friends could whip out programs, but they didn’t truly understand what was going on. He wanted to. No, he needed to. "Have you ever written a program using nothing but objects?" interrupted Ralph, regaining momentum. "Nothing but objects? That’s stupid, if not completely unnecessary." The fairy brushed his hand in the air like he was trying to erase the words just spoken. "Wizards, macros, and hacks. Kid, you need to understand the guts of the Java language, the reason behind the decisions, how the frameworks actually work and what they expect. This will make all those reference books quite useful."
chapter 2 - Ralph dismisses the books "Reference books?" exclaimed the developer, picking up a Java tutorial book. "This say is will teach me Java in 30 days, this one 60 minutes, and this one in just two!" "Have they?" asked the fairy godmother, scratching the remains of an earlier five o’clock shadow. "Have they what?" "Have they taught you Java?" "Well, no, but I suppose it’s because I just haven’t worked through them all yet." The fairy godmother got up, walked over to the bookshelf and took a copy of The C Programming Language off the shelf and started to flip through it as if it were a sacred writing. "See this? This is raw gospel. Problem, solution, and language feature representation. Ah those were the days. "Now days books just throw a few examples in your face, list the library calls, and claim you’re an expert. Pish. Do they answer the question of how to find what you’re looking for in the library? No. How to use a the methods? No. "What you need, son, is someone who’s been there. Someone who can put things into a perspective you understand, someone who can open your eyes to new ways." Excited beyond belief, the developer asked, "And you’re that person!" "No," paused the fairy godmother, "he’s on vacation, but I suppose I’ll have to do in the meanwhile." "Oh."
chapter 3 - Downloading the JDK "Let’s see what ya got so far," said Ralph stepping up behind the developer as he rotated to face the keyboard. The developer opened a menu, "which development environment do you want? Microsoft, Borland, Symantec, Asymetrix,…" Just then he heard a slap. Looking over his right shoulder he saw his fairy godmother’s face buried in his hands. "You don’t get it, do ya? These crutches are holding you back," explained Ralph. "Microsoft is deliberately polluting the Java language, so while that means ‘more features’ it also means your code may not compile under other compilers and the byte code won’t run on anything but their operating system. Borland is far more compliant, but they keep drifting behind Sun’s JDK releases, furthermore their IDE environment crashes a lot. Symantec is a really great IDE, but we’re interested in the latest Java the moment it’s available. Don’t get me started on Asymetrix,…" The developer sat there dumbfounded. He had paid a lot of money to have the best commercial Java environments money could buy. "Well, what would you recommend to start with?" "To start with, that’s the key phrase… start with the actual JDK from Sun. It’s free on the Internet." The developer posed for typing, but then turned back in his chair to Ralph. "Uh, I got a question for you…" "Shoot." "What’s a JDK?" Ralph pulled up a chair and grabbed a piece of scrap paper. "The JDK is the Java Development Kit. It contains your compiler, utilities, libraries, documentation, and example source code. Well, actually, you have to grab the documentation separately, but it goes with the JDK." "Oh! So it’s like getting the latest libraries, with the language thrown in for free." "Something like that," explained Ralph. He had finished drawing his picture and slid it across the desk. It looked something like this:
The developer looked at the picture. "Is this saying that AWT is built on Swing, or that Swing is built on AWT?" Ralph looked at his own drawing. "Ya know, I never considered that could be a source of confusion. Hmm, I’ll have to remember that. You start at the inner most boxes and work your way out. First there was AWT, then Swing was built around that, together with these other libraries," pointing at three boxes on the right, "that makes the JFC, which is part of the all encompassing JDK." "Explaining it like that makes it much clearer. Thanks." The developer paused, "so I want to get the latest JDK." Ralph made a mmm-hmmm noise in his throat. "And that would be where?" asked the developer? "You want to go to http://java.sun.com/ – you’ll find everything you ever need there." Ralph started munching on some pretzels while the developer pulled up the web page. Ralph continued after an audible swallow. "Scroll down to the bottom somewhere and find the JDK 1.2.1 link." The developer did so, and privately noted to himself that this took him to the URL http://java.sun.com/products/jdk/1.2/. "Look," he pointed out to Ralph, "they’re renaming the bundle from JDK 1.2.1 to ‘Java 2 SDK, Standard Edition, v1.2.1’." "Yeah?" validated Ralph. "There was some debate if they were gonna do that; I guess they have. At least it’s a whole lot more informative than "Java 99" like some companies do." Ralph came from a time when version numbers meant something about the product, well before the days when marketing got involved and screwed it all up. "Just download the Java for your platform, kid." "But," asked the developer, "I thought Java ran everywhere. What’s this about different platforms?" "Java does run everywhere, however keep in mind it’s running on a virtual machine. Each platform has to have a native virtual machine." "Oh," said the developer. Then he curiously added, "what happens if the virtual machines don’t behave the same way?" "Then," said Ralph, "you have the real world." He motioned with a hand to click the link and download the SDK while they were talking. The developer decided to download the one big 20 Megabyte file for windows called jdk1_2_1-win.exe, saving it in his download directory. "That might take a couple of minutes" pointed out Ralph. "You might want to also grab the documentation as well." The developer hit the back button in his browser a few times, found the link, and downloaded the English JDK 1.2 documentation for Windows as one large bundle in a zip file. The file turned out to be named jdk1_2_1-doc.zip, which also was placed in the download directory. "Care for a Coke?" asked the developer getting up from his chair. "Love one," said Ralph putting his feet up on the table waiting for the download to finish. "Heavy on the ice."
chapter 4 - Installing the JDK "Well, I suppose I should install it," said the programmer, returning to his computer and handing Ralph a the mega-sized soda. "If you have an older copy on your system, I’d uninstall it first," pointed out the fairy. However the developer shook his head, indicating that he didn’t. First he executed jdk1_2_1-win.exe and was greeted by a nice install program. The general gist was that Java 2 was going to be install on his hard drive. He went with the defaults, allowing it to make a root level directory called jdk1.2.1."Best to grab everything," said the fairy godmother, "you’ll never know when it will come in handy." So, they took the defaults of Program Files, Native Interface Header Files, Old native Interface Header Files, Demos, Java Sources, and JRE including Java Plug-in. Next the software asked to store the Java Runtime Environment on the hard disk. The developer looked over seeing if there was any visual clue from Ralph to put it in some place else. There wasn’t, so he proceeded to use the default. "Well that was relatively painless!" exclaimed the programmer. Ralph was pointing to the documentation file that hadn’t been unzipped yes. "Oh, yeah…" said the developer, as he extracted the contents to the root of the drive, allowing the zip file to store everything in the jdk1.2.1 directory for him.Ralph added, in order to be able to use the Java compiler and Run Time Environment, you’re gonna want to put your jdk.1.2.1\bin directory in your path.So the developer did. "What’s the difference between the JDK and the JRE?" he asked while typing. Ralph explained that the JDK was the development environment they just downloaded. It comes with a version of Java run time environment. You may distribute the runtime environment for free with your products, but not the SDK. chapter 5 - baby steps "I suppose the first thing you want me to do is write a hello world program," asked the developer. He had seen so many of these examples he was sick of them. Truth was, he couldn’t make it work without following an example step by step, but he was unsure why. Ralph knew this. "Actually, I thought we just sit here, chat, and drink our sodas," replied Ralph. The developer started typing, but was interrupted. "I’m serious," explained Ralph. "How do you plan on writing even the simplest programs if you don’t have a plan to get there?" "A plan for ‘hello world’?" asked the developer. Ralph ignored this statement and asked his own question as well. "How does a program know where to start executing?" The programmer paused, thinking this might be a trick question. "For Java?" "No. For any language." "I suppose it has to have an entry point. In PASCAL, it’s what’s ever is inside the BEGIN END. statements. In C, and C++, the program has a main() function, execution begins there.""Okay… where does a Java program begin?" "Well, I suppose a Java program would have to have a main() or something." The developer wasn’t used to this kind of verbal exploration."I see," said Ralph. "Would there be any instances of any objects existing at this point?" "I doubt it." "Correct. Here’s another issue to ponder… Java doesn’t have global functions like C or C++. That functions must be inside of a class." "Always?" "Always." The developer scratched his head. "That would mean that the main function would have to be declared static.""Yes it would, and now you know why. But take it the next step. Your Java program will have lots of classes in it. How will you find the class with the main() function in it?"This one created a pause in the conversation, to which Ralph took a healthy slug from his glass. The developer didn’t say anything but appeared to be lost in thought. "Yes?" probed Ralph. "I’m sorry, I hadn’t considered this before, but each class could have it’s own main() function. Certainly Java doesn’t execute them all…""How would it know which order to do them in?" pointed out the developer’s fairy godmother, looking smug. He could tell the developer was almost on to the answer. "It would have to be… specified… on the command line," answered the developer. Ralph was about to jump in, but the developer continued. "But I know you don’t specify which class when you run the program as an option." Then the light went on. "Wait! Wait! Yes you do! The program you’re invoking is the name of the class." "Very good!" praised Ralph, "Depending on which compiled class file you pass to the Java Runtime Environment as the program to run, that determines the class who’s main() is executed."The developer liked that, "you mean I can have multiple main() functions, and can make the program act differently based on which one I choose to invoke? That’s so cool."Ralph could tell this was going to be a promising venture after all. "So," said Ralph directing the developer’s attention back to the keyboard, "it sounds like you should make a directory to play in, and inside it put a file that has the name of the class the same as the filename. Give it a main() function. Remember to use .java as the source code’s extension."For the first time, the developer seemed to understand what was going on. He created a file called Test.java and this is what he put inside:class Test { static main() . . . } And then he realized he was stuck again. He turned to Ralph, "uh, what is the signature prototype for main() in Java?"Ralph smiled. "You already know it. You just don’t recognize you do." "Come again?" asked the developer. This was a little to Zen for him. "You know it’s static, you got that. Since there’s no instance available, how are you going to let the outside world, in this case the JRE, access your method?"The developer added the word public, drawing on his C++ knowledge. He turned back to see if the syntax was right; Ralph just nodded.public static main() "Java programs don’t return an exit code" stated Ralph. The developer raised his eyebrow at this, but typed the word void. He didn’t happen to see that Ralph had crossed his fingers behind his back.public static void main() "The other thing to keep in mind is that Java will give you an array of strings, representing the arguments passed to the program. This is like C++’s char * argv[] except that there are no pointers in Java, and you don’t need the count of elements since you can test the size of an array."The developer smiled, "what the string type in Java then?" "String, with a captial ‘S’" answered Ralph. The developer added String argv[], and this is what his screen now looked like:class Test { public static void main(String argv[]) { } } "All your main() functions are going to look like that" explained Ralph. "Now, run it.""But it doesn’t do anything," pointed out the developer. "It proves that you have the fundamentals down pat, now compile and run it." chapter 6 - compile and run "You mean compile, link, and run," corrected the developer. "No, I meant what I said," compile and run it. "The Java compiler produces byte codes as its output, these get stored in a filename with the same name as your .java file, but with the extension .class. The Java interpreter reads the .class file and executes the instructions inside it. No link phase is needed.""What’s the compiler syntax?" asked the developer. "Just invoke javac followed by the fullname of your source file. The ‘c’ after the word Java means the compiler, in case you’re curious."The programmer entered javac Test.java and in a moment a Test.class file was sitting in the same directory."What do I used to invoke the Test program?" asked the developer. Ralph was more than happy to start him down the path. "Simply use java followed by the name of the program, but don’t use the .class extension. Java will add the .class for you and find the main() for the class and run it."The developer poked out the keystroke java Test, and sure enough it executed with no output, returning him to the command prompt without error.The developer then did something Ralph wasn’t expecting. He did a directory on the Test.class file to see how large it was. "Hmm, 253 bytes. Not bad.""Not bad, indeed," said Ralph. "Pull Test.class up in a hex editor, and I’ll show you something."Ralph pointed out that a good hunk of that 253 was byte codes that described the class file, the relative paths to runtime routines like String (which was used in the main function), and the name of the class/source file, along with the base object, and the name of the main routine. In actuality, the byte codes that did the real work were relatively small in proportion. Java actually was efficient. The developer recognized that this meant while there was some overhead, it wasn’t going to cause massive code bloat. A real program would be a much higher percentage of byte codes that did work, and this pleased him. That was the last they ever went into a .class file together.chapter 7 - more than output Ralph set down his Coke, and got a serious look on his face. The developer was distracted because it had just now dawned on him that while Ralph was drinking, the glass wasn’t getting anymore empty. Ralph looked at the glass and picked it up, observing how the light shown through it. "With Java, things get a little blurry about what’s part of the language and what’s part of the library. You know how PASCAL had that writeln() function, and you could pass it a variable list of parameters, but PASCAL itself didn’t allow you to do that? Well, it appears that Java knows about some of its class libraries, and they know about Java." He set the glass back down. "Naturally, it’s not as obvious as PASCAL’s glaring example, but there are certain things that Java need to count on." "There’s a package in Java that is just so important that it is always included. It is the java.lang package, and with it come many important things like classes for the basic data types, I/O routines, thread classes, etc.""Whoa!" called out the developer, making a timeout symbol with his hands. "A package? What’s that, like a header file?" "Not exactly. Why do you need function prototypes?" "To handle forward references." "Right. But the Java allows forward references without declarations. Therefore, a class definition also acts like its declaration. It’s got to be there, but there isn’t a mandatory order things have to appear in. The compiler resolves things after the fact. This shouldn’t be surprising, since many languages allow forward referencing." The developer attempted a big leap. "So what you’re saying is that the compiler generates the code, but it is the Java Runtime Environment that is responsible for all the inter-module loading. If a module has a dependency, the JRE pauses and gets that module." "Which means," added Ralph, "that you tell your source which packages it needs for resolving names, and it treats the file like a header, even though it the file really contains source code. Only the file you explicitly fed to the compiler generates code, the rest do not. So it isn’t really an inclusion like a #include does in C or C++." The developer paused to digest that for a moment. "Ok, then," started the developer, "what’s the relationship between a filename and a package?" "A filename is a physical boundary. A package is a logical boundary. Remember, you said that the classes get loaded into the Java Runtime Environment. The package directive also acts as a namespace, which means different files belonging to the same package can see data among themselves that source files belonging to other packages can not." Ralph could see this was a good time for an illustration and drew this on the back of a used paper napkin:
"So," said the developer catching on, "I assign the same package name to source files containing classes that cooperate or are related, much like writing a library. This compartmentalizes the code, preventing naming conflicts in the source between things in other packages. If I want to include the exposed interface of a foreign package, I just import the package by name, which gives me access to it, but it doesn’t directly include the code." Ralph’s mouth fell open, and the developer grinned. "And what you were telling me is, there is one package called java.lang which is automatically imported by the compiler, thus I have the ability to reference things in that package without writing my own import statement." Ralph nodded silently. After a few seconds passed, Ralph chirped in, "Pull up the online help for java.lang. You see that in that package there is a class called System. That class has a public member called out of type PrintStream. "Looking up PrintStream, we see that it belongs to the java.io package, so if we use the out member, java.io’s routines gets used by our final binary when the JRE loads our classes, as it’s an implicit dependency, but we do not have java.io’s namespace imported in for our use unless we explicitly request it. "Furthermore it has a method called println(), which we are interested in." The developer took the napkin, flipped it over, and drew this:
Ralph looked over the napkin. "Didn't I just say that?" "Yes," said the programmer, "but you didn’t show it. Visual examples help me understand what’s going on." The programmer then modified his source to look like this: class Test { public static void main(String argv[]) { System.out.println( "hello world" ); } } And it compiled and ran just fine. "So, for any method I want, I have to find it’s applicable class. And for any class, I have to know it’s package. And then I have to import that package before I can use it?" asked the programmer. "Right," said his godmother. "Are you sure I can’t make a member of PrintStream?" "Try." Ralph watched for several minutes as the programmer tried adding a PrintStream object of his own to the example. The Java compiler kept reporting Class PrintStream not found. Eventually the developer tried adding a import java.io.*; line to his code, after some help from Ralph. That worked.And so it became clear, that just because some other package has access to stuff, doesn’t mean you get it too. This really was different than the C preprocessor’s include files. It also appeared to prevent unexpected problems, since things couldn’t sneak into your code without you wanting them to. To Be Continued...
|