Chapter:Classes - Packages

From Juneday education
Jump to: navigation, search

Meta information about this chapter (TODO)

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

Introduction

This chapter about classes deals with packages and the package declaration.

Purpose

This lecture gives a basic introduction to the package declaration and how packages relate to the directory layout of source code and class files. We think it is natural to talk about packages early and frequently, since this is so central to Java software and APIs. It is so central, that we get back to the topic in a later chapter where we focus on using packages and the motivation for doing so.

The purpose of this chapter is to give a soft introduction and explain why source code files for Java classes almost always start with a package statement.

Goal

After this chapter, the student shall understand:

  • The package statement and its relation to the directory layout (on a basic level)
  • That packages are important and central and used everywhere
  • That we will return to the topic in a later lecture

Instructions to the teacher

Common problems

Don't make the mistake of skipping packages in your examples and exercises unless you point out the reason for doing so (brevity for instance). Make sure that the students understand paths (relative and absolute) because without that understanding, they will struggle to understand packages and how to compile and run programs using packages from the command line (but also IDEs might have settings for class path etc).

Paths are so important to understand, that we have a dedicated page about the topic.

Explain also to the students that we will get back to the topic of packages in a later lecture.

Full frontal - code up-front!

Here's what the package declaration can look like:

package org.progund.education;

Introduction to the Package declaration

Imagine there are two classes with the same name and you want to use them both. Actually this is the case already in Java with a class called Date. In Java this is solved by adding an extra name to the class, we use the package construction. The two classes are java.util.Date and java.sql.Date and by using packages we can use them both.

Also imagine if you have a project with some thousand classes. Keeping all the corresponding Java files (the source code) in one directory would make it very hard to get an overview of the source code. Instead we split the project into smaller parts, each responsible for a part of the complete system. To achieve this we use the same construction as above.

We dare say that you will not see a program, in use by real users, that don't use packages. Not using packages is unfortunately something you will see in many books and education material. Since packages are easy to use we're going to use packages for everything we all write in the future - be it examples, exercises, assignments and exams.

A class can contain zero or one package declaration, which has to be the first statement in the source code file for the class. If the class source code doesn't have a package declaration, the class will implicitly belong to a "nameless" package, which could be thought of as "current directory". Packages correspond to the relative location of the compiled source code file. The source code is also saved in a directory structure matching the package name.

A class in the "nameless" package can only be found by the java command (actually by the JVM's so called class loader) if the command is executed in the same directory as the class file (the compiled source code file). A class in an explicit package must be compiled into a directory matching the package name.

A package normally name consists of a series of lower case parts, separated by '.' (dots) leading up to the actual class name, as in org.progund.Game, where Game is the name of the class. Each part leading up to the class name corresponds to physical directories of the same name and structure. If we look at org.progund.Game again, the source code for Game.java should be located in a directory structure as shown below:

.
`-- org
    `-- progund
        `-- Game.java

Note the dot at the top of the directory structure. This is the starting point of the relative path to Game.java. A dot signifies "current directory" in most terminals and shells. This is to say, that if we are in some directory and want to compile Game.java, and Game.java belongs to the package org.progund, we need to make sure that the class file from compiling Game.java ends up in a directory structure according to the package name. Here, the first part of the package is org. So we need to have a directory called "org". The next part is progund, which means that inside "org" we need to have a directory "progund". This means that the dots correspond to the file separator character in a path! On UNIX-like systems (like cygwin), the file separator character is "/" (forward slash). So, the compiled file for org.progund.Game must be located in the relative location org/progund/Game.class.

Now, if the source code file Game.java is in org/progund/Game.java and we are in the current directory as shown above, if we compile the file using the relative path to it:

$ javac org/progund/Game.java

Then, the compiler (if the compilation is successful of course) will put the class file in the same directory as the source code. We will then have a directory structure as shown here:

.
`-- org
    `-- progund
        |-- Game.class
        `-- Game.java

Now, let's pretend that the Game class has a main method, so that we can run it as a Java program. If we want to run it using the java command, we will actually give java the full class name (the qualified name including the package):

$ java org.progund.Game

We saw that the class file which is loaded and run by the JVM invoked by java was located in the relative path org/progund/Game.class but the argument to java was org.progund.Game. This should make it obvious that the dots in the class name corresponds completely to the directory separators!

It is OK if you keep things as described above where the class files end up in the same directory as the source code files. But in the real world, it is actually common to keep two parallel file structures; one for the source code and one for the class files:

.
|-- bin
|   `-- org
|       `-- progund
|           `-- Game.class
`-- src
    `-- org
        `-- progund
            `-- Game.java

Now we've added to extra levels; the bin directory, and the src directory. Note that these are not part of the Java world! They are just there so that we can have two identical directory structures side by side!

If we'd want to run the program using Game.class, we'd have to cd down to the bin directory, so that org.progund.Game still would translate to a valid relative path! If we cd to the bin directory, when the package name is translated to a relative path, the path would still be correct to the file org/progund/Game.class. But if we'd stayed in the directory annotated as "." in the layout above (the directory where both bin and src are located), running java org.progund.Game would yield a "Class not found" error from the java command. This is only natural, because the JVM would translate the qualified name org.progund.Game to a path for the class files org/progund/Game.class. Trying to resolve that path would fail miserably, because there was no org directory in the current directory! Only a bin directory, and a src directory.

Now, there is actually a solution to this too! Java comes with a concept called "class path". If we were in the directory above bin and src, we could actually help java find the org.progund.Game class, by giving it a hint on where to look for the org directory:

$ javac -d bin src/org/progund/Game.java 
$ java -cp bin org.progund.Game
Game over!
$ ls
bin  src
$ ls bin/org/progund/
Game.class
$ ls src/org/progund/
Game.java

The trick was to provide the class path using the flag -cp bin. That meant "run org.progund.Game but look in bin in order to find the class!".

Chapters about classes

Here are the chapters about classes in this book, so that you can keep a check on your progress:

Video

Links

Further reading

Where to go next

The next page has exercises for this chapter: Classes_-_Packages_-_Exercises

« PreviousBook TOCNext »