41039 · Programming 1
Week 4 · 41039 Programming 1

Methods, Functions and Records

Until now every program has been one long main. This week you break a program into named pieces — methods in Java, functions in Python — and learn exactly how values travel into and out of them. Along the way: what a call does in memory, why a method can change your array but not your int, and Java’s records, the tidy answer to the bundling problem that ended Weeks 2 and 3.

Code comprehension 1 · this week 3 Ed lessons Java Python
Week 4 · Interactive

The lecture, then the practice

Choose a section from the list to open it — or use the arrow keys once the list has focus. Every code example explains itself: hover over an underlined part (or tap it) to see what it does. Run runs it; ✎ Edit opens it in an editor to change it and break it on purpose. Several are meant to fail — read what the compiler says before you fix them.

01What methods are for

1.1Pieces of code with well-defined inputs

You have been calling methods since Week 1 — System.out.println(String), sc.nextInt() — so you already have some idea of the point. A method is a piece of code that takes well-defined inputs and performs some task. You write one when you spot a well-defined task your program is going to do over and over again.

That makes methods the basic unit of code reuse in Java. Because Java is object-oriented, they are also how you interact with classes and objects: a class usually has member variables, and methods mediate access to them. Put another way:

Nouns and verbs

Data are the nouns; methods are the verbs — the actions a class or object can take. And because Java is (almost) strictly object-oriented, a method must be declared inside a class. It cannot float around on its own.

Portrait of Brian Kernighan

Modularize. Use subroutines.

Brian W. Kernighan & P. J. Plauger, The Elements of Programming Style, 2nd ed., 1978, ch. 4 Portrait: Ben Lowe, 2012 · CC BY 2.0

“Subroutine” is the older word for the same idea. Java calls them methods, Python calls them functions, and Fortran — one of the two languages Kernighan and Plauger’s examples are written in — calls them subroutines.

Did you know?

The subroutine had to be invented. Maurice Wilkes, David Wheeler and Stanley Gill, working on Cambridge’s EDSAC, are credited with inventing the closed subroutine around 1951: one copy of the code, jumped to from anywhere, which then jumps back — the jump was long called a “Wheeler jump”. But Alan Turing had already discussed subroutines in his 1945 design proposal for the NPL ACE, going so far as to invent a stack of return addresses — the idea behind section 6. Source: Wikipedia — Function (computer programming), History and David Wheeler (computer scientist).

EDSAC under construction at Cambridge: tall racks of valves and wiring
Photo: Computer Laboratory, University of Cambridge, reproduced by permission · CC BY 2.0

1.2The method header, in five parts

The syntax for declaring a method is possibly the single most complicated piece of syntax in Java, mostly because several parts are optional. A minimal selection to start with — this line is the method’s header (or signature), followed by a block of code in braces:

<access modifier> [static] <return type> <name>(<parameter list>) {
    <code>
}
PartWhat it does
access modifierWho may call it. For now just two: public — any part of the program; private — only the class that contains it (and objects of that class)
[static]Optional (that is what the square brackets mean). Makes the method available from the class, so it can be called without creating an object first
return typeThe type of the value the method gives back when it is done — or void if it gives back nothing
nameSame rules and style as a variable: start lowercase, capitalise each later word, and make it say what the method does — usually a verb or a question: printFactors, isFactor
parameter listA comma-separated list that defines the data passed in. Each entry looks like a variable declaration — because effectively it is one

A concrete example. Enter two numbers:

  1. Both add and main are declared between the braces of Add. Java has no free-standing functions: every method belongs to some class.
  2. The first part of the header. private lets only code inside Add call the method; main is inside Add, so it may.
  3. The method can be called with no object in existence. main is static and runs before any object exists, which is why it can simply write add(n, m).
  4. Every call to add produces an int, so a call can be used anywhere an int value can — here, as the argument to println.
  5. Two parameters, each declared like a variable. a and b exist only inside add, and are created afresh on every call with the values the caller passes in.
  6. return ends the method and gives the value of a + b to the caller. That value is an int, as the header promised.
  7. nextInt reads the next whole number typed in and returns it as an int, which is stored in n. With the input 3 4, n gets 3 and m gets 4.
  8. The arguments are matched to the parameters by position: the value of n is copied into a, m into b. Java runs this inner call first, and println receives the int it returns.

