Chapter:Our first Java program

From Juneday education
Jump to: navigation, search

Meta information about this chapter

Expand using link to the right to see the full content.

Introduction

Here we expose the students to their first real-world Java program. We show source code, directory layout and the edit-compile-run cycle.

Purpose

Getting the student familiar with a Java program (with packages, objects and method invocation).

Give the students a frame of reference for the coming lectures on syntax and control flow etc.

N.b.! The students are not expected to understand every part of this small program or be able to write it themselves, rather to help them to better understand where the syntax and constructs in coming lectures will fit into a program.

Goal

The students should have been introduced to a Java program with:

  • package declaration
  • import declaration
  • Object creation
  • Method invocation
  • A main method

Instructions to the teacher

Common problems

Getting started on compiling could pose a problem to beginners. Here's a good page on common compilation problems etc. Here's the same thing on Oracle.

Chapter videos

All English videos in this chapter

All Swedish videos in this chapter

See below for individual links to the videos.

Source code

The file Simple.java:

 1 import lib.Greeter;
 2 
 3 public class Simple {
 4 
 5   public static void main(String[]args) {
 6 
 7     Greeter hello = new Greeter();
 8     Greeter hi = new Greeter("Hi, I am simple");
 9 
10     hello.greet();
11     hi.greet();
12   }
13 
14 }

The file lib/Greeter.java:

 1 package lib;
 2 
 3 public class Greeter {
 4 
 5   private String greeting;
 6 
 7   public Greeter() {
 8       this.greeting = "Hello!";
 9   }
10     
11   public Greeter(String greeting) {
12     this.greeting = greeting;
13   }
14     
15   public void greet() {
16     System.out.println(greeting);
17   }
18 
19 }

Line by line explanation

Simple.java:

  1. import - tells java we want to use functionality not found in this file, in this case the class "lib.Greeter" (which is to be found in the lib directory)
  2. a simple blank line to make it easier to read
  3. naming our class. More on classes soon, but for now a class is a building block of a Java program. We're starting a (named) block
  4. a simple blank line to make it easier to read
  5. starting point of our program inside a block (a named block, main)
  6. a simple blank line to make it easier to read
    The program starts to work/function at line 7
  7. Declare a reference "hello", create an object of class Greeter which hello can refer to
  8. Declare a reference "hi", create an object of class Greeter which hi can refer to
  9. a simple blank line to make it easier to read
  10. ask the object, using the reference hello, to greet
  11. ask the object, using the reference hi, to greet
    now the program has worked its way through the main block and will terminate
  12. ending the block
  13. a simple blank line to make it easier to read
  14. ending the class

Video for the Simple program (eng) (swe)

lib/Greeter.java:

  1. This statement shows that this class is inside the lib directory, in Java, classes in a directory are said to be part of a package
  2. Blank line
  3. Declares a class with the name Greeter
  4. Blank line
  5. Declares a variable for objects of this type - the variable is called greeting, is of type reference to String, and is an internal affair of objects of the Greeter class - therefor "private"
  6. Blank line
  7. Code to be run when someone creates a new Greeter object - this type of code is called a constructor
  8. Here, the greeting variable is initialized to the String "Hello!"
  9. End of the constructor block
  10. Blank line
  11. An alternative way for creating new Greeter objects - here with the possibility to send along information in the form of a String
  12. Here, the greeting variable is initialized to the String that was sent along as information
  13. End of the alternative constructor block
  14. Blank line
  15. This is code for when someone wants to ask a greeter object to "greet" - this is called "sending the message greet to the object" or "an instance method" - instance as in an object which is an instance of the class Greeter
  16. Here, the greet method has an instruction (a statement) to print the greeting variable for this object to the standard out
  17. End of the greet method
  18. Empty line
  19. End of the class Greeting

Compile and run the whole program

If you want to try yourself, you'll get a chance in the exercise chapter (the next chapter). Here are the instructions, but they will be repeated in the exercise instruction of the next chapter.

Start by creating a directory for this chapter (you may call it what you want but "our-first-java-program" could be a decent name).

Enter that directory and create a directory called "lib" (for the lib package where the Greeter.java should be).

Download Simple.java to the "our-first-java-program" directory (or whatever you called the directory).

