Questions and answers for the Programming in Java book

From Juneday education
Jump to: navigation, search

Deprecated - Q&A has been moved to respective chapters instead

This page is not maintained and kept only for archival reasons. The sections have been merged with the respective chapters instead.

The chapters have an expandable section (often at the end) named "Questions and answers", with the Q&A related to the chapter in question.

Chapters of the Programming in Java book

Computer introduction

Q: “The RAM memory is fast and suitable for storing instructions for the CPU which can read and execute those instructions in a quick fashion. Those instructions are often called a “computer program” or a piece of “software”. But where are the whole program stored?
A: The program, with all its instructions, are often stored on a persistent memory (you may think of it as a ‘long time storage’) e.g. on a hard drive. The reason is that most programs in a computer system typically is not running all the time. The user launches a program when the user needs the program to perform some task. The operating system loads the program from the hard drive into the RAM when the program is started. Usually, the program is run many times at different occasions, which is why programs are normally stored on this ‘long time storage’. The faster, but short term, memory called RAM is more of a temporary player in the system. It doesn’t remember anything when the computer is powered down. Programs and other files on the hard drive, remain even when the power is turned off. They will remain until someone uses some program to actively delete them from the hard drive.

Q: “You were talking of ‘named memory’, or ‘variables’ as you also called it. I understand that a name I come up with myself is much easier for me to remember and understand than some hardware address in a numeric format. But when and how do I create a variable?”
A: Great question! The variables (which is the more technical name for this named memory) are typically part of the source code for a computer program. You will learn how to write programs (using the Java programming language) throughout this course. But there are actually variables in other places than in the source code of programs! Most operating systems use variables (often called environment variables) to keep track of information that might vary from user to user or vary over time. For instance, many systems have an environment variable to keep track of the user’s preferred language for interaction. Other common environment variables include HOME (the path to the user’s home directory), EDITOR (the path to the user’s preferred text editor software), TZ (the standardized name of the user’s time zone), and, PATH (a list of directory paths where the system should expect to find the program executables the user invokes using a command line interface).

In this course, however, we will touch upon environments when we need them, but we will focus on variables used in the programs we learn how to write. Typically, a program deals with data (information) and such data is typically stored in variables. We give variables good name so that we, when we read the code later on, will understand what data is stored in them. Variable names are for humans, memory addresses (where the data is actually stored) are for computers!

Q: ”You talked about two main types of files: text files and binary files. Is it true that the computer can store text directly on the hard drive in the form of a text file? How is such text actually stored on the harddrive?”
A: Again, a very good question! This is actually a common source of confusion. When we say “text file” and that it “stores text”, we actually simplify things a lot. It might be easy to understand that an audio file doesn’t store sounds (like notes and keys) directly on the hard drive. The audio file must be coded into some format that some program later can decode and interpret as music. We need a program to make sense of an audio file (and to enjoy for instance the music in the file). How is this different from text files, you may ask? Actually, text files are also coded before being saved on the hard drive as a text file. But the coding is very simple - it just codes every character or symbol into a number according to some table (usually the ASCII code table). The only thing the numbers represent are what symbols (like letters, digits and special characters) from a standard table (like the ASCII table) the file contains and in what order they occur. There is no information about the fonts or style of the text - so no notion about bold or italic text exists, and no notion about text size. It is only what symbols occur in the file and in what order they occur that is saved in a text file. This is why such text is often referred to as “plain text”. The translation from symbols to numbers from a symbol table (like the ASCII table) is a very simple coding and decoding scheme compared to coding audio or video for instance. In fact it is so simple that there are a great number of programs that can display or save plain text available. These, so called text editors, are so simple and common that we tend to think of the content of the file (the number codes for all symbols) as “human readable” even though it is actually not the numeric symbol code numbers we are reading, it is their character representation. So we could alternatively think of text files as a special case of binary files. Most terminal programs (the text based interface to the operating system where we can enter commands using the keyboard) have built in support (or come with commands) for displaying the contents of a text file in the terminal window itself. This adds to the notion of textfiles being human readable, compared to for instance audio files, which cannot be displayed as any human readable content neither in a terminal, nor in any other program!

Q: “If text files after all are not that different from binary files in general, what’s the fuzz about them, then?”
A: Text files are important in the context of learning and practicing programming, because programs are entered as plain text (without any styling, sizes or fonts) using text editors. Understanding that a program is just a text file, is also important for understanding the process of compiling programs. Compiling a program means using another program (called compiler) to read the text file with the program you have written, understanding what was written so that it can be checked for correctness of syntax and other rules, and lastly transformed into a binary file which can be run (executed) on the computer. All this also helps us understand that in order to write a program, we need to use some kind of text editor capable of handling plain text!

Q: “OK, so all program source code files are written as plain text. But is it always necessary to compile programs into a binary format, before we can execute the programs?”
A: Great that you ask that! No, there are actually programming languages where the program is run “as-is” in the plain text format, using some other program to interpret the program code typically line-by-line. Such programming languages are said to be “interpreted”.

Q: “I think you said in the lecture video that Java programs are compiled before they can run. So Java programs are not interpreted, then?”
A: That’s a tricky question, but we’ll try to answer it the best we can! It is true that you need to compile a Java program before you can run it. The thing is, however, that it is not the operating system that is running the resulting binary program directly. It is a program called “Java Virtual Machine” that is responsible for executing the binary file from the compilation. The virtual machine is actually interpreting the binary files, but that is not something that is important to know in order to learn to program in Java in this introductory course! But since you asked, we felt obliged to answer!

Q: “It seems, from looking at the lectures, that most operating systems use something called ‘file system’ for organizing the files on a hard drive. Can’t files simply be stored on the hard drive in sequence or some other order?”
A: Of course, the files could be organized in this way or any other way actually. But, if files were stored simply in sequence, couldn’t that actually also be called a system? We could call that too a ‘file system’. The thing about file systems is that they allow us to make abstractions over how files are arranged on the hard drive! We don’t need to care where on the physical thing the data is stored. We don’t need to care about how to make use of the free space that opens up on the physical thing when we delete a large file somewhere. What file systems allow us to do, is to focus on a logical organization of files instead, where we can have names of files and locations where they are stored using the abstraction of directories. Directories are arranged in a file system in a hierarchical manner so that we can get relatively short paths describing the location of a particular files. The directories are often given descriptive names so that the hierarchical path makes more sense to us humans. For instance, we could have the following paths (using / as the directory separator):

/home/adam/music/classical/Bach/BrandenburgConcertos.ogg
/home/adam/music/rock/IronMaiden/RunToTheHills.ogg
/home/ana/programming/java/MyFirstProgram.java

The paths contain the order of directories from the root directory and the directories have descriptive names, helping us to understand and remember where files are located and what type of files to expect next to some file in the same directory.

