Java Syntax and Conventions
This chapter covers some of the basic Java syntax and conventions as well as updates in Java 5 and 6 (1.5 and 1.6).
Java JDK
The core class types included in Java is called the JDK (Java Development Kit). It includes all the basic tools you would need in a modern application, everything from collection types and queues to web sockets to files and image processing.
As an object-oriented language, methods and properties are organized into classes which are organized in packages.
Each Java class should be defined in one file named for that class.
The classes under java.lang such as String are always available, otherwise you need to explicitly import the classes using an import statement
at the top of your Java file.
An instance of a class is called an object.
All objects are passed by reference. Unlike in C you cannot modify a reference pointer.
A particular aspect of Java is that there are special types called “primitives”.
Unlike objects, primitives do not have methods and always have a value (they can never be null).
Primitives and Arrays
Primitive types in Java refer to different ways to store numbers (and have historical but also practical significance):
- char: A single character, such as ‘A’ (the letter A).
- byte: A number from -128 to 127 (8 bits1). Typically a way to store or transmit raw data.
- short: A 16-bit signed integer. It has a maximum of around 32 thousand.
- int: A 32-bit signed integer. Its maximum is around 2 to the 31st power.
- long: A 64-bit signed integer. Maximum of 2 to the 63rd power.
- float: A 32-bit floating point number. This is a non-precise value that is used for things like simulations.
- double: Like float but with 64-bits.
- boolean: Has only two possible values:
trueandfalse(much like 1 bit).
In Java you can define arrays of primitives or classes. For example, String[] strArray = {"a", "b", "c"}; creates an array of three Strings.
Once you define an array, you cannot directly change its length. If you need a list of expanding size, use java.util.ArrayList.
All other types other than primitives and arrays are considered objects.
Classes
To define a new class, create a new file named Classname.java. For example, let’s create a Dragon class in a file named Dragon.java:
1 import java.util.*;
2 public class Dragon {
3 }
In this case the class does not have a package. If it did we would declare it in the first line and the file must be in a directory structure matching the package.
The first line above imports everything in the java.util package. This includes List, ArrayList, Map, and HashMap for example.
Properties and Methods
Next you might want to add some properties and methods to your class. A property is a value associated with a particular object. A method is a block of code on a class.
1 package com.example.mpme;
2 public class SmallClass {
3 String name;
4 String getName() {return name;}
5 void print() {System.out.println(name);}
6 }
In the above code name is a String property and getName and print are methods.
The method getName returns a String (the name) and print uses the built in System class to print out the name to the standard output stream.
Comments
As a human, it is sometimes useful for you to leave notes in your source code for other humans and even for yourself later. We call these notes comments. You write comments thusly:
1 String gold = "Au"; // this is a comment
2 String a = gold; // a is now "Au"
3 String b = a; // b is now "Au"
4 b = "Br";
5 /* b is now "Br".
6 this is still a comment */
Those last two lines demonstrate multiline comments. So in summary:
- Two forward slashes denote the start of a single-line comment.
- Slash-asterisk marks the beginning of a multiple-line comment.
- Asterisk-slash marks the end of a multiple-line comment.
Java 5
Java 5 added several new features to the language. If you’re not familiar with Java 5 or would like a refresher, keep reading. We’re going to assume you understand these concepts in the remainder of the book.
Java 5 added the following features:
- Generics
- Annotations
- More concise
forloops - Static imports
- Autoboxing/unboxing
- Enumerations
- Varargs
- Concurrency utilities in package
java.util.concurrent
Generics
Generics were a huge addition to the language. They improved the type-safety of Java, but also added a lot of complexity to the language.
Generics are used most commonly to specify what type a Collection holds. This reduces the need for casting and improves type-safety.
For example, declaring a List of Strings is the following:
1 List<String> strings = new ArrayList<String>();
Declaring a Map of Long to String would appear as the following:
1 Map<Long,String> map = new HashMap<Long,String>();
The need to repeat the generic type twice in the declaration is one of Java’s harshest criticisms. However various libraries, such as Google’s guava, make this less painful by using static methods. For example declaring the above map would be as simple as the following:
1 Map<Long,String> map = Maps.newHashMap();
Also, Java 7 will ameliorate this situation with the diamond operator, which we will discuss later.
Annotations
Java annotations allow you to add meta-information to Java code that can be used by the compiler, various API’s, or even your own code at runtime.
The most common annotation you will see is the @Override annotation which declares to the compiler that you are overriding a method.
This is useful because it will cause a compile-time error if you mistype the method name for example.
Other useful annotations are those in javax.annotation such as @Nonnull and @Nonnegative which declare your intentions.
Annotations such as @Autowired and @Inject are used by direct-injection frameworks like Spring and Google Guice,
respectively, to reduce “wiring” code.
More concise for loops
You can write for loops in a concise way for an array or any class that implements Iterable. For example:
1 String[] strArray = {"a", "b", "c"};
2 for (String str : strArray)
3 out.println(str);
“Wait, don’t you need a System there?” you’re probably thinking. Not necessarily in Java 5 with the static import feature.
Static import
In Java 5 you can use the words import static to import a static member of another class.
This can help your code be more concise as shown in the above section.
To do this, you would need the following at the top of the class file:
1 import static java.lang.System.out;
However, the creators of Java recommend you use static import very sparingly, so don’t get carried away.
Autoboxing, Enums, Varargs
- Autoboxing
- The Java compiler will automatically wrap a primitive type in the corresponding object when it’s necessary. For example, when assigning a variable or passing in parameters to a function, as in the following:
printSpaced(1, 2, 3) - Unboxing
- This is simply the reverse of Autoboxing. The Java compiler will unwrap an object to the corresponding primitive type when possible.
For example, the following code would work:
double d = new Double(1.1) + new Double(2.2) - Enums
- The
enumkeyword creates a typesafe, ordered list of values. For example,enum Letter { A, B, C; } - Varargs
- You can declare a method’s last parameter with an elipse (
...) and it will be interpreted to accept any number of parameters (including zero) and convert them into an array in your method. For example, see the following code:void printSpaced(Object… objects) { for (Object o : objects) out.print(o + “ “); }
Putting it all together, you have the following code (with output in comments):
1 printSpaced(Letter.A, Letter.B, Letter.C); // A B C
2 printSpaced(1, 2, 3); // 1 2 3
Java 6
Java 6 did not have as many big changes as Java 5, but it did add the following:
- Web Services - First-class support for writing XML web services.
- Scripting - the ability to plug-in scripting engines (for Javascript, Ruby, and Groovy for example).
- Java DB (Apache Derby) is co-bundled in the JRE.
- JDBC 4.0 adds many feature additions like special support for XML as an SQL datatype and better integration of Binary Large OBjects (BLOBs) and Character Large OBjects (CLOBs).
- More Desktop APIs - SwingWorker, JTable, and more.
- Monitoring and Management - Jhat for forensic explorations of core dumps.
- Compiler Access - The compiler API opens up programmatic access to javac for in-process compilation of dynamically generated Java code.
- Override interface methods - The @Override annotation can be used to declare you’re overriding an interface method.