Why use code that someone else wrote?
Every program so far has relied on code you did not write. When you called System.out.println, something displayed the characters on the screen. You did not need to know how: only what to call and what you would get. That idea is called procedural abstraction, and it is why modern programs can be built at all. If every programmer had to write screen drawing, text handling and mathematical functions from scratch, nothing would ever be finished.
The collection of ready-made code is organised in layers:
- A library is a collection of classes.
- Classes in the libraries are grouped into packages, a bit like files into folders.
- A class defines a specific reference type (Topic 1.2), and existing classes can be used to create objects.
- An application programming interface (API) specification informs the programmer how to use those classes. It is documentation: the manual for the library.
Reading API documentation
Documentation found in API specifications and libraries is essential to understanding the attributes and behaviors of a class defined by an API. You do not have to see the code for substring; the documentation tells you everything you need to call it.
A method entry gives four things. Take the entry for one of the String methods:
| Part | In the entry | Meaning |
|---|---|---|
| Return type | String |
the type of value the method gives back |
| Name | substring |
what you write to call it |
| Parameter list | (int from, int to) |
how many values you must give, their types and their order |
| Description | “returns the substring beginning at index from and ending at index to - 1” |
what it does, and what exactly the returned value is |
The first three parts together (return type, name and parameter list) are what you see in a Quick Reference line such as String substring(int from, int to). The description is the contract. If you give the method what it asks for, it does what it says.
On the exam, the Java Quick Reference is provided. It lists accessible library methods with an explanation of each. A very large part of the skill is reading an entry and using it correctly: matching the argument types and order, using the returned value, and knowing what happens at the boundaries.
Attributes and behaviors
Every class describes two things.
- Attributes are the data related to the class, and they are stored in variables. For a
String, the attribute is the sequence of characters it holds. For aScanner, the attributes include the source it reads from and how far it has read. - Behaviors are what instances of the class can do (or what can be done with them), and they are defined by methods. For a
String, behaviors include reporting its length and extracting a part.
When you hold a String object, you can ask it questions and request new strings by calling its behaviors. You usually cannot see or change its attributes directly; you use the methods. This split (data inside, a menu of behaviors outside) is the heart of object-oriented programming, and you will build classes of your own in Unit 3.
Using classes from a library
The Math class and the String class are part of the java.lang package. Classes in the java.lang package are available by default, so you can use them with no extra line of code. A class in another package must be imported.
import java.util.ArrayList;
public class Library {
public static void main(String[] args) {
double h = Math.sqrt(Math.pow(3, 2) + Math.pow(4, 2));
System.out.println(h);
String s = "banana";
System.out.println(s.length() + " " + s.indexOf("a") + " " + s.substring(1, 4));
ArrayList<String> list = new ArrayList<String>();
list.add("one");
System.out.println(list.size());
}
}
5.0
6 1 ana
1
Math and String need nothing extra. ArrayList lives in java.util, so the program begins with an import line. Without it the compiler cannot find the class:
public class NoImport {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
System.out.println(n);
}
}
error: cannot find symbol
Scanner in = new Scanner(System.in);
symbol: class Scanner
(You do not need to recite the import lines for the exam. Knowing why a missing class is reported, and which package a class belongs to, shows that you understand how libraries are organised.)
A routine for using any API entry
New library methods appear on the exam, so it pays to have a routine that works for any entry, not only the ones you have practised. Follow these four steps in order.
- Find the class and decide how the method is reached. Is it a method you call on an object (such as
substringon a string), or one called through the class name (such asMath.sqrt)? Topics 1.10 and 1.14 explain the two forms; for now notice that the entry’s heading and the wordstatictell you which. - Match the parameters. Count the values you must supply, check that each one is compatible with the parameter type, and put them in the order the entry gives. An
intcan fill adoubleparameter, but adoublecannot fill anintparameter without a cast. - Use the return type. If the entry says
double, the call is an expression of typedouble: store it in adouble, use it inside a larger expression, or print it. If the entry saysvoid, there is no value to use (Topic 1.9). - Read the description for special cases. Phrases such as “returns -1 if not found” or “ending at index
to - 1” are the places where a careless reading loses marks.
This routine also guards against a very common mistake: assuming a method changes what it is called on. Reading the documentation of String methods shows that they return new strings; you will see in Topic 1.15 that a String object cannot be changed by calling a method on it.
Finally, remember the purpose of the layers in Figure 1. Because a library is organised into packages and classes, two different classes may have methods with the same name, and the class tells you which one you mean. Math.abs and a method called abs somewhere else are different things; the class name in front of the dot is part of the address.
Worked example 1: Use an API entry to write a call
Task. The Quick Reference includes these Math methods:
static double pow(double base, double exponent): returns the value of the first parameter raised to the power of the second parameter.static double sqrt(double x): returns the nonnegative square root of adoublevalue.
A right-angled triangle has shorter sides 3 and 4. Use these methods to find the hypotenuse.
Step 1, read the entries. Both are static (Topic 1.10 explains why you call them with the class name) and both return a double. pow takes two double parameters, base first and exponent second. sqrt takes one double parameter.
Step 2, plan. The hypotenuse is the square root of 3 squared plus 4 squared.
Step 3, write the call. The arguments 3, 2 and 4 are int values; they are converted to double automatically (Topic 1.5), so they fit the double parameters.
double hyp = Math.sqrt(Math.pow(3, 2) + Math.pow(4, 2));
Step 4, work it out. Math.pow(3, 2) returns 9.0 and Math.pow(4, 2) returns 16.0. Their sum is 25.0, and Math.sqrt(25.0) returns 5.0.
Step 5, check. The result is 5.0 (see the first program above). Notice what you used: only the signature and the description. You did not need to know how pow or sqrt are written.
A trap. Math.pow(3, 2) returns a double (9.0), not an int. Storing it in an int variable without a cast is a compile-time error.
Worked example 2: Classify attributes and behaviors, and choose the method
Task. The String class documentation includes int length(), String substring(int from, int to) and int indexOf(String str), whose description says it “returns the index of the first occurrence of str; returns -1 if not found”. For the string "banana":
(a) State which of these three is an attribute and which are behaviors.
(b) Choose the method and write a call that finds the position of the first "nan".
(c) Write a call that extracts "ana" (the characters from index 1 up to, but not including, index 4).
(d) What would indexOf("x") return?
(a) None of the three is an attribute: all three are behaviors, defined by methods. The attribute of a String is the sequence of characters itself, which these methods read.
(b) indexOf finds a position, so "banana".indexOf("nan") returns 2: the letters are b(0) a(1) n(2) a(3) n(4) a(5), and “nan” starts at index 2.
(c) substring(int from, int to) returns the substring beginning at index from and ending at index to - 1, so "banana".substring(1, 4) returns "ana" (indices 1, 2 and 3).
(d) The documentation says it returns -1 if str is not found, so "banana".indexOf("x") is -1.
public class Docs {
public static void main(String[] args) {
String s = "banana";
System.out.println(s.length());
System.out.println(s.indexOf("nan"));
System.out.println(s.substring(1, 4));
System.out.println(s.indexOf("x"));
}
}
6
2
ana
-1
Check. Each result matches what the description promised. The skill here is to take a documented contract and use it, including the special case the documentation mentions (the -1).
Common misconceptions
- “A library and an API are the same thing.” The library is the code; the API specification is the documentation that explains how to use it.
- “I must see the code of a method to use it.” Documentation is enough. That is procedural abstraction.
- “All library classes are available automatically.” Only
java.langis. Others need animport. - “Attributes are methods.” Attributes are data stored in variables; behaviors are methods.
- “The parameter list tells me what the method returns.” The return type comes before the name; the parameter list is what goes in.
- “If I pass an
intwhere adoubleis needed, I get an error.” Anintis converted to adoubleautomatically. - “I need to memorise the Quick Reference.” It is provided; you need to read it accurately.
Where this leads
Practise with the Topic 1.7 practice questions, recap with the revision notes and tick off the checklist. The next topic, 1.8 Documentation with Comments, turns to the other side of documentation: writing it yourself, as comments, preconditions and postconditions.
Quick questions
What is the difference between a library and an API?
A library is the collection of classes itself, ready to be used. The API (application programming interface) specification is the documentation that tells you how to use those classes: what each class, constructor and method is called, what it needs and what it does or returns.
Do I have to memorise every method in the Java library?
No. The exam provides the Java Quick Reference, which lists the accessible library methods you may meet, with an explanation of each. You need to be able to read an entry and use it correctly, not recite it from memory.
Why do some classes need an import statement and others do not?
Classes are grouped into packages. The java.lang package, which contains String, Math and Integer, is available to every program by default. A class in another package, such as Scanner in java.util, must be imported so that the compiler can find it.
Is System.out.println part of a library?
Yes. println is a method of a library class; you have been using the library since your first program. You do not write how it works, only how to call it, and that is the idea of procedural abstraction.