Java in easy steps

To the right you see the book I have now set mny hopes on. I'm still reading it and I'm still liking it. Until now, this is my kind of book:

This is where I bought the book: www.amazon.de (in the used books section) for a few euro's. Always consult the 'New and used' section on Amazon. Until now all of the items I bought there were still in their shrink wraps. For a fraction of the normal price.


The book

The book is easy to read. The topics (which are littered with examples) begin at really novice levels and take you by the hand to ever higher grades of difficulties. This book is fun to read. The paragrapahs are laid out such, that each topic within a paragraph takes up one and only one set of a left- and righthand page. This means that you can easily oversee the whole topic. Page flipping is only required if you want to see how the previous example looked like. The topics covered are:

  1. JDK, variables, data types, constants, comments
  2. arithmetic, assignments, comparisons, logical, conditions, bits
  3. if-else, switch, for-next, while, do while, break, continue
  4. type casts, arrays, function arguments
  5. classes, mathematics, rounding, random numbers, strings, characters
  6. methods, scopes, multiple classes, object operations
  7. reading/writing from files and console, sorting arrays, handling formats
  8. windows, buttons, labels, text fields, selectors, layout
  9. event handlers, button events, keyboard events, mouse events, sounds
  10. program deployment, program distribution, archives, web starts, applets, web pages


Bang! Game over?

I reached to the end of chapter 7. And then something happened that was very familiar: I got tired of the terse and very unlogical way programs are built. Add to this the mumbo jumbo that was introduced in chapter 8 (Graphical user Interfaces) and I just got sick and tired of it again. This language is not Modula-2. It's (C++)--, like Bruce Eckel called it. I have to stop now and see what will come of it. The step from chapter 7 (full command line) to chapter 8 (GUI building) was just too big and too fast.

So I took the other book: "Thinking in Java" by Bruce Eckel. The book has a chapter of its own in this section so you can find out how things went from here.


Back to the Easy steps book again

After having read 250 pages of Bruce Eckel's magnificent book about Java my mind started to block again. Java is a difficult language to master if you already are familiar with a decent language like Modula-2 or Oberon. So after a day I decided to pick uop where I left off with the Easy Steps book. That turned out to be a good decision. Bruce Eckel explains a lot of the background of Java. And now the obscure parts of the Easy Steps book are lit up a little bit. I decided to restart the book in chapter 6 (Creating classes) and to remake every example to see what it does.

The examples and the results are included below.


Chapter 6 : Creating classes

class Methods
{
   public static void main (String [] args )
     {
	System.out.println ("Message from the main...");
	sub ();
     }
   
   public static void sub ()
     {
	System.out.println ("Message from the sub....");
     }
}
   
This example shows that special functions can be created that can be called from other places in the source file. Nothing new to a programmer of a Higher Language, but it's nice to see that is possible. Here's the result:
jan@Beryllium:~/develop/java$ javac Methods.java
jan@Beryllium:~/develop/java$ java Methods
Message from the main...
Message from the sub....
jan@Beryllium:~/develop/java$
   
It works! Flip the page; we're at 'Understanding program scope' now:
class Scope
{
   final static String txt = "This is a final static string";
   
   public static void main (String [] args )
     {
	String txt = "This is a local variable in MAIN";
	System.out.println (txt);
	sub ();
	System.out.println (Scope.txt);
     }
   public static void sub ()
     {
	// String txt = "This is a local variable in the SUB";
	System.out.println (txt);
     }
}
   
In this source, we have a global and a few local variables. If you read the book you will understand why the line in 'sub' was commented out.
jan@Beryllium:~/develop/java$ javac Scope.java
jan@Beryllium:~/develop/java$ java Scope
This is a local variable in MAIN
This is a final static string
This is a final static string
jan@Beryllium:~/develop/java$
   
Not very special, but you can see that the book uses a lot of easy to follow examples. And you learn from your typo's and from the small experiments you build in. We're engineers, remember? We tinker with everything, all the times. If you are familiar with Modula-2, the scope example will be familiar. Java just needs more words to bring the message.