Download Greeter.java to the "lib" directory. You should now have the following structure:

.
|-- lib
|   `--Greeter.java
`--Simple.java

Still in the directory where you have downloaded Simple.java (and also put the lib directory!), do the following to compile and run:

$ javac Simple.java
$ java Simple

Videos for compiling and running (eng) (swe)

Questions and Answers

Expand using link to the right to see the full content.

Q: “I’ve seen a simple program in Java called HelloWorld.java. It also outputs ‘Hello’ or something similar to the terminal/console. But that was only one simple file with everything happening inside the main method. How is this program different?”
A: In a way, they are very similar. You could say that everything ‘is happening’ inside the main also in this example. For sure, everything starts in the main and ends in the main (as in every Java program). But what is it that happens inside the main in the typical HelloWorld compared to the version of the program called Simple that was in the lecture video?

In the typical HelloWorld program, the call to System.out.println() happens inside the main method itself. We wanted to avoid that, and rather focus on the delegation of responsibility for outputting this greeting to objects instead. So in our version, called Simple, we too have a main method (which is the starting point for every Java program - they all have a main method where the action starts!). But in our version, the main in the Simple class doesn’t call System.out.println directly. Instead it creates two objects of the type Greeter and uses the variables referring to those objects to ask for a greeting, using a call to greet() for each one of the objects. As you saw, asking the first object to greet() had a different result from asking the second object to greet().

This is a little more typical of a classic Java program - action starts in main and there some object (or objects) are created and some method is invoked on the object(s). The objects then take over control and decide what will happen from now on in the program.

An object is an entity that we can ask to perform some work, using a technique called “invoking a method on the object”. Sometimes we say that we send a method to the object. Typically, an object has a “state” which it uses to perform the work we ask it. A state is the current values for any variables an object has to “remember” (or store) data. Our Greeter objects had different state, and that’s why they did different stuff when asked to greet(). The first one that we referred to using the variable name “hello”, had a state in that it stored the String “Hello” in its variable greeting. In main, we used the variable “hello” to ask the object to greet() and “Hello” was printed to the screen. If you inspect the Greeter class, where all objects of type Greeter are described, you can find the String variable named “greeting” and see that it gets the value “Hello” in the code for one of the so called constuctors (the one with simply empty parentheses after the class name on lines 7-9).

When we created the object in main, and assigned the variable hello to refer to it, we said new Greeter();. When the program was executed, it seems like Java understood which constructor to call and do the initialization of the object.

The other object was created in main like this: “new Greeter("Hi, I am simple");”. This time, a String saying “Hi, I am simple” was used in the call to create the object. This time, it seems, Java chose a different so called constructor (the one in Greeter.java on lines 11-13). The code there seems to accept some string, and then assign that to the greeting variable - allowing clients (users) of this class to create objects while passing along some value to affect the initial state of the object.

Now, it doesn’t merely seem like Java can understand what “constructor” to call. It really does! It matches the call to “new” with the stuff inside the parentheses so that “new Greeter();” is matched with the constructor that also has empty parentheses, while “new Greeter("Hi, I am simple");” matches the constructor with a String variable inside the constructor parentheses.

This gives the clients of this class (programmers writing code in some class that creates and uses objects of class Greeter) flexibility to create Greeter objects in different ways.

Q: “You say client code, or clients. Can you describe this a little more?”
A: Certainly! You see, as you will learn throughout the course, there are two different types of programming activities when using the Java programming language. One is writing code to actually start the program and solve some task with the use of objects of different classes (different types of objects - objects are described in classes). The other activity is to write classes that merely describes objects to be created later. Often it is not even the same person who writes the classes describing objects - it can be a colleague (or your teacher, or if it is a class in the standard API someone at Oracle). The person using some class to create and use objects of that class is said to be a client of a class.

If we take the Simple program, it has two parts: The program itself with the main method in the class Simple - where some Greeter objects are created and used. The code in the main method can be said to be client code using the Greeter class. The other part is the Greeter class. If you only look at the Simple class and the main method, it is perfectly possible to guess what is going on without even looking at the code inside the Greeter class. All we have to know, is how can we create objects from the Greeter class and what messages can we send to the objects.

