Return to Course Content Home

Basic Java Syntax

Required Reading

None

Optional Reading

Learning the Java Language on the Java Tutorial Site. I provide this site as a source of (sometimes) required reading in later chapters, but it is an excellent online resource.

Java Class File

When creating a Java class, you typically put each class in its own source file. In object-oriented programming, you try to come up with descriptive names for each object so that the name really means something to you.

Object oriented design is a computer science class unto itself. How you create objects, where to draw the lines from one object to the next, and how to best re-use them requires both learning and practice. Suffice to say, the best test of an object's design is how much it stands alone without modification as you continue to use it. If you keep having to tweak things, or add more links to other objects, the choice of content may not have been the best. If you can keep using the object over and over, and it does everything you'd expect from an object with that name, you've probably done a good job.

Let's say you want to make an object that represents a person. One of the tricks to object-oriented design is to not try to capture too many things in one object at a time unless it is fundamental to that object.

So, for our person object, you can create a Person class. In Java, objects should begin with capital letters. No spaces are allowed, and by convention if it is a multiple word name, each word begins with a capital letter (e.g. AddressBook for an address book object).

You will define the Person class in a file called Person.java. The name of the file must match the name of the class. All object names, and class names are case sensitive (actually, Windows can be sloppy some times and ignore case, but you shouldn't!) .

Class definition

A java class file consists of three parts.

The first is a package definition. Packages allow you to group (and qualify) objects in a package name. This lets you re-use an object name in a different package. For example, in Java SE 6 and above, there are three classes named Timer, one is java.util.Timer, on is javax.swing.Timer, and one is javax.management.timer.Timer. We'll see later on how to use packages, but you can see how it lets you have a little more flexibility in naming your classes, you don't have to worry about a conflict with a name already in use in another package.

The second (optional) part of a java class file consists of import statements. We'll talk about these later as well.

The third part of a java class is the class definition. This describes what the class does, what it's traits are, and lastly, an optional main method. Method's are the object-oriented terminology for functions, and attributes are object-oriented terminology for object variables. The main method is special because it tells the JVM that if this class is to be run as a stand-alone application, this is the starting point in the code.

Let's take a look at a very simple Java class file.


public class Test

  public static void main(String[] args) {

    System.our.println("Hello world!");

  }

}

The above code defines a class called Test, and it should be located in a file called Test.java. You'll note that there isn't much in this class, no attributes and only a single method called main. When run, all this class will do is print out Hello world! to your console.

Before we go to the next section, read the Java Tutorial on Object-Oriented Programming Concepts.

Object Oriented Concepts

Now that you have read the Java Tutorial on Object-Oriented Programming Concepts, let's talk about a few more things.

First, Java shares some similarities with C++

However, Java has some differences with C++

Objects are used in modern programming to make it easier to comprehend what your program is doing. If chosen well, the objects will "behave" exactly as you would expect them to behave.

Remember, a "Class" means a category of things. It can be used as either a template for creating objects, or as a container for methods that do not rely on an object actual being created. An "Object" refers to a particular item that has been created from a Class template.

Basic Java Syntax

Before we cover some specific examples, please read the Java Tutorial on Language Basics.

As a review on the material you just read, we have the following:

Primitive Types

Primitive types are variables that are just simple numbers, characters or booleans, similar to those found in almost any other programming language. They are not Java Objects, and have no internal methods or attributes. See the Primitive Data Types section of the Java Tutorial for more details.

Primitive Type Description min value max value
byte 8 bit signed two's complement integer -128 127
short 16 bit signed two's complement integer -32,768 32,767
int 32 bit signed two's complement integer -2,147,483,648 2,147,483,647
long 64 bit signed two's complement integer -9,223,372,036,854,775,808 9,223,372,036,854,775,807
float 32 bit floating point number (decimal) n/a n/a
double 64 bit floating point number (decimal) n/a n/a
boolean Boolean data type false true
char 16-bit Unicode Character \u0000 \uffff

The fundamental integer data type in Java in the int, a four-byte, big-endian, two's complement integer.

Strings

In Java, Strings are more than just an array of char values, they are real classes. Since Strings are so common throughout the language, they have a special shortcut "constructor" which is just the double quotes.

As Java Objects, Strings have many useful built-in methods to get substrings, test the contents etc...

Java does a lot to make Strings efficient, and sometimes two Strings are == if they are the same, but sometimes not. That is why you should always use the .equals() method to compare strings. Look at the following code example:


        String foo = "Hello World";

        String bar = "Hello World";

        String baz = "Hello";

        baz = baz + " World";

        System.out.println("foo = " + foo);

        System.out.println("bar = " + foo);

        System.out.println("baz = " + foo);        

        System.out.println("foo.equals(bar)? " + foo.equals(bar));

        System.out.println("foo == bar? " + (foo == bar));

        System.out.println("foo.equals(baz)? " + foo.equals(baz));

        System.out.println("foo == baz? " + (foo == baz));