Q: “Why do we need operating systems? What do they do for us?”
A: Operating systems are also about abstractions. Humans like abstractions because they help us think about and relate to the world in a way that is much less complicated than it really is. Even if a computer isn’t really a complicated machine, it is a very technical one. We like to be able to use a computer (and even write new programs for it to change or add to its capabilities) without having to be electrical engineers. For instance, we like to think about files as the representation of something (like an image) and that we can simply “save” the image, and later find and look at it. We don’t like to think about all the wiring and electrical signalling that takes place in such a simple operation as opening or saving an image. The same applies when we are programming. We might write a program capable of displaying and saving images. As programmers, we are like most of the rest of the humans, we don’t like to focus on technical details. As programmers too, we prefer to use abstractions that allows us to write code that “saves” an “image” in some “folder”. Someone else has (thankfully) written sets of really technical and complicated stuff which offer us these high-level abstractions for operations such as saving files. The sets of such complicated software are called Operating Systems. Without an operating system, using a computer would be a very complicated and technical business. Having said this, parts of the operating systems may be quite complicated and technical too. As programmers to be, we would be greatly rewarded if we took the time to also learn a lot about the operating we are using, so that we better can tune and use it to our benefit and convenience!

Programming introduction

Q: “There seems to be many different programming languages. Do we need so many?”
A: Luckily, we only need to learn one language in order to learn how to program. But there are many languages being used for programming and, of course, all programming languages differ more or less from each other. After learning on language, it is wise to at least gain some basic knowledge of a few other common languages. Reasons for learning any particular language may range from career decisions (some languages are more common on the job market than others) to reasons based on curiosity. If the languages differ, there must be reasons for this! What makes any one particular language different from the rest? Beware that if you ask any proponent (or sales representative, or member of the fan club etc) for one programming language, they will tell you that the language in question solves all problems with the rest of the programming languages in existence. However, there are some main differences between at least families of programming languages, which stem from the fact that different families of language take different approaches to describe the task for the program to be written together with different approaches for how the task should be solved and executed. For this reason, there is much to be gained from learning a few languages (at least on a basic level) from different families of languages, because that might help you gain insights about how to think about the practice of programming - modelling the components that are part of the task for a program and also how to solve problems or perform the tasks using the modelled components.

Other reasons for needing different programming languages could be the domain for the programs to be written. There are languages that are more suitable for writing software that is very close to the hardware the program is running on (like programs that are part of an operating system, or programs that are running on some small piece of hardware perhaps even without an operating system). There are other languages that are specialized on solving problems of a mathematical nature, languages specialized for statistical analysis and visualization, languages more targeted at the world wide web etc.

Programming has been around for quite some time now, so this could also help explain why there are so many languages for this activity. Languages of course evolve over time and it is not uncommon for the industry to take part in the creation of new languages. Often there are competing languages from different vendors, where the languages do not differ all that much, but that’s not what the vendors’ marketing departments will tell you!

Q: “Is a program really nothing but a sequence of instructions?”
A: At least to the computer, it is! As you have learnt from the previous answer, there are many different families of programming languages which all take a different approach to how to organize the instructions and how to express what the program should do. But in the end, the computer is the one responsible to do the actual work that the program describes, and the computer will do this in a way that very well might be described as executing a sequence of instructions. Java is a so called Object Oriented programming language. As we will learn throughout the course, the ‘Java way’ of describing what the program deals with and what to to with that, is focused around the notion of objects representing the stuff our program deals with, and what those objects can do (to help us get our program to do what we want). For this reason, programs written in Java don’t lend themselves as easily as programs written other languages, to the idea of “programs as sequences of instructions”. As you will discover, however, when we write the code describing what our objects can do, we express that behaviour in the form of “sequences of instructions”.

Q: “What are the steps to create and execute a Java program?”
A: You will learn this throughout the course, but it is really simple and only three steps:

  1. Create the program using a text editor by typing in valid Java code and save the file (according to some file naming conventions).
  2. Compile the file using the javac compiler (javac is the name of the Java Compiler) giving your source code file as the argument to javac.
  3. Run the Java program using the java command (java invokes the Java Virtual Machine and takes the class name of your program as an argument).

Q: “There are naming conventions for the Java source code files? And what did you mean by ‘class name’?”
A: All this will become clear in coming chapters of this course! In short, every Java program has at least one ‘class’ which is a kind of unit for your programs. A class you define has a name (that you choose). The file must be saved using the name of the class followed by the suffix ‘.java’. When you run the program, the java command expects as an argument the name of the class and nothing else. But don’t worry if this sounds complicated! It will be clear in a chapter coming soon!

Setting up your environment

Q: “You have chosen to use a terminal and this bash shell thing, throughout the course. What’s the reasoning behind that? Aren’t there any fancier tools for programming in Java?”
A: We don’t know about fancy, but we have some reasons behind choosing command line (a terminal window where you enter commands interpreted by a shell like ‘bash’) together with a texteditor as the programming environment and tools. First, learning a shell like bash is a very useful skill when working with programming and with computers in general. Being confident about using the shell and terminal let’s you learn about the file system, files, the standard streams for output and input, paths, and some environment variables like the PATH variable. The environment for the command line we have chosen (bash or bash via Cygwin) is the standard command line interface for UNIX, GNU/Linux and Mac OS. Being familiar with the bash shell (command interpreter) will prepare you for working with servers and other systems that are running quite a few different operating environments. Also, since we expect all students to run and use bash inside a terminal, all the examples will look the same and we don’t have to provide examples for three (or more) different types of systems.

Using a text editor stresses the fact that a Java source code file is nothing magical but rather a simple text file. Having limited support from “fancy” helper features like “code completion” and other stuff typically found in the fancier tools, forces the students to carefully think about what they are typing in. If a student gets stuck and can’t remember some names etc from the Java class library (Java comes with a huge library of pre-written code that you can use!), the student must look this up, which fosters skills also for getting information and researching the Java class library. Hopefully, the student will better remember what to type after having to look it up, which may not be the case if the fancy tools writes the code for her at the click on a magic button etc.

Also, knowing how to use a decent text editor is a very useful skill! A text editor can be used to write code in any programming language, and, of course, to write and edit text files of any general purpose (such as changing configuration files etc). Using a fancy programming tool gives the students experience of a piece of software with limited applicability outside the realm of writing programs. And it is not unusual that a programming tool only supports one or a few programming languages or suites.

Since this is an introductory course, we wanted to focus on not only the theory and syntax behind the Java programming language, but also on the practice of writing programs. The practice is to author code, save (and organize) the code in files and directories, compile the code and lastly run it. Using a tool that at the same time is used to edit and write code, compile the code and often even running the code, does not make this practice very clear. Using our philosophy of using only the basic tools (terminal, editor, compiler, Java Virtual Machine) prepares the students for using any other tool at a later stage in their career or continued studies. If you only know how to program using one particular all-in-one programming tool, you are quite dependent on that tool being installed everywhere you want to create programs (and even run programs!). We try to avoid such a situation.

