Navigate Classes and Objects topic: v  d  e )

Fundamentals

edit

Every class in Java can be composed of the following elements:

  • fields, member variables or instance variables — Fields are variables that hold data specific to each object. For example, an employee might have an ID number. There is one field for each object of a class.
  • member methods or instance methods — Member methods perform operations on an object. For example, an employee might have a method to issue his paycheck or to access his name.
  • static fields or class fields — Static fields are common to any object of the same class. For example, a static field within the Employee class could keep track of the last ID number issued. Each static field exists only once in the class, regardless of how many objects are created for that class.
  • static methods or class methods — Static methods are methods that do not affect a specific object.
  • inner classes — Sometimes it is useful to contain a class within another one if it is useless outside of the class or should not be accessed outside the class.
  • Constructors — A special method that generates a new object.
  • Parameterized types — Since 1.5, parameterized types can be assigned to a class during definition. The parameterized types will be substituted with the types specified at the class's instantiation. It is done by the compiler. It is similar to the C language macro '#define' statement, where a preprocessor evaluates the macros.
  Code listing 4.1: Employee.java
public class Employee {              // This defines the Employee class.
                                     // The public modifier indicates that
                                     // it can be accessed by any other class

    private static int nextID;       // Define a static field. Only one copy of this will exist,
                                     // no matter how many Employees are created.

    private int myID;                // Define fields that will be stored  
    private String myName;           // for each Employee. The private modifier indicates that
                                     // only code inside the Employee class can access it.
 
    public Employee(String name) {   // This is a constructor. You can pass a name to the constructor
                                     // and it will give you a newly created Employee object.
        myName = name;
        myID = nextID;               // Automatically assign an ID to the object
        nextID++;                    // Increment the ID counter
    }
 
    public String getName() {        // This is a member method that returns the
                                     // Employee object's name.
        return myName;               // Note how it can access the private field myName.
    }
 
    public int getID() {             // This is another member method.
   
        return myID;  
    }
 
    public static int getNextID() {  // This is a static method that returns the next ID
                                     // that will be assigned if another Employee is created.
        return nextID;
    }
}

The following Java code would produce this output:

  Code listing 4.2: EmployeeList.java
public class EmployeeList {
    public static void main(String[] args) {

        System.out.println(Employee.getNextID());
 
        Employee a = new Employee("John Doe");
        Employee b = new Employee("Jane Smith");
        Employee c = new Employee("Sally Brown");
 
        System.out.println(Employee.getNextID());
 
        System.out.println(a.getID() + ": " + a.getName());
        System.out.println(b.getID() + ": " + b.getName());
        System.out.println(c.getID() + ": " + c.getName());
    }
}
  Console for Code listing 4.2
0
3
0: John Doe
1: Jane Smith
2: Sally Brown

Constructors

edit

A constructor is called to initialize an object immediately after the object has been allocated:

  Code listing 4.3: Cheese.java
public class Cheese {
  // This is a constructor
  public Cheese() {
    System.out.println("Construct an instance");
  }
}

Typically, a constructor is invoked using the new keyword:

  Code section 4.1: A constructor call.
Cheese cheese = new Cheese();

The constructor syntax is close to the method syntax. However, the constructor has the same name as the name of the class (with the same case) and the constructor has no return type. The second point is the most important difference as a method can also have the same name as the class, which is not recommended:

  Code listing 4.4: Cheese.java
public class Cheese {
  // This is a method with the same name as the class
  public void Cheese() {
    System.out.println("A method execution.");
  }
}

The returned object is always a valid, meaningful object, as opposed to relying on a separate initialization method. A constructor cannot be abstract, final, native, static, strictfp nor synchronized. However, a constructor, like methods, can be overloaded and take parameters.

  Code listing 4.5: Cheese.java
public class Cheese {
     // This is a constructor
     public Cheese() {
          doStuff();
     }

     // This is another constructor
     public Cheese(int weight) {
          doStuff();
     }

     // This is yet another constructor
     public Cheese(String type, int weight) {
          doStuff();
     }
}

By convention, a constructor that accepts an object of its own type as a parameter and copies the data members is called a copy constructor. One interesting feature of constructors is that if and only if you do not specify a constructor in your class, the compiler will create one for you. This default constructor, if written out would look like:

  Code listing 4.6: Cheese.java
public class Cheese {
     public Cheese() {
           super();
     }
}

The super() command calls the constructor of the superclass. If there is no explicit call to super(...) or this(...), then the default superclass constructor super(); is called before the body of the constructor is executed. That said, there are instances where you need to add in the call manually. For example, if you write even one constructor, no matter what parameters it takes, the compiler will not add a default constructor. The code listing 4.8 results in a runtime error:

  Code listing 4.7: Cheese.java
public class Cheese {
     public Cheese(int weight, String type) {
          doStuff();
     }
}
  Code listing 4.8: Mouse.java
public class Mouse {
     public void eatCheese() {
             Cheese c = new Cheese(); // Oops, compile time error!
     }
}

This is something to keep in mind when extending existing classes. Either make a default constructor, or make sure every class that inherits your class uses the correct constructor.

Initializers

edit

Initializers are blocks of code that are executed at the same time as initializers for fields.

Static initializers

edit

Static initializers are blocks of code that are executed at the same time as initializers for static fields. Static field initializers and static initializers are executed in the order declared. The static initialization is executed after the class is loaded.

  Code section 4.2: Static initializer.
static int count = 20;
static int[] squares;
static {  // a static initializer
    squares = new int[count];
    for (int i = 0; i < count; i++)
        squares[i] = i * i;
}
static int x = squares[5];  // x is assigned the value 25

Instance initializers

edit

Instance initializers are blocks of code that are executed at the same time as initializers for instance (non-static) fields. Instance field initializers and instance initializers are executed in the order declared. Both instance initializers and instance field initializers are executed during the invocation of a constructor. The initializers are executed immediately after the superclass constructor and before the body of the constructor.