Produces the following output...



foo = Hello World

bar = Hello World

baz = Hello World

foo.equals(bar)? true

foo == bar? true

foo.equals(baz)? true

foo == baz? false

Note that even though foo and baz are the "same" string and are equal, they are not == because they live as two different Objects, but with the exact same content.

Use the "+" sign for simple string concatenation. If you are concatenating in loops, use a StringBuffer class and then append() the new string onto the old.


String foo = "Grand" + " " + "Tetons";

Produces the string variable containing the String "Grand Tetons". For loops:


StringBuffer buff = new StringBuffer()

for (int i=0; i < 5; i++) {

  buff.append(i);

}

String foo = buff.toString()

This produces the string variable foo containing the String "01234". The StringBuffer class has been around for a while, and is synchronized so it can be used in multiple threads. In JDK 1.5, the StringBuilder class was introduced. It has the same API as StringBuffer but it is not syncrhonized, (which you won't need most of the time) and is therefor faster and more efficient.

Arrays

Arrays are accessed with [], and their indices are 0 based. That means the first element is at index [0]. The length field gives the number of elements in an array.

As you saw earlier when we talked about the
public void static main(String[] args)

statement, we can now examine the args variable using array accessors. args.length gives the number of command line arguments.

If you wanted to print out the values of the command line arguments, the following class would do so:


public class ShowTwoArgs {

  public static void main(String[] args) {

    System.out.println("First arg: " + args[0]);

	  System.out.println("Second arg: " + args[1]);

  }

}

Note that in the above example, you'd better have at least two arguments provided or you will get an ArrayIndexOutOfBoundsException indicating that you are trying to access an index that does not exist.

Before we continue, let us make a ShowTwoArgs class in Eclipse and test it. Create a project example2 and then make a class ShowTwoArgs and insert the code for the main method. When you are done, you should see the following:

Show Two Args

If you right click in the ShowTwoArgs window and select Run File, you will get the following in the output window:

Output with errors

This is because we haven't provided arguments to the class when we run it. That is because when you "run a file" in Eclipse you run one without any optional arguments. You'll need to run the project instead. To do so, right click on the example2 project in the projects window and select Properties.

Project Properties window

Click on the Run/Debug Settings, then loock for the name of your main class (ShowTwoArguments). Select it and the "Edit..." button will enable, click on Edit and you should see the following:

Run/Debug settings window

Click on the Arguments tab and the put your two arguments in the "Program arguments" window. Note that these are just separated by spaces (just like on the command line):

Arguments to Project

Click Ok, and then "Apply and Close" in the original properties dialog.

When you run your application now, you should see the expected results:

Show Two Args with Two Args

Arrays

Arrays have an interesting feature in that you can declare and allocate an array in one simple statement. This means that the following is equivalent.


int[] values = new values[3];

values[0] = 10;

values[1] = 100;

values[2] = 1000;





  is the same as

  

int[] values = {10, 100, 1000};

Note that in the second example, the size of values is never explicitly set, and the pintail values are provided within a set of {}'s.

For more on arrays, read the Java Tutorial on Arrays.

Looping Constructs

There are several different looping constructs within Java. One of the most common is the for loop, which has two forms. The first, more common, form is the following


for (initStatement; continueTest; updateOp) {

}

This lets you initialize local variables (variables seen only within the loop), update them each iteration and perform a test before starting the loop again. As an example, to print out the arguments for your main method that we saw earlier, you would use:


for (int i=0; i < args.length; i++) {

  System.out.println("Arg " + i + " is = " + args[i]);

}

If you want to iterate through a Java Collection, Java SE 6 provides a new alternate form for the "for" loop


for (variable; collection) {

}

Which loops through a collection, assigning the next item in the collection to the variable each loop, and automatically stopping at the end of the collection.

Using the method we just showed, we can use this new form instead.


int i=0;

for (String arg: args) {

    System.out.println("Arg " + i + " is = " + arg);

	  i++;

}

There is no performance difference, it is just a different way of coding the same thing.

Besides the "for" loop, Java provides the "while" and "do" loops, which loop through a series of statements as long as a conditional test is passed.


while (test) {

   // execute statements

}





do {

   // execute statements

}

The only difference is that the do loop always executes its group of statements at least once, and then does the test.

As an example of a while loop:


public static void listNums2(int max) {

  int i = 0;

  while (i <= max) {

    System.out.println("Number: " + i);

    i++; // "++" means "add one"

  }

}

This while loop produces the following output when the number 5 is passed as the argument:


Number: 0

Number: 1

Number: 2

Number: 3

Number: 4

If statements

"if" statements allow you to make decisions within your code. They can be chained or nested to produce whatever level of complexity you wish to obtain.

The first form of the "if" statement is a single test:


if (boolean-expression) {

  statement;

}

This performs a test, and if the test is true, performs the statements contained within the {}'s following the test. It is true that if you have a single line of code after the test, the {}'s are not required, but this is very bad coding style and you should always use the {}'s after the test in an "if" statement.

The second form of the "if" statement is still a single test, but there is a second grouping of code that is executed if the test fails. This is referred to as an "if-then-else" statement


if (boolean-expression) {

  // statements to be executed if boolean expression is true

} else {

  // statements to be executed if boolean expression is false

"if" statements can be combined and chained


if (boolean-expression) {

  // statements to be executed if boolean expression is true

} else if (second-expression {

  // statements to be executed if second boolean expression is true

} else {

  // statements to be executed if neither expression is true

}

Boolean operators

Operator Use
== Equality, are these the exact same object in memory (not to be confused with equals() method)
!= No Equals
<. <=, >, >= Numerical less than, less than or equals, greater than, greater than or equal
&&. || Logical AND and OR.
! Logical negation

There are two things to consider when using logical operators. The first has to do with the == method. Use the == method if you want to test if two primitive types are equal or if two Objects point to the exact same location in memory. Use the equals() method to see if two Objects are to be considered equal even if they have different memory locations. This is always significant when comparing String objects. NEVER use ==, use the equals() method with Strings.

The other item is that with the logical && and || operators, each boolean expression is evaluated. If the result of that expression fulfill the test, the next expression is not executed. For example, if you wanted to test for a String of characters greater than 5, you might want to make sure the String is not null first before trying to call the length.


String foo=null;

... some code which might set foo ...

if ((foo != null) && foo.length() > 5) {

   ... some more code...

}

This test first checks to see if foo != null, if it isn't Java knows the && test will fail so it stops evaluating tests in the clause, the foo.length() statement is never executed (if it were, it would have thrown an exception if foo was null).

For a more detailed description of the equality and relation operators, read The Java Tutorial on Equality, Relational and Conditional Operators. There is also an excellent section on Control Flow Statements that cover more on if-then, for and while statements.

Basic Mathematical Routines

For a description of the basic operators, read The Java Tutorial on Operators.

Reading Simple Input from the main arglist

At this point we've seen how to create a program, print some output, and do some tests, but you may have asked yourself "if the arguments to a program are an array of Strings, how do I get numbers in to the program?"

Ahh...good question. It turns out that Java has several number classes that are more than happy to turn those Strings into something more useful.

We've just covered some of the primitive types, short, int, etc... It turns out that there are Java classes that can be used to represent these primitive types. For example, there is an Integer class that represents an Integer value, but there are several methods attached to this class. Why not use Integer all of the time? Because it uses much more memory than the primitive type, so only use it when you need it.

In earlier versions of Java you had to manually convert between an int and an Integer.


int i = 5;

Integer myInt = new Integer(i);

int other_i = myInt.intValue();

In JavaSE 5 and on, there is something called "autoboxing" which will automatically convert on to the other.


int i = 5;

Integer myInt = i;

int other_i = myInt;

Autoboxing automatically converts the Integer class to an int and vice-versa.

Where were we going with this? It turns out that the Number classes all have parse methods to turn a string into that type of value. So, if you wanted to turn the first argument to your class into an int, you would do the following:


public static void main(String[] args) {

   int x = Integer.parseInt(args[0]);

}

A lot is going on here. Integer.parseInt() returns an Integer value, but the autoboxing feature allows me to directly assign it to an int value. What if the value passed to parseInt() isn't an Integer? Well, that leads us to exceptions, which we'll cover in the next section.

System Properties

Java tries not to interract directly with the OS too much, but there are some things you just have to know about the user's machine and evironment some times. There is a java.lang.System class that allows you to get information about the user's environment. In particular, there is a getProperty() method on System that lets you query the system for specific traits.

The folllowing is from the JDK API:

Key
Description of Associated Value
java.version Java Runtime Environment version
java.vendor Java Runtime Environment vendor
java.vendor.url Java vendor URL
java.home Java installation directory
java.vm.specification.version Java Virtual Machine specification version
java.vm.specification.vendor Java Virtual Machine specification vendor
java.vm.specification.name Java Virtual Machine specification name
java.vm.version Java Virtual Machine implementation version
java.vm.vendor Java Virtual Machine implementation vendor
java.vm.name Java Virtual Machine implementation name
java.specification.version Java Runtime Environment specification version
java.specification.vendor Java Runtime Environment specification vendor
java.specification.name Java Runtime Environment specification name
java.class.version Java class format version number
java.class.path Java class path
java.ext.dirs Path of extension directory or directories
os.name Operating system name
os.arch Operating system architecture
os.version Operating system version
file.separator File separator ("/" on UNIX)
path.separator Path separator (":" on UNIX)
line.separator Line separator ("\n" on UNIX)
user.name User's account name
user.home User's home directory
user.dir User's current working directory

For example, System.getProperty("line.separator") returns a String object containing the appropriate line separator sequence for the platform the JVM is running is. Unix/Linux has one pattern, Windows another, and Mac's used to have another still (although since they are now *nix based, they use the same as Unix/Linux).