Lastly, we have seen that some aspects of the Java programming languages that has to do with so called packages (Java compilation units/classes that are grouped together inside a directory) and paths are not very intuitive when using a fancy tool for the programming activity. In fact, many fancy tools for creating Java programs efficiently hide what’s going on from the user. While this may be OK for an experienced programmer, it stands in the way of the novice programmer who is struggling to understand what packages are, how to declare them and where to put the files, how to compile programs using packages, and how to write code that imports names from a package written by the programmer herself.

Q: “But there are fancy tools then?”
A: Yes! There are quite a few fancy tool that you are free to explore on your own. We will probably not be able to help you solve any problems related to the use of any one particular tool, however, which is why we try to steer all the students into using very similar tools for the practice of programming in this course. Fancy tools (also known as IDE - integrated development environments) include Eclipse and NetBeans.

Q: “So the practice of programming is basically these activities: Edit/save, compile, run?”
A: Yes! However, typically you first analyse what your program should do, what restraints are there and what requirement exist. Then you model the things your programming is managing and lastly you write code to implement how the program will use the things in order to perform the task which the program is there to do. When the actual coding has started, there is typically a cycle of “edit-change, compile, run” which is repeated until you have a functional program. On top of this, it is very common that the programmer also documents the code that is written (so other programmers later can understand how the program and code works) and sometimes even writes a more high-level documentation of the system and even a manual.

The analyses and design are material for a later course and will not be the focus of this course. Writing documentation will be touched upon and that too is something for later courses.

Programming in Java

Q: “You say that even the smallest Java program has at least one ‘class’ declared. Is it common to have more than one class?”
A: Oh, yes! It is in fact more common than having only one! In these first introductory courses, we usually start with the simplest form and structure however. But since it is so uncommon in the real world to write everything in one single file with one single class, we will very quickly move to the situation where you use many classes. Note that since Java comes with a huge library of predefined classes for you to use (the so called standard Java API), it is not uncommon that even if you were to write a stand-alone program in just one file with just one class defined by you, you would anyway use one or many classes from the API! In fact, you hae already used (or seen in the examples) how to use classes from the API.

Q: “Wait, what? There were classes from the standard Java library in your examples?”
A: Indeed! For instance, you remember the so called main method? It had the name String inside the parentheses. String is a predefined class from the Java API. It is a class representing strings of text. If you look closely to the greet() method of the Greeter class, it also uses a class called System. That’s also from the standard Java API. System is a class for accessing and using the computer system where Java is running, so that’s where we have stuff for writing out text to the terminal (standard output stream, which is usually connected to a terminal) for instance. Soon we will look at more predefined classes from the API (in the chapter on using objects for instance).

Q: “But in your example, you said that the Small class was using the name Greeter which was a class in a package/directory called ‘lib’. In order to use stuff like the Greeter class from that package/directory we had to write “import lib.Greeter”. How come we don’t need to import the path to the Java standard API classes like String and System?
A: Well spotted! There is no fooling you it seems! In fact, all classes in the Java API are grouped together in various packages and in order to use the classes in some package, the path to that package needs to be imported to your program. However, the creators of Java have cheated a little when it comes to one particular package called java.lang (where commonly used classes like String and System exist). That is the one package that is always available to your programs with or without an import statement! You may, of course explicitly import “java.lang.String” for instance, but nobody does that. But try for yourself and see that the code still works the same with such a statement. Now try and remove the “import lib.Greeter;” statement from the Small class and re-compile. Greeter is definitely not part of the java.lang package of the standard Java API (probably many people wish it were! No just kidding!). It is a local class that we wrote and put in the lib directory/package. So the compiler will complain about the Greeter name, and probably complain that it can’t find a class named Greeter anywhere. Put back the import statement again and re-compile and see that it works again. This way, you will understand that classes in packages other than java.lang can only be used if the path to the correct directory/package is imported. You may think of the import statement as an instruction to the compiler where to find classes and other names that occur in your code but is not part of the java.lang package. There is actually an alternative, however, to using import. We will see later in the course that you may also use classes by their full names including the package name. So if we wanted to avoid importing lib.Greeter, for instance, we could change every occurrence of Greeter in the code to lib.Greeter (packagename.classname is the pattern here). But that is quite long to write (there are packages with very long names) so the import statement is very handy.

Don’t worry if this sounds confusing at this point. We will use packages and imports a lot throughout the course!

Q: “The Small class did not have a package declaration at the top of the file. So it’s OK to have classes that are not in a package?”
A: It is not forbidden, but it would be wrong to say that a class could not not be in a package. That would actually be the same as saying that the file is not in a directory! Remember, package is the Java way of talking about paths and directories. So, the Small class does actually also belong to a package, but a package without a name. The reason we can compile and run this class in the Small.java file is that we instructed you to navigate to the same directory as the Small.java file. So when we run the Small class, Java will actually know that this is a class in the nameless package. Classes in the nameless package must always exist in the same directory as where you ran the java command (unless you have used a special construct called class path, but that’s a topic for later chapters!).

Our first Java program

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.

Variables and types

Q: “OK, so we use variables so that we can use a name instead of some technical hardware address. Are there any rules or recommendations for what kind of names we should use?”
A: We are glad that you asked! In Java, there are some rules and some recommendations. Let’s start at what names are legal to use (the compiler will tell you when you try to violate these rules, but it is good to know the rules anyway). The name you choose for a variable must start with a letter (underscore and $ are legal but nobody uses them as the start of a variable, and you shouldn’t either!). The rest of the variable name should be a combination of letters (numbers are valid too but not as the first letter of the variable name) and you may use underscore.

The recommendation is to start with a lower case letter and if the name consists of several words such as in “number of students” you should start each word with a capital letter to make the name more readable: numberOfStudents. Names should be short, but meaningful. Prefer numberOfStudents to nSt or ns etc. Think that your colleagues should immediately understand the meaning of a variable (and you too should understand it when you read the code after a year or two!).

There is a special form of variables for values that do not change over time, called constants. Constants usually have names with only upper case letters and words separated by underscore such as in UPPER_CASE_LETTER, MAX_VALUE or HTTP_NOT_FOUND.

Q: “Are there some words that are forbidden to use as variable names, even though they obey the lexical rules?”
A: Sure there are! There are words that are reserved as part of the language itself (or future part). There is a whole list of such reserved words here: [1] We have actually seen some of them already but not talked about them in detail. The reserved words you already have seen include: class, import, package, private, public and void. The names of the primitive types are also reserved.