The next section brings something new to people who have never used Modula-2 or Oberon: multiple classes and how the javac compiler reacts to these. Here are the sources:
class Multi
{
   public static void main ( String args [] )
     {
	String messy = "This is a local variable in the MAIN";
	System.out.println (messy);
	System.out.println (Data.txt);
	Data.greetings ();
	Draw.line ();
     }
}


class Data { public final static String txt = "This is the string from DATA"; public static void greetings () { System.out.println ("Hi there, this is Data.greeting"); } }
class Draw { static void line () { System.out.println ("---------------------------------------"); } }
Yes, these are three different sources. The classes 'Data' and 'Draw' are here to show that you can use any subroutine from any other class, as long as you clearly show which one you mean. Qualified imports are used here. And this is the result:
jan@Beryllium:~/develop/java$ javac Multi.java
jan@Beryllium:~/develop/java$ java Multi
This is a local variable in the MAIN
This is the string from DATA
Hi there, this is Data.greeting
---------------------------------------
jan@Beryllium:~/develop/java$
   
See something odd? If you came from Modula-2 or Oberon, this is just what you would have expected. You ask the 'class' Multi to be compiled, and that's exactly what javac does. But if you came from a lesser language, like C, you ask yourself: what about Data.java and Draw.java? Why were these files compiled at all? There's no MAKE file and still..

At this point you see that Java was (to say the least) 'influenced' by Modula-2 and Oberon. If the compiler notices a dependency of another file, it checks to see if there is an associated .class file. If there isn't one, it looks for the related source file and compiles that first. If the compiler sees that the source file is newer than the .class file, it recompiles.
All very familiar to people used to Modula-2. And now also for the java gang(sters).

Next is extending a class. This is kind of strange. You have a superclass and if you make it bigger, you get a subclass... I would have named it the other way round, but then, I'm just a guy who knows a real programming language... Anyway, here's the source:
class SuperClass
{
   public static void hello ()
     {
	System.out.println ("Hello from the Super Classs...");
     }
   
   public static void echo ( String arg )
     {
	try
	  {
	     System.out.println ("You entered : " + arg);
	  }
	catch (Exception e)
	  {
	     System.out.println ("Argument vergeten, klojo");
	  }
     }
}


class SubClass extends SuperClass { public static void hello () { System.out.println ("Message from the SubClass"); } public static void main (String args []) { hello (); SuperClass.hello (); try { echo (args [0]); } catch (Exception e) { System.out.println ("Wel iets invullen, zoutzak"); } } }
See how this compiles:
jan@Beryllium:~/develop/java$ javac SuperClass.java
jan@Beryllium:~/develop/java$ java SuperClass
Exception in thread "main" java.lang.NoSuchMethodError: main

jan@Beryllium:~/develop/java$ java SubClass
Exception in thread "main" java.lang.NoClassDefFoundError: SubClass
Caused by: java.lang.ClassNotFoundException: SubClass
        at java.net.URLClassLoader$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.net.URLClassLoader.findClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)	
	at java.lang.ClassLoader.loadClassInternal(Unknown Source)
Could not find the main class: SubClass.  Program will exit.
jan@Beryllium:~/develop/java$
   
Hmm. I thought I started to pick up the logic behind it all. Apparently not. The errormessages are plentyful. But hardly descriptive. Less is better. Ask professor Wirth.
The nasty part is: these sources have been prepared on the laptop. All of them ran (in the end). And now, after I have recompiled on another computer, I get these mumbo jumbo error messages. Not very assuring.

Oh wait. Let's pay some closer attention to things. There's something wrong with the type of the main routine of SubClass. After nine lines of mis-information the only errormessage that matters pops up:
Could not find the main class: SubClass.  Program will exit.
It's so easy... I forgot to compile SubClass.java... And the java interpreter is too stupid to just tell me. Java is so smart that it will look all over the internet if there is a SubClass.class file somewhere in some remote place. And if there isn't, it will mention it in the very last errorline.
jan@Beryllium:~/develop/java$ javac SubClass.java
jan@Beryllium:~/develop/java$ java SubClass
Message from the SubClass
Hello from the Super Classs...
Wel iets invullen, zoutzak
jan@Beryllium:~/develop/java$ java SubClass "Hi there argument"
Message from the SubClass
Hello from the Super Classs...
You entered : Hi there argument
jan@Beryllium:~/develop/java$
   
