Welcome to Java for Python Programmers. This short ebook is an ongoing project to help Computer Science students who have had one or two semesters of Python learn the Java programming language. If you are not a part of that audience you may still find this a useful way to learn about Java. This book is written using the build on what you know philosophy. In order to help you learn Java I will start with a Python example and then implement the example in Java. Along the way we will examine the strengths, weaknesses and differences between those two languages.
This book does not attempt to replace the many good Java reference books that are available, in fact I use this in my course along with Horstman’s Core Java volumes. Please feel free to use this book for yourself, or if it fits a class you are teaching you are welcome to use this as a resource for your own class.
I have published this article using a Creative Commons license to encourage you to use it, change it, and modify it for your own purposes. I would appreciate knowing what you think if you do use this book, and I would love to see any modifications or additions you make.
Brad Miller bmiller@luther.edu January, 2008

This work is licensed under a Creative Commons Attribution 3.0 United States License. See http://creativecommons.org
This book assumes that you are already familiar with the Python programming language. We will use Python as a starting point for our journey into Java. We will begin by looking at a very simple Java program, just to see what the language looks like and how we get a program to run. Next, we will look at the main constructs that are common to most programming languages:
Once we have the basics of Java behind us we will move on to look at the features of Java that are both unique and powerful.
Please note that this book is a work in progress. I will continue to update and post new versions.
Python is a nice language for beginning programming for several reasons. First the syntax is sparse, and clear. Second, the underlying model of how objects and variables work is very consistent. Third, you can write powerful and interesting programs without a lot of work. However, Python is representative of one kind of language, called a dynamic language. You might think of Python as being fairly informal. There are other languages, Like Java and C++ that are more formal.
These languages have some advantages of their own. First, is speed: For very large programs Java and C++ are going to give you the best performance. Second is their maintainability. A lot of what makes Python easy to use is that you must remember certain things. For example if you set variable x to reference a turtle, and forget later that x is a turtle but try to invoke a string method on it, you will get an error. Java and C++ protect you by forcing you to be upfront and formal about the kind of object each variable is going to refer to.
In one sense Python is representative of a whole class of languages, sometimes referred to as “scripting languages.” Other languages in the same category as Python are Ruby and Perl. Java is representative of what I will call industrial strength languages. Industrial strength languages are good for projects with several people working on the project where being formal and careful about what you do may impact lots of other people. Languages in this category include C++, C, C# and Ada.
Programming languages will always change. As the field of computer science advances there will be new programming languages and you will need to learn them. It is important to learn several programming languages so that you know what to expect. There are certain features that most programming languages have in common; variables, loops, conditionals, functions. And there are some features that are unique. If you know what is common in languages that is a good place to start.
Java is an enormous language. There are over 3700 different classes included in the Java 6 Standard Edition. We could not begin to scratch the surface of these classes even if we devoted all 2700 minutes of class time that we have in a semester. However Java is very powerful and we will write some very powerful programs this semester.
A time honored tradition in Computer Science is to write a program called “hello world.” The “hello world” program is simple and easy. There are no logic errors to make, so getting it to run relies only on understanding the syntax. To be clear lets look a a “complicated” version of hello world for Python:
Remember that we can define this program right at the Python command line and then run it:
>>> main()
"Hello World!" >>> |
Now lets look at the same program written in Java:
What we see is that at the core there are a few similarities, such as a main and the string “Hello World” However there is a lot more stuff around the edges that make it harder to see the core of the program. Do not worry! An important skill for a computer scientist is to learn what to ignore and what to look at carefully. You will soon find that there are some elements of Java that will fade into the background as you become used to seeing them. One thing that will help you is to learn a little bit about Java Naming Conventions.
The first question you probably have about this little program is “How do I run it?” Running a Java program is not as simple as running a Python program. The first thing you need to do with a Java program is compile it. The first big difference between Java and Python is that Python is an interpreted language. We could run our Python programs in the Python interpreter and we were quite happy to do that. Java makes running programs a two step process. First we must type the hello world program into a file and save that file using the name Hello.java The file name must be the same as the public class you define in the file. Once we have saved the file we compile it from the command line as follows:
$ javac Hello.java
$ ls -l Hello.* -rw-r--r-- 1 bmiller bmiller 391 Jul 19 17:47 Hello.class -rw-r--r-- 1 bmiller bmiller 117 Jul 19 17:46 Hello.java |
The command javac compiles our java source code into compiled byte code and saves it in a file called Hello.class. Hello.class is a binary file so you won’t learn much if you try to examine the class file with an editor. Hopefully you didn’t make any mistakes, but if you did you may want to consult the Common Mistakes section for helpful hints on compiler errors.
Now that we have compiled our java source code we can run the compiled code using the java command.
$ java Hello
Hello World! $ |
Now you may be wondering what good is that extra step? What does compiling do for us? There are a couple of important benefits we get from compiling:
The job of the compiler is to turn your java code into language that the Java Virtual Machine (JVM) can understand. We call the code that the JVM understands byte code. The JVM interprets the byte code much like the Python interpreter interprets your Python. However since byte code is much closer to the native language of the computer it can run faster.
When the compiler does the translation it can find many different kinds of errors. For example if you make a typo the compiler will find the typo and point it out to you before you ever run the program. We will look at some examples of compiler errors shortly. Chances are you will create some on your own very soon too.
Now that we have run our hello world program, lets go back and look at it carefully to see what we can learn about the Java language. This simple example illustrates a few very important rules:
Lets take the hello world example a line at a time to see how these rules are applied. On line 1 we see that we are declaring a class called Hello. As rule 1 says all Java code resides inside a class. Unlike Python where a program can simply be a bunch of statements in a file, Java programs must be inside a class. So, we define a class, Hello is not a very useful class it has no instance variables, and only one method. You will also notice the curly brace { In Java blocks of code are identified by pairs of curly braces. The block starts with a { and ends with a }. You will notice that I indented my code that followed the left brace, but in Java this is only done by convention it is not enforced.
On the next line we start our method definition. The name of this method is:
public static void main(String[] args)!
|
Everything on this line is significant, and helps in the identification of this method. For example the following lines look similar but are in fact treated by Java as completely different methods:
Just digging in to this one line will take us deep into the world of Java, so we are going to start digging but we are not going to dig too deeply right away. Much of what could be revealed by this one line is better understood through other examples, so be patient.
The first word, public indicates to the Java compiler that this is a method that anyone can call. We will see that Java enforces several levels of security on the methods we write, including public, protected, and private methods.
The next word, static tells Java that this is a method that is part of the class, but is not a method for any one instance of the class. The kind of methods we typically wrote in Python required an instance in order for the method to be called. With a static method, the object to the left of the . is a class, not an instance of the class. For example the way that we would call the main method directly is: Hello.main(parameter1). For now you can think of static methods the same way you think of methods in Python modules that don’t require an instance, for example the math module contains many methods: sin, cos, etc. You probably evaluated these methods using the names math.cos(90) or math.sin(60).
The next word, void tells the Java compiler that the method main will not return a value. This is roughly analogous to omitting the return statement in a Python method. In other words the method will run to completion and exit but will not return a value that you can use in an assignment statement. As we look at other examples we will see that every Python function must tell the compiler what kind of an object it will return. This is in keeping with the rule that says everything in Java must have a type. In this case we use the special type called void which means no type.
Next we have the proper name for the method: main. The rules for names in Java are similar to the rules in Python. Names can include letters, numbers, and the _. Names in Java must start with a letter.
Finally we have the parameter list for the method. In this example we have one parameter. The name of the parameter is args however, because everything in Java must have a type we also have to tell the compiler that the value of args is an array of strings. For the moment You can just think of an array as being the same thing as a list in Python. The practical benefit of declaring that the method main must accept one parameter and the parameter must be a an array of strings is that if you call main somewhere else in your code and and pass it an array of integers or even a single string, the compiler will flag it as an error.
That is a lot of new material to digest in only a single line of Java. Lets press on and look at the next line: System.out.println("Hello World!");. This line should look a bit more familiar to you. Python and Java both use the dot notation for finding names. In this example we start with System. System is a class. Within the system class we find the object named out. The out object is the standard output stream for this program. Having located the out object Java will now call the method named println(String s) on that object. The println method prints a string and adds a newline character at the end. Anywhere in Python that you used the print function you will use the System.out.println method in Java.
Now there is one more character on this line that is significant and that is the ; at the end. In Java the ; signifies the end of a statement. Unlike Python where statements are almost always only one line long java statements can spread across many lines. The compiler knows it has reached the end of a statement when it encounters a ;. This is a very important difference to remember. In Java the following statements are all legal and equivalent. I would not encourage you to write your code like this, but you should know that it is legal.
System.out.println("Hello World");
System.out.println("Hello World") ; System.out.println ( "Hello World" ) ; System. out. println("Hello World") ; |
The last two lines of the hello world program simply close the two blocks. The first or outer block is the class definition. The second or inner block is the function definition.
If we wanted to translate the Java back to Python we would have something like the following class definition.
Notice that we used the decorator @staticmethod to tell the Python interpreter that main is going to be a static method. The impact of this is that we don’t have to, indeed we should not, use self as the first parameter of the main method! Using this definition we can call the main method in a Python session like this:
>>> Hello.main("")
Hello World! >>> |
One of the great things about Python is that all of the basic data types are objects. Integers are objects, floating point numbers are objects, lists are objects, everything. In Java that is not the case. In Java some of the most basic data types like integers and floating point numbers are not objects. The benefit of having these primitive data types be non-objects is that operations on the primitives are fast. The problem is that it became difficult for programmers to combine objects and non-objects in the way that we do in Python. So, eventually all the non-object primitives ended up with Objectified versions.
| Primitive | Object |
| int | Integer |
| float | Float |
| double | Double |
| char | Char |
| boolean | Boolean |
|
|
In older versions of Java it was the programmers responsibility to convert back and forth from a primitive to an object whenever necessary. This processing of converting a primitive to an object was called “boxing.” The reverse process is called “unboxing.” In Java 5, the compiler became smart enough to know when to convert back and forth and is called “autoboxing.” In this book we will typically use the Object version of all the numeric data types and let the compiler do its thing.
Lets go back in time and look at another of our very early Python programs. Here is a simple Python function to convert a Fahrenheit temperature to Celsius.
Next, lets look at the Java Equivalent.
There are several new concepts introduced in this example. We will look at them in the following order:
In Java you can use any class that is available without having to import the class subject to two very important conditions:
You first question might be how do the java and javac commands know that certain classes exist. The answer is the following:
You can think of the import statement in Java as working a little bit like the from module import xxx statement in Python. However, behind the scenes the two statements actually do very different things. The first important difference to understand is that the class naming system in Java is very hierarchical. The full name of the Scanner class is really java.util.Scanner. You can think of this name as having two parts: The first part java.util is called the package and the last part is the class. We’ll talk more about the class naming system a bit later. The second important difference is that it is the Java class loader’s responsibility to load classes into memory, not the import statement’s.
So, what exactly does the import statement do? What it does is tell the compiler that we are going to use a shortened version of the class’s name. In this example we are going to use the class java.util.Scanner but we can refer to it as just Scanner. We could use the java.util.Scanner class without any problem and without any import statement provided that we always referred to it by its full name. As an Experiment you may want to try this yourself. Remove the import statement and change the string Scanner to java.util.Scanner in the rest of the code. The program should still compile and run.
Here is where we run into one of the most important differences between Java and Python. Python is a dynamically typed language. In a dynamically typed language a variable can refer to any kind of object at any time. When the variable is used, the interpreter figures out what kind of object it is. Java is a statically typed language. In a statically typed language the association between a variable and the type of object the variable can refer to is determined when the variable is declared. Once the declaration is made it is an error for a variable to refer to an object of any other type.
In the example above, lines 5—7 contain variable declarations. Specifically we are saying that fahr and cel are going to reference objects that are of type Double. The variable in will reference a Scanner object. This means that if we were to try an assignment like fahr = "xyz" the compiler would generate an error because "xyz" is a string and fahr is supposed to be a double.
For Python programmers the following error is likely to be even more common. Suppose we forgot the declaration for cel and instead left line 6 blank. What would happen when we type javac TempConv.java on the command line?
TempConv.java:13: cannot find symbol
symbol : variable cel location: class TempConv cel = (fahr - 32) * 5.0/9.0; ^ TempConv.java:14: cannot find symbol symbol : variable cel location: class TempConv System.out.println("The temperature in C is: " + cel); ^ 2 errors |
When you see the first kind of error, where the symbol is on the left side of the equals sign it usually means that you have not declared the variable. If you have ever tried to use a Python variable that you have not initialized the second error message will be familiar to you. The difference here is that we see the message before we ever try to test our program. More common error messages are discussed in the section Common Mistakes.
The general rule in Java is that you must decide what kind of an object your variable is going to reference and then you must declare that variable before you use it. There is much more to say about the static typing of Java but for now this is enough.
In the previous section you saw that we created a Scanner object. In Java Scanner objects make getting input from the user, a file, or even over the network relatively easy. In our case we simply want to ask the user to type in a number at the command line, so in line 9 we construct a Scanner by calling the constructor and passing it the System.in object. Notice that this Scanner object is assigned to the name in, which we declared to be a Scanner on line 7. System.in is similar to System.out except of course it is used for input. If you are wondering why we must create a Scanner to read data from System.in when we can write data directly to System.out using println, you are not alone. We will talk about the reasons why this is so later when we talk in depth about Java streams. You will also see in other examples that we can create a Scanner by passing the Scanner a File object. You can think of a scanner as a kind of “adapter” that makes low level objects easier to use.
On line 11 we use the Scanner object to read in a number. Here again we see the implications of Java being a strongly typed language. Notice that we must call the method nextDouble. Because the variable fahr was declared as a double. So, we must have a function that is guaranteed to return each kind of object we might want to read. In this case we need to read a Double so we call the function nextDouble. The compiler matches up these assignment statments and if you try to assign the results of a method call to the wrong kind of variable it will be flagged as an error.
Table 2 shows you some commonly used methods of the scanner class. There are many more methods supported by this class and we will talk about how to find them in the next chapter.
| Return type | Method name | Description |
| boolean | hasNext() | returns true if more data is present |
| boolean | hasNextInt() | returns true if the next thing to read is an integer |
| boolean | hasNextFloat() | returns true if the next thing to read is a float |
| boolean | hasNextDouble() | returns true if the next thing to read is a double |
| Integer | nextInt() | returns the next thing to read as an integer |
| Float | nextFloat() | returns the next thing to read as a float |
| Double | nextInt() | returns the next thing to read as a Double |
| String | next() | returns the next thing to read as a String |
|
|
Of course Java is more well known for producing applications that have more of a user interface to them than reading and writing from the command line. Lets look at a version of our temperature control application that uses dialog boxes for input and output.
This example illustrates a couple of interesting points:
First, the function call JOptionPane.showInputDialog pops up a dialog box to allow you to enter a temperature. But, since you could enter anything into the text input box it returns a String. On the next line the string is converted into a Double by the Double constructor. This is similar to what happens in Python when you call float() with either a string or an integer as the argument.
The next dialog box is JOptionPane.showMessageDialog. Notice that the first parameter is null In Java null serves the same purpose as None in Python. The first parameter is null because we do not have a ‘main window’ for this little application. When we look at creating full blown java programs with user interfaces, we will learn more about this parameter.
The second parameter is "The temperature in C is, " + cel. Now you may be thinking to yourself that this must surely be a violation of the strong typing I have been describing to you. After all you should not be able to add together a string and a Double right? You are correct, however, all java objects have a method called tostring. The tostring method acts much like the Python method __str__() and is called automatically by the compiler whenever it makes sense to convert a Java object to a string.
Strings in Java and Python are quite similar. Like Python, Java strings are immutable. However, manipulating strings in Java is not quite as obvious since Strings do not support an indexing or slicing operator. That is not to say that you can’t index into a Java string, you can. You can also pull out a substring just as you can with slicing. The difference is that Java uses method calls where Python uses Operators.
In fact this is the first example of another big difference between Java and Python. Java does not support any operator overloading. Table 3 maps common Python string operations to their Java counterparts. For the examples shown in the table we will use a string variable called “str”
| Python | Java | Description |
| str[3] | str.charAt(3) | Return character in 3rd position |
| str[2:5] | str.substring(2,4) | Return substring from 2nd to 4th |
| len(str) | str.length() | Return the length of the string |
| str.find('x') | str.indexOf('x') | Find the first occurrence of x |
| str.split() | str.split('\s') | Split the string on whitespace into a list/array of strings |
| str.split(',') | str.split(',') | Split the string at ',' into a list/array of strings |
| str + str | str.concat(str) | Concatenate two strings together |
| str.strip() | str.trim() | Remove any whitespace at the beginning or end |
|
|
Lets look at another early Python program. We are going to read numbers from a file and produce a histogram that shows the frequency of the various numbers. The data file we will use has one number between 0 and 9 on each line of the file. Here is a simple Python program that creates and prints a histogram.
def main():
count = [0]*10 data = open('test.dat') for line in data: count[int(line)] = count[int(line)] + 1 idx = 0 for num in count: print idx, " occured ", num, " times." idx += 1 |
Now if we run this program on a data file that looks like this:
9 8 4 5 3 5 2 1 5
We will get output that looks like this:
0 occurred 0 times
1 occurred 1 times 2 occurred 1 times 3 occurred 1 times 4 occurred 1 times 5 occurred 3 times 6 occurred 0 times 7 occurred 0 times 8 occurred 1 times 9 occurred 1 times |
Lets review what is happening in this little program. In the first line we create a list and initialize the first 10 positions in the list to be 0. Next we open the data file called ‘test.dat’ Third, we have a loop that reads each line of the file. As we read each line we convert it to an integer and increment the counter at the position in the list indicated by the number on the line we just read. Finally we iterate over each element in the list printing out both the position in the list and the total value stored in that position.
To write the Java version of this program we will have to introduce several new Java concepts. First, you will see the Java equivalent of a list, called an ArrayLlist. Next you will see three different kinds of loops used in Java. Two of the loops we will use are going to be very familiar, the third one is different from what you are used to in Python but is easy when you understand the syntax:
Here is the Java code needed to write the exact same program:
Before going any further, I suggest you try to compile the above program and run it on some test data that you create.
Now, lets look at what is happening in the Java source. As usual we declare the variables we are going to use at the beginning of the method. In this example we are declaring a Scanner variable called data, an integer called idx and an ArrayList called count. However, there is a new twist to the ArrayList declaration. Unlike Python where lists can contain just about anything, in Java we let the compiler know what kind of objects our array list is going to contain. In this case the ArrayList will contain Integers. The syntax we use to declare what kind of object the list will contain is the <Type> syntax.
Technically, you don’t have to declare what is going to be on an array list. The compiler will allow you to leave the <Type> off the declaration. If you don’t tell Java what kind of object is going to be on the list Java will give you a warning message like this:
Note: Histo.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details. |
Without the <Integer> part of the declaration Python simply assumes that any object can be on the list. However, without resorting to an ugly notation called casting, you cannot do anything with the objects on a list like this! So, if you forget you will surely see more errors later in your code. (Try it and see what you get)
Lines 13—20 are required to open the file. Why so many lines to open a file in Java? The additional code mainly comes form the fact that Java forces you to reckon with the possibility that the file you want to open is not going to be there. If you attempt to open a file that is not there you will get an error. A try/catch construct allows us to try things that are risky, and gracefully recover from an error if one occurs. The following example shows the general structure of a try catch block.
try {
Put some risky code in here.... like opening a file } catch (Exception e) { If an error happens in the try block an exception is thrown. We will catch that exception here! } |
Notice that in line 16 we are catching an IOException. In fact we will see later that we can have multiple catch blocks to catch different types of exceptions. If we want to be lazy and catch any old exception we can catch an Exception which is the parent of all exceptions.
On line 22 we create our array list and give it an initial size of 10. Strictly speaking it is not necessary to give the ArrayList any size. It will grow or shrink dynamically as needed just like a list in Python. On line 23 we start the first of three loops. The for loop on lines 23–25 serves the same purpose as the Python statement count = [0]*10, that is it initializes the first 10 positions in the ArrayList to hold the value 0.
The syntax of this for loop probably looks very strange to you, but in fact it is not too different from what happens in Python using range. In fact for(Integer i = 0; i < 10; i++) is exactly equivalent to the Python for i in range(10) The first statement inside the parenthesis declares and initializes a loop variable i. The second statement is a Boolean expression that is our exit condition. In other words we will keep looping as long as this expression evaluates to true. The third clause is used to increment the value of the loop variable at the end of iteration through the loop. In fact i++ is Java shorthand for i = i + Java also supports the shorthand i-- to decrement the value of i. Like Python you can also write i += 2 as shorthand for i = i + 2 Try to rewrite the following Python for loops as Java for loops:
The next loop (lines 27–30) shows a typical Java pattern for reading data from a file. Java while loops and Python while loops are identical in their logic. In this case we will continue to process the body of the loop as long as data.hasNextInt() returns true.
Line 29 illustrates another important difference between Python and Java. Notice that in Java we can not write count[idx] =<