Q: “In Java, where are variables declared?”
A: It’s a little early in the course to give a full answer to that without listing places that we haven’t talked about yet. But so far, we have at least seen a few places where variable names (they are also sometimes called identifiers in some sources - identifiers are names we come up with of variables, classes, methods, arguments etc but we are focusing on variables in this chapter!) are declared. The first variable name we saw was actually the parameter to the main method. The main method had parentheses, remember? And in the parentheses it said String[] args where args is a variable name. That it is called exactly args is just a convention by the way. The next place we saw a variable name being declared was in the main method. We had some Greeter reference variables named hello and hi. So, apart from being parameters, variable names can be declared inside methods. Such variables are called “local variables”. And lastly, we have already seen one more place where a variable was declared. Do you remember where?

Q: “I don’t remember the third place where a variable was declared. Where was that?”
A: The third place we have seen so far, was in the Greeter class declararation! We said that Greeter objects had state - a way to remember and hold data at some point of their lifetime. The Greeter objects had an internal thing called greeting which was a variable holding information on what String to use when asked to greet(). The greeting variable was declared inside the class definittion of the Greeting class in Greeting.java but not inside any method. Variables that every object of a class has their own copy of (to hold a part of their state) are called instance variables (because an object is also called “an instance of a class”).

Q: “What was the list of primitive types?”
A: The primitive types are the following eight types: boolean, byte, short, char, int, long, float, and, double.

Q: “And then there were reference types. Is there a list of them too?”
A: No, there is no list. Reference types are types storing a kind of address to objects of some type. Object types are described in classes (and constructs similar to classes such as Enum and interface and arrays). Primitive types were pretty straightforward - they had a predefined set of legal values, which is why the Java designers didn’t think that they needed normal objects described in classes in order to implement these types. The values (in the legal range for each type) can be thought of as stored directly in the variable. But objects are much more complex creatures! They have state which can be a combination of many values (even references to other objects!) and behaviour (which is expressed in so called methods like greet() ). For this reason, it is hard to implement a reference type that would hold all of this directly in the variable. Numbers and boolean values are much easier to store than complex constructs like objects. Also, objects need to be created before they exist and can be used. So there is a need to allow for reference variables to be declared before they refer to any particular object.

But the main reason we can’t give you a list of reference types, is that much of programming in Java deals with declaring and writing code for classes. When we make a class up, like the authors did when they created the Greeter class, we come up with a name ourselves. So the list of reference types is not fixed! You are going to write your own classes etc later in the course, and each new class is a reference type.

I think it might be good to say something about the naming conventions for reference types here, if you don’t mind! Reference types like classes should always start with a capital letter! This is only a convention and standard, but it really helps when reading some source code. Names (identifiers as some call them) that start with a capital letter signals that these are exactly that, reference types! We directly see that a variable whose type starts with a capital letter (like String) must be a reference type. We don’t have to remember the eight primitive types in order to see this. The capital S in String gives away the information we need, this must be a reference type (such as a class)!

Q: “What is a declaration of a variable and when do I need it?”
A: The declaration of a variable is a very common instruction in Java programs (and programs in many other languages). Java is a language where types are very important and thoroughly checked by the compiler and runtime system. That means that types are important in Java and the reason it is so important to check the types, is that it helps us from doing mistakes (as we humans are so prone to do). If we have a variable that we plan to use to hold some numeric information and we by mistake store a string of text in it, the program will most likely not work the way we planned and hoped. So that kind of behaviour is forbidden in the Java programming language. So, in order for the compiler to help us check things like this, we need to declare what types our variables have - that is what legal values can later be stored in the variables. So when we declare that we want to use a new variable, we also say what type it has and then what name we want to use. If we want a variable capable of storing integral numbers (in the range that matches the legal values in the int primitive type) we could say like this:

 int numberOfLines;

After that declaration statement (statement is just a fancy word for instruction), we are free to use the variable numberOfLines in our program in later statements. The compiler will now help us so we don’t try anything stupid as trying to store text in the variable. Only integers in the range for the int primitive types are now possible to store in numberOfLines.

Inside methods, it is common to start the code by declaring all the variables that will be used in the method. When we declare a class, it is common to start with variables before constructors and methods (but this is also just a convention and not a rule).

Q: “What’s the difference between declaration and initialization?”
A: Declaration is about deciding type and name of a variable before it can be used. Initialization is all about giving the variable its first value. You can do the steps one-by-one like this:

 int numberOfPages;
 numberOfPages = 0;

Or in one statement in one go like this:

 int numberOfPages = 0;

You can choose the version that you find most convenient or intuitive. However, you cannot use a local variable (as a part of an expression, that is: using it as having a value) before it has been assigned a value. Instance variables are a different story, but we’ll talk about them in chapters to come!

Q: “Is it correct that assignment is used when we want to change the value a variable holds? If so, where does the value come from? It seems odd that we already know what values a variable will hold already when we write the program...”
A: It is correct that assignment is used to store a new value in a variable. The values we know beforehand are usually the initial values. Typically, as the program is running, new situations occur and we need to change the state of the program according to external events. Depending on the domain of the program we are writing, a number of sources can be found for the new values. On program might be used to order some product. In order to process the order, the user of the program must indicate in some way what product or products is to be ordered. Depending on the user’s actions (and how we respond to them) the information about the order will probably be stored in some way using variables and assignment. When the customer wants the order to be shipped, the customer might be presented with a form where the customer enters name, address, email, phone number etc. The program would typically use the values entered by the customer and store them in variables using assignment.

Another program might be used to get information about text files. It could, perhaps, count the number of characters, words and lines of any text file the user provides as an argument. Since the number of lines, for instance, is not known beforehand, the program would probably read the file and count how many lines it can find in the file. The count of lines would typically be stored in a variable (perhaps called numberOfLines). The value of the variable would change by being increased by one for every new line the program finds while reading through the file. That could also be accomplished using assignment.

We think it is safe to say that most assignments are results of some operation rather than typed in literally when the program is written. But since we don’t know how to get information from users, or how to read files etch, we show examples using typed in values directly in the source code. Such values are sometimes referred to as “hard coded values”.

Q: “What is the relation between assignments and types?”
A: That is an important but a little tricky to answer question. We’ll try our best! In an assignment there are two parts. The part on the left (maybe we could think of it as the assignee - the variable which is being assigned a value) is always a variable. And all variables have, as we now know, a type. The other part, on the right-hand side, is some kind of value. The value could be typed in (hard coded) or it could be something more complicated like another variable. It could also be the result of some calculations like in

 numberOfChildren = numberOfSons + numberOfDaughters;

There are more things that result in a value which would fit in on the right-hand side but we haven’t learned those yet. The important thing to understand here is that not only variables have a type. In Java, values too have a type! For instance, if you type in an integer such as 7 and use that as a value in, say, an assignment, Java will consider the 7 as being of primitive type int. If you instead type in a real number, say 3.14, that value will be interpreted as being of primitive type double. We have already seen that variables can be used as the right-hand side of an assignment, and we know that variables have a type. Now we have also told you that even hard coded values have a type.