Read the header private static int add(int a, int b) against the table: private, so only Add can use it; static, so main can call it without creating an object; it returns an int; it is called add; and it takes two ints that will be called a and b inside the method — regardless of what they were called outside. Here the caller’s variables are n and m.

1.3main, read the same way

You have typed public static void main(String[] args) since Week 1. Now it can be read part by part:

  1. public — any part of the program can call it.
  2. static — it runs right at the start, when no objects exist yet, so it has to be static.
  3. void — it returns nothing.
  4. main — its name.
  5. String[] args — one parameter, an array of Strings holding the command-line arguments given to the program, if any.

1.4Without static

To see what static is buying you, take it away. The method now belongs to objects of the class, so main has to make one first and call the method on it — the same new you use for a Scanner:

  1. The same header without static. The method now belongs to each object of class Add, so it can only be called on an object.
  2. main runs when no object exists yet, so it has no object to call add on. It must make one before it can use the method.
  3. nextInt is a non-static method of Scanner, which is why you have always called it on an object, sc, rather than on its own.
  4. The class Add can be the type of a variable, just as Scanner is the type of sc. adder will refer to an Add object.
  5. new builds an object of class Add and gives back a reference to it. Add has no member variables, so this object holds no data; it exists only so that add can be called on it.
  6. The object.method(arguments) form, as in sc.nextInt(). The parameters and the returned int work exactly as in the static version, so the program prints the same sum.

Forget the object and call it the old way, and the compiler stops you. Run this one and read the message:

  1. The instance method from 1.4: it belongs to objects of Add, so every call needs an object to be called on.
  2. Nothing in the body of add is wrong. The compiler objects only to the way main calls it.
  3. Inside a static method there is no current object. main belongs to the class and runs before any Add object has been created.
  4. A bare call to a non-static method from static main: there is no object to call it on, so the program does not compile. Fix it by putting static back on line 3 (as in 1.2), or by calling new Add().add(3, 4) (as in 1.4).

The console here says Cannot make a static reference to the non-static method add(int, int); Ed’s javac says non-static method add(int,int) cannot be referenced from a static context. Same complaint: main is static, and there is no object to call add on. Until the classes weeks, make your methods static.

1.5A typical first program with methods, explained

Measuring a flat: three small methods, each with one well-defined task, called again and again from main. Every header has the five parts from 1.2, and the return types cover all three cases — a number, a yes/no answer, and nothing. Point at an underlined part to see what it does, then press Run.

  1. The access modifier. main is inside Flat, so it can call area; code in any other class that tries Flat.area(3, 4) will not compile.
  2. main is static too, so it can call area directly, with no new Flat() first. Leave static off and every call from main fails with Cannot make a static reference to the non-static method.
  3. Two inputs, each written like a variable declaration — because each one is: width and length are variables that exist only inside area.
  4. Ends the method and gives the product to whoever called it. Its type must match the int in the header.
  5. The return type is boolean and the name asks a yes/no question, so if (isLarge(a)) reads like English. Line 8 returns the comparison itself: true or false.
  6. printRoom’s whole job is printing, so there is no value to return. Its calls stand alone as statements; int x = printRoom("Study", 2, 3); would not compile.
  7. The caller’s w and l are matched to width and length by position, not by name. Inside area only the parameter names exist.
  8. public, static (it runs before any object exists), void, the name main, and one parameter: an array of the command-line arguments, unused here.
  9. The printing task is written once and used for three rooms, each call with its own inputs. A fourth room would cost one more line.
03 · This week

What to actually do

On Ed, work through the three Week 4 lessons. This order matches the sections above:

  1. Basics of Methods in Java — sections 1 to 3
  2. Functions in Python — sections 4, 5 and 7.4
  3. Plain Old Data in Java — Record Classes — section 8
