slanted W3C logo

Day 06—APIs

Today's class lays the foundation for reading the standard Java API documents.

Reading Method Headers

Let's look at one of the methods named min in the utility java.Math:

public static long min(long a, long b)
Returns the smaller of two long values.

The statement public static long min(long a, long b) is called the method header.

Reading Method Headers

public static long min(long a, long b)
Returns the smaller of two long values.

The keyword public is called an access modifier. Remember that only public (and protected) features appear in an API, so I will usually drop the keyword public from documentation examples.

Reading Method Headers

public static long min(long a, long b)
Returns the smaller of two long values.

The keyword static indicates that the method is associated with a class. To invoke a static method you use the name of the class followed by a period followed by the method name.

If the keyword static is missing then you need to use the name of an object (instead of the class name) to invoke the methd.

Reading Method Headers

public static long min(long a, long b)
Returns the smaller of two long values.

The keyword long (after static) indicates that this method returns a value of type long back to the client.

The keyword void is used to indicate that the method returns nothing back to the client.

Reading Method Headers

public static long min(long a, long b)
Returns the smaller of two long values.

The identifier (or name) min is the method name.

Reading Method Headers

public static long min(long a, long b)
Returns the smaller of two long values.

The parentheses contain the parameter list of the method. In this case, the method takes as input two parameters both of type long.

Parameters refers to the list of variables in a method declaration. Arguments are the actual values that the client passes to the method when the client invokes the method.

When you invoke a method, the arguments used must match the declaration's parameters in type and order.

Mini Quiz

Which of the following methods are associated with a class (invoked using the name of the class)?

static boolean disjoint(Collection c1, Collection c2)

void setIcon(Icon newIcon)

String toString()

static int round(double a)

static void showMessageDialog(Component parent, Object message)

All of the methods with the keyword static in the header are associated with a class.

Mini Quiz

What is the return type for each of the following methods?

static boolean disjoint(Collection c1, Collection c2)

void setIcon(Icon newIcon)

String toString()

static int round(double a)

static void showMessageDialog(Component parent, Object message)

boolean
void
String
int
void

Mini Quiz

What are the names of each of the following methods?

static boolean disjoint(Collection c1, Collection c2)

void setIcon(Icon newIcon)

String toString()

static int round(double a)

static void showMessageDialog(Component parent, Object message)

disjoint
setIcon
toString
round
showMessageDialog

Mini Quiz

How many parameters do each of the following methods take and what are their types?

static boolean disjoint(Collection c1, Collection c2)

void setIcon(Icon newIcon)

String toString()

static int round(double a)

PrintStream printf(String format, Object... args)

  • 2; Collection and Collection
  • 1; Icon
  • 0
  • 1; double
  • at least 1; one String and zero or more Objects

Contracts

contract
a binding agreement

In software engineering, the notion of a contract is used as a metaphor for the design and documentation of software components. For example, when a client decides to invoke a method on a utility class we can think of the client and the utility class as entering into a contract.

Contracts: Client Obligations

The client has certain obligations:

  • supply the correct number and types of arguments in the correct order
  • ensure that any preconditions on the values of the arguments are met

Contracts: Method Obligations

The method also has certain obligations:

  • perform the action that it advertises
  • return a value of the type it advertises (if any)
  • inform the client of any errors

Preconditions

precondition
something that must be true immediately before the method is invoked

Many methods have parameters; that is, they require the client to supply arguments (data) to the method. Often, the method will have conditions attached to the parameters. For example, the fictitious method:

double squareRoot(double x)

might require that the parameter x always be greater than or equal to positive zero. Such a condition is called a precondition, because it must be true before the method can be successfully invoked.

It is the client's responsibility to ensure that the precondition is true. If the client fails to ensure the precondition, then there are no guarantees on the behavior of the method.

Preconditions


Celine says, "?"

Postconditions

postcondition
something that must be true immediately after the method returns

If the client satisfies the preconditions then the method must meet its contractual obligations. Satisfying the postconditions is the responsibility of the method.

Example with Precondition

double squareRoot(double x)
Returns the positive square root of a double value.

Parameters:
x – a value

Precondition:
x >= 0.0

Returns:
the positive square root of x

Postcondition:
the return value is as stated above

Remember that the method has no obligations if the precondition is false.

Example without Precondition 1

double squareRoot(double x)
Returns the positive square root of a double value.

Parameters:
x – a value

Precondition:
true

Returns:
the positive square root of x

Postcondition:
the return value is as stated above if x >= 0.0;
the return value is NaN otherwise

In this case, the client has to obey no preconditions, and the method promises to handle negative value gracefully.

Example without Precondition 2

Normally we omit the Precondition section if there are no preconditions.

Normally, the Postcondition section is merged with the Returns section.

double squareRoot(double x)
Returns the positive square root of a double value.

Parameters:
x – a value

Returns:
the positive square root of x if x >= 0.0;
NaN otherwise

Introducing Exceptions

Notice that computing the positive square root of a value requires that the value be greater than or equal to 0.0; this condition can be verified inside the squareRoot method at runtime.

One way to deal with the case where a client asks for the square root of a negative value is to indicate to the client that an error has occurred. The mechanism for doing so in Java is called an exception.

When an exception occurs, the method stops executing (i.e. it does not return a value) and the Java runtime system checks to see if the client has written some code to handle the exception; if not, the program will terminate (with some sort of error message hopefully).

We study exceptions in detail in Chapter 11.

Example with Exceptions

A method that might throw an exception when it detects an error will advertise this fact in its API. For example:

double squareRoot(double x)
Returns the positive square root of a double value.

Parameters:
x – a value

Returns:
the positive square root of x if x >= 0.0;

Throws:
IllegalArgumentException if x < 0.0

All methods in the Java Standard Library take this approach (no preconditions, and exceptions for error handling).

Validating Arguments

Even though a method may have no preconditions, it is often a good idea to validate the values of any arguments you pass to a method when you cannot trust the source of the values.

Why might you have values that you cannot trust?

Validating User Input

Failure to validate user input is a common cause of computer security breaches:

Validating User Input Using type.lib.ToolBox

Suppose you want to make sure that some user supplied input value is greater than or equal to zero (the value might represent an amount of money, a quantity, etc.).

import type.lib.ToolBox;
import java.util.Scanner;

public class PositiveInput
{
   public static void main(String[] args)
   {
      Scanner input = new Scanner(System.in);

      System.out.print("Enter the value for ... : ");
      int userValue = input.nextInt();
      ToolBox.crash(userValue < 0, "Input cannot be negative");

      // the rest of your code here
   }
}

The line in red means: if userValue is less than zero then indicate that there is an error, print an error message, and stop the the program.*

* Not exactly, but close enough for now.