The relation between assignments and types is that we have type security (we get help checking types) in Java. Before we can compile some code containing an assignment, our friend, the compiler, checks the types on both sides of the assignment operator. It starts by looking at the type of the variable to be assigned, and then checks the type of the value on the right-hand side (this sometimes is non-trivial - there are rules for determining the type of a calculation for instance). If the type of the variable to be assigned can hold values of the type of the value on the right-hand side, the compiler will not complain. If, however, the value on the right-hand side is not compatible with the type of the left-hand side variable, we get a compilation error with a message describing the problem.

Q: “What is compatibility then? When is a value of some type compatible with some other type?”
A: First of all, numeric types can only hold numeric values. We can never assign for instance a boolean value to a numeric type in Java. But there are 6 numeric types in Java. Four integer types: byte, short, int, long and two real number types: float, double. Why the need for four integer types, you may ask? The answer has to do with the storage space for the various types. For small values, only a smaller space in the memory is required to represent all valid values. For an integer between -128 and +127, only eight bits are required (a bit is the smallest unit of memory, a space that only can hold a 0 or a 1). The standard integer type int has 32 bits memory space (which allows for really small and really large integer values). Since both byte and int are for integer values, they are compatible at least in one direction. You are always safe to assign a byte value to an int variable and the compiler will always allow this.

Now, if we want to assign a variable of type byte (with only 8 bits space) a value of type int, there might be a problem. It is far from certain that an int value will be inside the allowed range of a byte. For int type values (32 bits) that are unknown at compile time (such as variables) i.e. not hard coded, such values won’t be allowed as the right-hand side of an assignment to a byte (8 bits) or a short (16 bits). If we insist of doing so, we must first convert the value to the corresponding left-hand type of the variable to be assigned.

Q: “How does one convert a type to another type?”
A: This is done using a type-cast. To convert an expression (a value, a calculation, a variable, etc) of type int to type byte, for instance, we write like this:

(byte)intExpression

That is, we put the target type in parentheses before the source type. Now, we must be aware that this is a risky business! To store a value from a huge storage space of 32 bits inside a small space of only 8 bits, there is a huge risk that something will go wrong and information will be lost. The problem is similar to pouring the water from a large glass into a smaller glass. If the large glass only holds a small enough amount of water to fit inside the small glass, everything is fine. But if the large glass is holding much more water than the small glass, pouring all the water into the smaller glass will result in a loss of water (and probably a wet floor).

Expressions and operators

Q: “What types of operators are there in the Java programming language?”
A: One way of grouping operators together is by looking at the type of the value they produce. For instance, there are operators that produce boolean values like comparison operators and boolean operators. Comparison operators take numeric operands in the form of a claim about the relation between two values: a < b

The claim that the value of a is smaller than the value of b is either a true claim or a false claim. Therefor the value of the expression a < b has the type boolean (which only allows two values, true or false).

The boolean operators also produce a boolean value but the operands have to be boolean values as well. If we have two boolean values; isRaining and isStormy, that hold the state of the weather (if isRaining is true, it is raining, if isStormy is true it is stormy), than we can combine them using a boolean operator such as && (meaning AND). If we use the && operator with the variables as operands, we would say for instance

 isRaining && isStormy

which also would be a claim about the weather which would be true or false. Only if both isRaining and isStormy are true, the claim that it “isRaining && isStormy” would be true! (And it would also probably be wise to wear a raincoat instead of bringing the umbrella.)

For numeric types we can also use operators which produce new numeric values. That would be the arithmetic operators which take operands which are also numeric such as addition, subtraction, multiplication and division. We also have remainder (which produces the left over from integer division).

To produce references (addresses to objects we could say) we use the new operator (new is also a Java keyword and reserved word). We have seen that in a previous chapter when we produced brand new Greeter objects using the new operator (and a named constructor).

A special kind of operator is the assignment operator. It always has a variable as the left-hand operand and an expression as the right-hand operand. But what type of value does it produce? It produces the same value as the right-hand side, actually (and the same type). So, in theory, we could use an assignment as an expression and put it on the right-hand side of another assignment like this for instance:

 numberOfLinesBackup = ( numberOfLines = firstBatch + secondBatch );

This is actually also possible in practice but we advise you not to use this style. Much clearer if you divide the above into two assignment statements instead.

Above we have seen some of the operators grouped together by the type of value they produce.

Q: “What other way could we use to group operators?”
A: We could, for instance, look at the function or purpose of operators. We could say comparison operators, assignment operators, logical operators, arithmetic operators etc. How we group the operators may not be the most important aspect for understanding operators however. We have to understand that operators are applied to form expressions and to produce values of some type. Sometimes the type of the expression is the same as the parts (operands) of the expressions and sometimes not.

What we haven’t talked about is the number of operands an operator requires. There are two basic categories here: unary operators and binary operators. Unary operators are applied to one single operand. Examples of this is sign operators ( + and - ). If we want to change the sign of the value of a variable we could use - (the minus sign) like this:

 int warm = 30;
 int veryCold = -warm; // -30 is very cold

The - operator used like this operate on a single operand (in the example the variable warm). So - used like this is a unary operator. Used like a unary operator, the - sign must be applied before the operand. You cannot say “warm -;” for instance.

Unary operators that are applied before the operand are called prefix unary operators. Does people talk like that, you may wonder? Well not everybody, but people at universities and people writing books about programming like to use words like that. You don’t have to learn all the technical terms, we are just discussing different types of operators and their number of operands and the position of the operand of operators with only one operand.

Other examples of unary operands include ! (the exclamation mark is used as meaning NOT and is a boolean prefix unary operator). The NOT operator can be used like this:

 !isRaining

Used like that requires isRaning to be a boolean type variable and would have the effect of negating whatever value isRaining might have. The value produced is of boolean type of course, since we should consider it a claim meaning “not is raining” which is true on a sunny day but a false claim most days in Göteborg (where it is raining a lot).

The increment and decrement operators ++ and -- can be used both as prefix (before the operand) and postfix (after the operand). There is a difference between these two positions in the way the expression is evaluated. As all operators, the increment and decrement operators produce a value when applied to their operand. But they also have a side-effect, in that the operand (which always is an integer type variable) changes its value (up one for increment and down one for decrement). When applied as a prefix operator (before the variable operand) the change of value happens before the value of the expression is produced. When applied as a postfix operator (after the variable operand) the value produced of the expression is the old value of the variable, and only then, after the expression is evaluated to a value, the change of value takes place.