If someone told you: You can create a Greeter using one of two so called constructors. One without “arguments” (meaning with empty parentheses) which will create a standard Greeter object which will say “Hello” when asked to greet(). The other way is to use the second constructor, which takes a String with a custom greeting as an argument (it should have a String inside the parentheses). Greeter objects created using the latter constructor will remember the string given as argument and use that when asked to greet(). Additionally, the same someone tells you the next piece of information you need to use a Greeter: In order to ask any Greeter to greet, you send the message “greet()” to the object (also known as invoking the greet() method on the object).

This first small and simple program thus shows us that typical Java programming is about creating objects that will hold data as “state” and to whom we can send messages asking them to do something. We also learn that if we have a description of how to create objects of some class (of some type described in some Java class) and what messages can be sent to them (and in what form, by what name etc), we can get started without having to look at the code for the class describing the objects we need!

If you don’t understand everything about this yet, that is only to be expected! Do not worry about that. We have just gotten started and this chapter was about showing you what Java code looks like and how to compile and run it. We do not expect you to be able to create your own programs and classes yet, since that will be something we will do a lot throughout the course in later chapters. And we haven’t learnt all the techniques yet for doing something more intelligent than outputting a greeting to the terminal/console!

Q: “When I compiled the Simple.java file, it seems like the file lib/Greeter.java was also compiled automatically. Why was that?”
A: We understand that that might have come as a surprise. But it was convenient, wasn’t it? The reason for lib/Greeter.java to be compiled too, was that javac, the compiler, first took a look at what was going on in the Simple.java file. It saw that inside the main method, the class Greeter was being used four times. But javac didn’t know anything about any Greeter class (there was for sure no such class in the standard API, for instance!) so it understood that it must inspect and compile the source code for that class too, in order to see if the program makes sense, and in order to create code for the JVM that would use the Greeter class. Luckily, javac found the import statement at the top of the file saying “import lib.Greeter;” - which javac immediately understood to mean - “Hey, there is a class called Greeter in the lib directory. Check that out!”. So javac, the compiler, went to the lib directory but found no compiled Greeter class. However it found the Greeter.java file so it could compile it.

Q: “You keep saying that programming in Java is about creating objects in the main method and using the objects to take over and do the work. I don’t understand that fully yet. Can you give another example of that?”
A: It is only natural that you don’t fully understand something new that you just were introduced to, so don’t worry. I’ll give you another example of a main that creates and object and passes control of the execution to the hands of that object.

Suppose you want a fancier greeting application which doesn’t simply outputs some greeting as plain text in the terminal/console. You want windows and buttons and stuff!

In order to write that program, you would typically have a very short main method which creates an object that does the hard work. The object typically would have a method to display the user interface, let’s call it “launch()”.

The code inside main then could look something like this:

 FancyGreeter fancy = new FancyGreeter("I am fancy");
 fancy.launch();

And that could very well be it! Clearly, the program doesn’t end just yet, but rather launches some kind of graphical user interface (GUI) with a window and buttons and stuff. From this we can conclude that an object, such as the one fancy refers to, can have a lot of objects as part of its state! The object fancy refers to, of the class FancyGreeter, might for instance have a window, some buttons and some label for displaying a greeting. Perhaps the button says “Click me” and when the user clicks the button, a greeting text magically appears on the screen.

The point of this second example, is to show that main typically is really short, and that objects live their own lives inside the application. The FancyGreeter referred to by the variable fancy lives until the user gets bored with this application and closes the window. At this point, control is return to the main method and if the main method has no more instructions, then the whole application terminates.

Let’s return to our first example again. In the much simpler first example in the Simple program, the control of execution goes between main and the objects in turns. First there is code in the main method which asks the object referred to by the hello variable to greet(). Here, execution leaves main and is passed to the object. The object performs its greet() method and after that, execution goes back to main again. Next in main, the object referred to by the variable “hi” is asked to greet(). Once more, execution is passed from main to an object (a different object this time). The object referred to by “hi” performs its greet() method and after that, execution is passed back to main. Again, don’t worry if all this sounds confusing at this point. We will make sure that all this is explained in more detail and repeated throughout the course.

Links

Where to go next

Next page has the exercises for this chapter: Our first Java program - Exercises

« PreviousBook TOCNext »