Odds and Ends

The "final" modifier

In addition to public/private/protected and static, Java has a modifier "final". It means different things depending on whether it is used with a class, method or field definition. Its meanings for classes and methods involves inheritance, which we haven't yet studied, but its meaning with fields is pretty straightforward. A field, whether static or not, that is declared "final" never changes after it is given its initial value. So you might say something like:

private static final double PI = 3.14159;
... which means that PI is a double, it's a static field (a single variable PI shared by all instances of the class), it's private (can't be accessed outside of the class), and it's final, which means that it's value can never change from the 3.14159 it was originally assigned.

Initializing static fields (data members)

Non-static fields are initialized by constructors. What about static fields? There are two basic mechanisms for initializing them. The first is to give an initializing expression at the point at which the declaration takes place. E.g. the "= 0" in:

private static int counter = 0;
But that doesn't work when there is code that needs to be executed, not just a simple expression. For this, we can add static initialization blocks or, more simply, we can add a static method and call it as the initializer expression, e.g.:

private static int[] squares = initSquares(10);

private static int[] initSquares(int n) {
  int[] A = new int[n];
  for(int i = 1; i <= n; i++) {
    A[i] = i*i;
  }
  return A;
}

Java style

Java's API is a huge part of any Java program you write, and it follows a very strict set of conventions. Therefore, since we don't want two different sets of conventions running around, we always follow the same conventions in our code. The basics are:

  1. Class names begin with an upper-case letter and otherwise follow "CamelCase" — separate words are squished together, but each new word starts with a capital letter. E.g. TimeOfDay.
  2. Method and field names begin with a lower-case letter and otherwise follow lower camelCase, and the first (or only) word in a method name should be a verb. E.g. growBy.
  3. Constants (e.g. class variables that are declared "static final") are all upper-case with multiple words seperated by an underscore. E.g. static final int NUM_GEARS = 6.
  4. Comments should precede every method and every class definition, at a minimum. Java has a unique way of including comments for methods/classes that you should follow as shown below. The leading asterisks in the middle lines are optional .
    Note: It is not with the // characters:
    import java.util.*;
    import java.lang.*;
    
    /**
     * A generic class for demonstrating how to comment correctly in Java.
     * You should follow it!
     *
     * Sometimes you may see examples with * characters at the beginning
     * of each line.  Those *s are optional!
     * @author McGiffin, Philo
     */
    public class Commenter {
    
      /**
      Returns the String "hellooooo".
      */
      public String toString() {
        return "hellooooo";
      }
    
      /**
      Returns the sum of two numbers.
      */
      public int add(int num1, int num2) {
        return num1 + num2;
      }
    }
    

Java's printf

Sometimes System.out.println( ) is painful to use. The PrintStream (which is what System.out is) also has "printf", which behaves similarly to C's printf. So for example:

public class Ex1 {
  public static void main(String[] args) {
    double x = 0.2373451, y = 1.8021234;
    System.out.printf("%1.3f divided by %1.3f is %1.5f\n",x,y,x/y);
  }
}

produces the following output when run

~/$ java Ex1
0.237 divided by 1.802 is 0.13170
See the documentation for more details.

Primitive wrapper classes

Java distinguishes between primitive types and objects primarily for performance reasons. It complicates things, though. Moreover, you sometimes want a double or an int to behave like an object — for example when you'd like to distinguish between the absence of a value (null) as opposed to a zero value (0 or 0.0). Java has class version of the primitive types, called Primitive wrapper classes. They are class Integer, Double, Character, Byte and Boolean. Objects of these types are immutable (like strings, they cannot be changed). Here's an example that uses the Integer class so that null can signal the absence of a value.

import java.util.*;

public class Ex2 {
  public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    Integer I  = null;

    while (I == null) {
      System.out.print("Enter an integer: ");

      if (!sc.hasNextInt()) {
        sc.nextLine();
      } else {
        I = sc.nextInt();
      }
    }
    System.out.println("You entered " + I);
  }
}
Here's a sample run:

~/$ java Ex2
Enter an integer: I = 23
Enter an integer: twenty
Enter an integer: help?
Enter an integer: 23
You entered 23