Binary operators, on the other hand, require two operands, on on each side. The * operator (asterisk or star) is a binary operator. The operator is in the middle of the two operands, and some people like to call this an “infix” operator. You don’t have to call it that, though.

Finally, there is one ternary operator (or operator pair) in Java. The operator has two symbols, ‘?’ and ‘:’ (question mark and colon). It is used as a short form for making decisions. The operands are three. First there is a boolean expression followed by the question mark. Next, there is an expression which is to be the value produced if the boolean expression was true, next there is the colon followed by and expression which is the value to be produced if the boolean expression was false. This requires an example, probably:

 Boot myBoot = isRaining? Boots.WELLINGTONS : Boots.REGULAR_BOOTS;

Video about ternary: Java Ternary operator (pdf)

In the example, we pretend we have a type Boot (which is described somewhere, perhaps in a class defined in a file Boot.java) and a reference variable myBoot. We want to decide what type of boot it should be and let the variable isRaining decide for us. If it is raining, Wellington boots are suitable. Otherwise, we go for regular boots.

Q: “I have seen some other symbols in the example programs you have shown us. They include:
 ; . ( ) [ ] { } ,

Are those too operators?
A: Well, no. They are very similar to operators but we call them separators. They are used to... well... separate parts of our program from other parts. We can talk a little about some of them, in particular the ones we have seen being used in practise. First we have the semicolon ;

The semicolon is used to terminate an instruction (a statement). To the Java compiler it means “Here ends one instruction”. Next, we have the dot .

The dot is used in a few ways. One way it is used, is to form the separator between directories in a package path. We’ve seen it in the form import lib.Greeter . The dot between lib and Greeter means that lib is a directory and in that directory we find Greeter (which is a class).

The parentheses are used to group parameters when we define a constructor or a method. They are also used to group the values we give as arguments when we call a constructor or a method. Client code (like the code we saw in the main method) calls a constructor in some class and use the parentheses to group any arguments (supplied values) that we might want to send along. The same thing applies when we call a method. Client code might want to call a method defined somewhere and we use parentheses to group any arguments we might want to send along.

The square brackets [ ] have to do with lists of values (such lists are called arrays in Java - more on that later!). We’ve only seen it in the definition of the main method:

 public static void main(String[] args)

The use of a list (called an array) of String in the main method’s parameters means that it can be called (by the JVM) with zero or more String arguments. We don’t know yet how to use arguments to the main method, so this probably sounds abstract. Don’t worry. We’ll see examples of that later in the course. For now, just think that you can send along values to a method. Arrays can be used to let us send any number of values packed as a list (which may be empty - or even no list at all).

The curly braces are used to form blocks of code. Typical blocks include a class definition, a constructor definition, or a method definition. There are actually a few other types of blocks but we haven’t seen them yet so we leave that for a later day. The comma , is used when we list things. It could be contents of an array (example of that later in the course), or a list of values that we send as arguments to a method. When declaring a method that can accept for instance two arguments, we define the parameters separated by a comma.

 public static long add(int a, int b){ ...code adding a and b... }

That’s actually how we could define a method that takes two int values as arguments. Not that we declare the parameter variables a and b separated by a comma. You will soon learn more about methods, so please be patient.

Control flow

Q: “The for loop and the while loop seem to do the same thing. When should we use the one and when should we use the other?”
A: You may use the one you feel most comfortable with. If you want a hint of when to use for and when to use while, there is a recommendation that in situation when you know beforehand how many iterations you want, you should use the for loop. It could make the program easier to read and understand. When you don’t know how many iterations you want (for instance if your program is reading lines of text from a file and you don’t know how many lines there are in the file), it is probably more clear to use the while loop. When you read the code out loud, it could better match the way we think and speak. An example of reading out loud the line counting loop, could be “While we haven’t reached the end-of-file, read one more line and increase numberOfLines with one”. If we want to print ten copies of a document, we could use for and such a piece of programming could be read out loud like this, perhaps: “For every number between 0 and 9, print a copy and move the counter to the next number”.

As you see, reading out the for statement doesn’t really match the way we think or speak, but there is an alternative syntax for the for loop that we use when we have some kind of list. We’ll revisit the for loop when we have learned about lists, but as a teaser, we can say already that reading out the for loop when iterating over a list reads something like this: “For each element in theList, do something with that element and move on to the next element”.

Q: “Are there any other control flow mechanisms that you haven’t told us about?”
A: Actually, yes. There is a version of the while loop, called “do while”. It works almost like the while loop, but it always execute the statements in the block at least once, because it has the test of the condition at the end of the block.

 do{
 swingAxeAgainstTree();
}while( tree.isStillStanding() );

The example above could be a simulation of cutting down a tree using an axe. We know that we must swing the axe against the tree at least once. And then we check to see if the tree is still standing. If it is, we repeat until the test fails (and and the tree is down).

To be honest, the do while construct is not very common, since in most situation (like when cutting down trees) there is no harm in doing the test first. That would be like first checking that the tree is standing before starting to swing the axe against it.

Another construct is the Switch statement. It is useful as an alternative to if-else-if statements when we know that there are many possible cases to test. It is quite common but not very hard to learn. We will not require that you know the switch statement but we encourage you to learn it anyway, as an exercise. You can read about it here: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/switch.html

Q: “Where in a Java program do we use the control flow things?”
A: Almost exclusively in methods and constructors. There are some exceptions to that rule (there are two special kinds of nameless blocks inside classes, but they are outside the scope of this course!) but if you want a rule it would be: Always inside a block, but never directly inside the block of a class (or inside the block of the friends of classes called interfaces and enums).

So you will never see an if statement, for instance, directly in the body of the class block. It is always inside a block that is inside the class block. Remember, the class block is one of the few blocks that can be the outermost blocks in a compilation unit (in a Java source code file).

Objects

Q: "Objects are entities with data and behavior, you say. How is the data actually stored in an object and how do we invoke an object's behavior?"
The data is stored inside the object in the memory space for the object in the JVM's so called "heap memory". This happens when the program is running and the code of the program creates a new object somehow (usually be calling a constructor in the class which describes obects of this type and this is done using the operator new). The data inside an object can also be called "the object's state". The code in the class describing objects of a particular type declares variables to store the state of the object. Normally, this is done using the keyword private, which effectively hides the variable name from uses by code in other classes (code that use and manipulate the objects). To change or use the state of an object, one typically invoke one of the instance methods of the object. Instance methods are methods also written in the class describing a particular type of objects, and they may access the instance variables (even if they are marked private because code in the same class is the only code that have access to private stuff).

In order to invoke some behavior, i.e. calling an instance method, for an object, you need to have a reference variable which refers to the object you want to use. A reference variable is a variable whose type is the same as the type of the object (often the class of the object). The reference variable is your handle to the object in the heap memory. Invoking a method on an object is done by using the reference variable and the dot separator and the name of the instance method together with any arguments the method might need.