Sections 6 and 7 go further than Ed

The Java methods lesson ends by promising more on how parameters relate to values outside the method, once you know how memory is handled. Sections 6 and 7 are that material, for both languages. It is not decoration: it explains every “why did my array change?” question you will have for the rest of the subject.

Code comprehension 1 · 5%

The first code comprehension stage is scheduled for this week, timetabling permitting. You will be asked to explain code, in person. Canvas → Assignments is authoritative for what is due and when; where this page differs, Canvas and the announcements win. Assessed lab exercises are still due 11:55pm the Monday of the following week, and you must pass all test cases in an exercise to get its marks.

If you only do one thing

For every runnable block in section 7, predict the output before you press Run, and say out loud which line mutates and which line rebinds. That habit is most of this week.

Coming up in Week 5: classes, objects and enums — the methods from this week finally get objects to belong to.

Sources

Everything cited on this page

The lecture content comes from the Week 4 lessons on Ed. Sections 6 and 7 extend them; the links below are for those sections and for the claims this page adds around the lessons — checking a source yourself is a better habit than trusting any lecture slide, including ours.

Specifications and documentation

Used inSource
1–3Oracle — Defining Methods, The Java Tutorials
3.3javap java.io.PrintStream on JDK 26 — ten println overloads
6.1, 6.3, 6.4The Java Virtual Machine Specification, Java SE 25, §2.5.2 (JVM stacks, StackOverflowError), §2.5.3 (heap, garbage collector), §2.6 and §2.6.1 (frames, local variables used to pass parameters)
6.3The Java Language Specification, Java SE 25, §4.3.1 — “The reference values (often just references) are pointers to these objects”
7.1The Java Language Specification, Java SE 25, §8.4.1 — “the values of the actual argument expressions initialize newly created parameter variables”
7.2Oracle — Passing Information to a Method or a Constructor — reference parameters “are also passed into methods by value”
4.3, 7.4The Python Tutorial, §4.8 Defining Functions — the None passage, “call by value (where the value is always an object reference …)”, and footnote 1
7.4Python Programming FAQ — How do I write a function with output parameters (call by reference)?
8Oracle — Record Classes, Java SE 21 language guide; JEP 395 — Records; JDK 16 (General Availability 16 March 2021)

Quotations

Every quotation on this page was checked against a primary source — the original book, proposal or documentation, not a quotation website.

Used inSource
1.1Brian W. Kernighan & P. J. Plauger, The Elements of Programming Style, 2nd ed., McGraw-Hill, 1978 — “Modularize. Use subroutines.” (ch. 4)
4.4Guido van Rossum, Jukka Lehtosalo & Łukasz Langa, PEP 484 – Type Hints, created 29 September 2014, section “Non-goals”
7.4The Python Tutorial, §4.8 Defining Functions, footnote 1
8.3JEP 395 — Records, Summary — “transparent carriers for immutable data”, “nominal tuples”

Comics

All by Randall Munroe, xkcd.com, used under CC BY-NC 2.5: 138 (Pointers, 2006) and 221 (Random Number, 2007 — the one the Ed methods lesson uses).

Photographs

From Wikimedia Commons, reused under the licence each one names. Author and licence come from the Commons API rather than from anyone’s memory — see media/fetch-photo.py.

ImageSource
edsacEDSAC (10) — Computer Laboratory, University of Cambridge, reproduced by permission · CC BY 2.0
stack-platesStack of dinner plates — Santeri Viinamäki, 2016 · CC BY-SA 4.0
kernighanBrian Kernighan in 2012 at Bell Labs 1(cropped) — Ben Lowe, 2012 · CC BY 2.0

Articles

Used inSource
1.1Function (computer programming) — History: Wilkes, Wheeler and Gill and the closed subroutine; Turing’s 1945 ACE proposal
1.1David Wheeler (computer scientist) — EDSAC, the closed subroutine around 1951, the “Wheeler jump”