Hey, that's better. The SubClass compiles and when ran it checks for a command line argument. If it cannot find one, it tells the user in a friendly way (alas in dutch, but any educated person has no probems with that). And if you supply an argument it gets printed.

It's time to start creating an object class:
class Car
{
   public static final String colour = "Red";
   public final static String bodyType = "Saloon";
   
   public static String accelerate ()
     {
	String motion = "speeding up";
	return motion;
     }
}

class FirstObject { public static void main (String [] args) { System.out.println ("Paint is " + Car.colour); System.out.println ("Style is " + Car.bodyType); System.out.println (Car.accelerate ()); } }
An obejct called 'Car' and a method to show it:
jan@Beryllium:~/develop/java$ java FirstObject
Paint is Red
Style is Saloon
speeding up
jan@Beryllium:~/develop/java$
   
This is no surprise but it still is nice to see it run. That's the nice part about this book: the steps between topics is so small that you don't notice learning things. Time for some encapsulation:
class Carr
{
   private String maker;
   private String colour;
   private String bodyType;
   
   private String accelerate ()
     {
	String motion = "Speeding up......... ";
	return motion;
     }
   
   public void setCarr (String brand, String paint, String style)
     {
	maker = brand;
	colour = paint;
	bodyType = style;
     }
   
   public void getCarr ()
     {
	System.out.println (maker + " paint is " + colour);
	System.out.println (maker + " style is " + bodyType);
	System.out.println (maker + " is " + accelerate () + "\n");
     }
}

class SafeInstance { public static void main (String args [] ) { Carr Porsche = new Carr (); Carr Bent = new Carr (); Porsche.setCarr ("Porsche", "Gray", "Saloon"); Bent.setCarr ("Bentley", "Silver", "Coupe"); Porsche.getCarr (); Bent.getCarr (); } } jan@Beryllium:~/develop/java$ javac SafeInstance.java jan@Beryllium:~/develop/java$ java SafeInstance Porsche paint is Gray Porsche style is Saloon Porsche is Speeding up......... Bentley paint is Silver Bentley style is Coupe Bentley is Speeding up......... jan@Beryllium:~/develop/java$
Well, that wasn't too complicated. In Oberon we would call such a structure a RECORD, here it's called an 'object'. For me, RECORDS are better to understand and use. But perhaps things will change... One more topic in this chapter: Constructors.
class Carz
{
   private String maker;
   private String colour;
   private String bodyType;
   
   public Carz ()
     {
	maker = "Porsche";
	colour = "Pink";
	bodyType = "Roadster";
     }
   
   
   private String accelerate ()
     {
	String motion = "Speeding up......... ";
	return motion;
     }
   
   public void setCarr (String brand, String paint, String style)
     {
	maker = brand;
	colour = paint;
	bodyType = style;
     }
   
   public void getCarr ()
     {
	System.out.println (maker + " paint is " + colour);
	System.out.println (maker + " style is " + bodyType);
	System.out.println (maker + " is " + accelerate () + "\n");
     }
}

class Constructor
{
   public static void main (String args [] )
     {
	Carz Porsche = new Carz ();
	Porsche.getCarr ();
	
	Carz Ferrari = new Carz ();
	Ferrari.setCarr ("Testarossa", "Red", "Coupe");
	Ferrari.getCarr ();
     }
}
   
There's no line between the two classes in this source. That's because both of them (the class 'Carz' and the class 'Constructor') are in the same one file : Constructor.java. Here's the result:
jan@Beryllium:~/develop/java$ javac Constructor.java
jan@Beryllium:~/develop/java$ java Constructor
Porsche paint is Pink
Porsche style is Roadster
Porsche is Speeding up.........

Testarossa paint is Red
Testarossa style is Coupe
Testarossa is Speeding up.........

jan@Beryllium:~/develop/java$
   
Does it all come as a surprising shock? No. But there's a difference between Oberon and Java here: the empty object is filled with default values. This can be an advantage. It comes in handy in any case.


Chapter 7 : Importing functions

To come in this theatre real soon now ....

Download the uncompiled java source files

Page created on 31 May 2010 and

Page equipped with FroogleBuster technology