You have already used objects via reference variable, perhaps without knowing so. When you used the System.out.println("Hello"); statement, you were actually using the reference object out (which belongs to the class System). Via the reference variable out, you invoked the instance method println(String str) for the object which out referred to.

In coming chapters, we will learn how to write our own classes. Hopefully things will get clearer then, when you yourself write the code for instance variables and instance methods. For now, you can think of classes as compilation units for a program. This units (classes) describe common state variables and common instance methods for a type of objects. Classes are written once and used many times. You use a class as the type of reference variables you use in a program. Reference variables are then assigned references to objects, usually as the result of calling the constructor of the class that describes a certain type of objects.

Q: "Can you say that classes, then, are descriptions of objects of the same type?"
That's one way of putting it. But beware that not all classes are used as the blueprint or description of objects! For instance, you have already learned that a small Java program requires at least one class, the one containing the main method. It is not sure that such a class will be used for creating objects (but it is possible).

Many Java books define classes simply as the blueprint for similar objects. While this is true most of the time, it is not true in every case. You have, for instance, used the System class (because it's the one which has the out reference variable we use for printing stuff to the standard output stream). The System class can't even be instantiated (you cannot create objects using System as the type or description). There are actually quite a few classes like that in the Java standard API. Another example is the class Math. You use the class Math because it offers a lot of mathematical methods directly to the programmer. You don't have to create a Math object in order to invoke for instance the sqrt (square root) method. In fact, you cannot create an instance of Math. The reason for this design decision is probably convenience (smoother to invoke a method directly using the class name) and the fact that it doesn't make sense to have many objects representing "Mathematics".

Q: "You say that some classes can't be instantiated, i.e. you cannot create objects from them. What keeps some programmer from simply calling the constructor using the operator new on for instance the System class?"
It is done using the private keyword. Anything in a class marked as private cannot be used from outside the class itself. You have seen what a constructor looks like. Do you remember? Usually a constructor looks like this:

public ClassName(){
  //some clever code which initializes the state of the ClassName
  //object which is being created here... 
}

The pattern is public followed by ClassName (the name of the class) and parentheses with arguments (if any) to be used in the constructor body for initialization. But what if you substitute private for public? Then the constructor itself cannot be called from outside the class! This means that no one can create objects of this class (provided there are no public constructors at all in the class). This is what the only constuctor in System looks like:

    /** Don't let anyone instantiate this class */
    private System() {
    }

This is taken directly from the source code of java.lang.System. Note the comment in the source code!

Q: "You say instance methods must be invoked using a reference to some object. Yet you say that there are methods in for instance Math but we cannot create objects of type Math. How can this be?"
That's a very good observation! Instance methods are always only relevant for some object and you need to invoke them using a reference to the object which you want to use. But methods in the class Math, for instance, are not instance methods. I'm sorry to break it to you, but there are actually two types of methods. Methods that you can call without objects or references are called "class methods" (because they belong to the class itself and not any particular object) or "static methods" (because they are written with the keyword static like the good old public static void main(String[] args). The method sqrt in class Math for instance, is defined like this:

public static double sqrt(double a){
  //some clever code which calculates the square root of "a" 
}

Note the static keyword! It means that this method should be called using the class name such as:

  double c = Math.sqrt( a*a + b*b );
}

Q: "But if static methods, or class methods as you also call them, are more convenient than instance methods, why do we need instance methods?"
Again, a great question, but a little harder to answer. The thing about static methods, is that they are not very common in typical Java program (if you don't count methods from simple programs in Java text books). Programming in the object oriented style means that we package data and behavior together in objects and we let the objects do all the work in our program. Static methods cannot operate on instance variables (since they cannot know if there are any instances, and which instance to use if threre are). So static methods can only operate on the data we send to them as arguments (and data that is stored directly in the class). This is the opposite of the object oriented way of thinking! We don't want to manage a lot of data and send them to methods. We'd rather talk about objects and let the objects keep track of their data, and we humbly ask the objects to do some work for us, taking their state into account.

Static methods are mainly there as convenience methods for performing rather mechanical and static work, like calculating the square root of some number. Objects, on the other hand, are much more lifelike creatures. A program for a computer game, for instance, might have several Player objects (perhaps running around in a maze trying to find a treasure). All Player objects share the same characteristics but they are individuals. One Player object might be green and very fast, while another Player object might be Pink and not so fast (but has the ability to jump over large rocks). All players are described in the Player class, but their state varies. We can invoke the same type of behavior using the instance methods described in the class on them, but the result would be different depending on their state. Invoking the run() method on the first player would result in fast movement but if we invoke the same behaviour (run) on the second player, the movement wouldn't be so fast. This could be done using a private speed variable which keeps track of the maximum speed for particular Player objects. The first player had a large number stored in its speed variable while the second player had a smaller number in its speed variable. But the actual variables are private and hidden from the users of the Player class (the programmer writing the logic of the game). The program using the Player class uses reference variables to invoke behavior on a Player object like calling the run method on one of them. The object itself now knows how to run (and how fast it can run) which lets our programmer focus on things on a much higher level of abstraction.

Q: "The String class seems to be very useful. There are lots of program which handle text. But it seems a little special. Could you say something about what makes the String class and objects of type String (reference to String, as you seem to prefer to say)?"
The String class has some properties which makes it a little different from other classes. The first thing that comes to mind here, is that we can create new String objects simply by typing a text string inside quotes. That's very untypical for object creation. The reason for Java to allow this weird behavior is that it actually makes the creation of String objects very simple. And since String objects are so common in programs, why not offer a simple way to create them? You can use constructors for creating String objects too. But there is a subtle difference between a String created like this: String name = "Adam"; and a String created like this String name = new String("Adam");. The difference is very subtle but very important to understand later in the course (or if you keep studying Java). Strings created using the double quotes are re-used. By re-used, we mean that in a program where two Strings with the exact same text are created using double quotes doesn't actually create two different String objects. The JVM will discover that there already exists a String object with the same text as the second object created with quotes. So any reference variables referring to the String object created with quotes, will refer to the same object in the memory:

  String myName   = "Adam";
  String yourName = "Adam";
}

In the code above, threre is only one String object created. Both myName and yourName now refers to that same object in the memory. Such objects are said to be put in the "string constants pool". If you really need two different String objects with the same text, for some reason, you would have to use the constructor and the operator new for at least one of them. Using the constructor for any class of object, always guarantees a new distinct object.

At this point you don't have to care about this subtle difference so much, but it would be wrong for us not to mention it at least. If you keep using or studying Java, however, these things might get important for you to understand the exact behavior of a program written in Java.

Another thing that makes String convenient to use is that it is part of the java.lang package. The special thing about that package is that you can use classes in that package directly without having to import their path to the program using the import statement. You may think of it as the java.lang package always automatically (implicitly) being imported.

Lastly, there is another subtle thing about the String class and its objects. Objects of type String are what is called immutable. That simply means that you cannot change the state of a String object (you cannot change the text of a String object). If you call, for instance, the toUpperCase() instance metod of a String, you might think that you change all the letters in the String to upper case. You don't. What happens is that the method creates a new String (with the same letters but all upper case) and returns a reference to that object to you. The old object will get discarded from memory automatically:

  String name = "Adam";
  name = name.toUpperCase();
}

In the code above, first a String is created representing the text "Adam" and the variable name is assigned the reference to it. On the second line, the instance method toUpperCase() creates a new String object representing "ADAM" and returns a reference to that object. The reference to this new object is assigned to name. The first object (representing "Adam") is now long gone and forgotten about. It will be "garbage collected" by the JVM since there are no references to it any more, so it can't be used anyway.

Q: "Phew! Strings seem to be complicated creatures. Should I worry?"
Don't worry. This is an introductory course and we will not use these special cases against you! We are only telling you about them so that we don't feel that we've kept secrets from you. If you don't understand these subtleties now, you don't have to worry. Hopefully they will become clearer when you have read more chapters and seen more lectures later on. Why not revisit this explanation after a few more lectures? However, we will not require that you understand and remember these quirks after the course. Topics we feel are very important will always be part of lectures and/or exercises. These Questions and Answers are for the curious and ambitious student who always want to learn more!

Q: "Packages seems to be an important concept in Java, because every class seems to belong to a package. When we write our own classes, like in the exercises, the package declaration always matches the path to the source code (and binary class) file for the class (only that dots are used to separate directories where the shell would use a forward slash). But when we import for instance java.util.Properties, I don't understand where the path "java/util/Properties.class" would lead? Is there really directories somewhere for the java api packages and their classes?
That was very observant of you! Yes, the packages in the API (like java.lang, java.util and all the rest) are actually also paths to the compiled versions of the classes in the packages. The only difference, is that the whole API (with all its directories for packages and all the class files in those directories) are packaged together in a file called rt.jar. If you think about it, how could it work to use java.lang.String for instance, if there was no compiled class file called String.class on your system? And how could the compiler and JVM find it if the package didn't symbolize a path with directories, like when we create our own classes?

When you install the JDK (Java Development Kit), you get the API as a part of the installation (otherwise we couldn't use String or Properties etc). The part which actually contain all these API classes is a kind of zip file (compressed archive file) with a large directory structure inside it. The file is called rt.jar (jar is a Java type of compressed archive file format).

To prove we are not lying to you we'll show you that the directory structure is there, using some bash command trickery:

$ ls /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar
/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar

$ file /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar
/usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar: Java Jar file data (zip)

$ jar tf /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar | grep '/System.class'
java/lang/System.class

$ jar tf /usr/lib/jvm/java-7-openjdk-amd64/jre/lib/rt.jar | grep '/Math.class'
java/lang/Math.class

What we did there, was to list the rt.jar on a computer with Java 7 installed. Next, we used the file command to investigate what kind of file the rt.jar was. The answer was "Java Jar file data (zip)" (file is a very capable command for investigating files!). After that, we used the jar utility command (also included in the JDK) to list the files in the rt.jar, but since there are thousands of classes there, we filtered using grep the result for some familiar classes mentioned above. As you can see, the System.class was in the directory java/lang/System.class and the Math.class file was in the same directory. The directories correspond the the package names! java.lang.Math corresponds to the compiled class file found in java/lang/Math.class in the rt.jar archive.

Q: "In one of the more complicated solution suggestions to the Loop Challenge exercise, you were using List instead of ArrayList. You said something about List not being a class but something called an interface. What is the difference between a class and an interface?"
We will talk a lot about interfaces in a chapter to come, but since you ask already, I'll try to be brief and explain some basic differences between classes and interfaces. As usual, you don't have to understand this yet, since we haven't gotten to the Interfaces chapter yet, but here goes anyway!

A class can define both instance variables for storing the state of objects to be created using the class and instance methods. Classes are in this regard quite closely related to objects. You can use a class to create an object. Interfaces (in the most common case) only concern themselves with describing the behavior (instance methods) of a group of objects. Interfaces describe what messages (what methods can be called) for a related type of objects. So interfaces also define a type of objects. But interfaces do this in a very abstract way, as they only describe the names, return types and arguments of methods for the type. Interfaces don not define the code for what the methods actually should do, just that they exist. An interface, then, is a construct much less related to specific classes of objects, since we use them when we only care about what methods exist for objects of an interface type, and how to use these methods.

List is an interface describing the methods common to different sorts of lists. ArrayList is a concrete type of list, described in a class. But the class ArrayList is said to implement the List interface, which means that all the methods abstractly described in List exist "for real" in the ArrayList class.

This construct allows us to declare references of type List so that we only care about what messages we can send to the actual object referred to (and the signature of the methods). If we use a List reference variable to refer to some List type object, the actual object may very well be an ArrayList (or some other list). We don't have to worry about that, since we will only send the messages (call the methods) declared in the List interface. You could, in this sense, say that it is easier to program against an interface type, than against a concrete (class) type.

In the actual example code where you found the use of List, the reference was assigned like this:

List<String> argList = Arrays.asList(args);

The asList() method in the Arrays class (by the way, a static method) takes as argument an array and converts it into an object of interface List type, and returns the reference. The actual object created most certainly is an ArrayList but we don't care, since we are only using the for-each loop to traverse the list in our program anyway. List type objects can be used in for-each loops, which was what we wanted to do in our program.

Q: "Talking about advanced solutions to challenges, the org/progund/lists/ArgumentHelper.java class, used in the suggested solution to the LoopChallenge in this chapter, the object oriented version, has a lot of instance methods, I guess. But why are some of them marked as private and some marked as public?"
We will talk a lot more about so called "access modifiers" (public and private for instace) in the next chapter, but in short private means "can only be used by code in this class". So only code in the ArgumentHelper class may call any of the private methods in the same class. On the other hand, public means that code from any class may call it. The ArgumentHelper class is used to create an object in the main method of the LoopChallengeOOVersion class. Code in this class can only call the public instance methods of the ArgumentHelper object.

Methods that are of no concern or use directly to users of objects should be declared as private (to keep people from using them or even knowing about them). The public methods in a class are what users of objects of the class see and can use. The public methods of an object can be said to be the "programming interface" to the object. The programming interface is what you can do with an object. As you saw in the solution, some of the public methods needed to get help from other methods but sometimes such helper methods are not meant to be part of the public interface of objects created from the class. So we hide them from users of the objects, which makes our objects easier to use. The fewer public methods an object has, of course, the easier it is to use and understand the object's capabilities.