From lesson 3-3, for (int s : scores) gives s each element of the array in order, one per pass.
The enhanced for is Java's for-each. The variable s takes the value of each element in turn, like Python's for s in scores, and no index is involved.
When the index itself is needed, for writing back into the array or for printing a position, the classic for is the tool instead.
A Python function, translated
Methods exist so a piece of logic is written once, named, and reused. The alternative is the same ten lines pasted in five places, where a bug fixed in four of them lives on in the fifth.
They are also the unit of teamwork. A teammate can call your average method correctly knowing only its one-line signature, without ever reading the body.
In Python:
def square(n): return n * n
In Java, a method declares the type of everything, including what it returns:
static int square(int n) { return n * n; }
Reading left to right: static, which can wait one more lesson, then int as the return type, then square as the name, then (int n) declaring one parameter of type int. A method that returns nothing uses the return type void.
The name plus its parameter types form the method's signature, and the compiler checks every call against it. square("hi") will not compile.
Two methods beside main
One method returns a value, one prints and returns nothing, and calls can nest inside expressions.
public class Main { static int square(int n) { return n * n; } static void greet(String name) { System.out.println("Hi, " + name + "!"); } public static void main(String[] args) { greet("Ada"); System.out.println(square(6)); System.out.println(square(3) + square(4)); } }
Output
Hi, Ada! 36 25
greet("Ada") stands alone as a statement because it returns void and there is nothing to use. square(6) produces a value, so it has to be printed, assigned, or otherwise consumed.
The last line calls square twice and adds the two results, 9 + 16. A method call is an expression like any other, which is what makes small named methods compose into larger ones.
Rules of return
A non-void method must return a value of its declared type on every path through the body. Forget one branch and the compiler reports a missing return statement, which is one more mistake that cannot reach a running program.
static String label(int n) { if (n > 0) { return "positive"; } return "zero or negative"; // required, the if is not enough }
return in a void method simply exits early, like Python's bare return. Parameters are typed as well, so static double average(double a, double b) takes exactly two doubles and rejects anything else.
As for where methods live, write them for now as siblings of main inside the class, each marked static. Order does not matter, and main can call a method defined below it.
A return type is a promise
A method declared static int half(int n) whose body says return n / 2.0; does not compile.
n / 2.0 produces a double, because one side is a double as covered in lesson 2-3, and a double cannot be returned as an int without an explicit cast. The declared return type is a promise the compiler enforces on every path.
There are two honest fixes, and which one is right depends on what the method means:
static int half(int n) { return (int) (n / 2.0); } // truncates static double half(int n) { return n / 2.0; } // keeps the decimal
The cast version discards the half, so half(7) gives 3. The second version returns 3.5 and forces every caller to handle a decimal, which is the right choice when the fraction matters.
A mean and an even test
Two small methods, one returning a double and one returning a boolean.
public class Main { static double average(double a, double b) { return (a + b) / 2; } static boolean isEven(int n) { return n % 2 == 0; } public static void main(String[] args) { System.out.println(average(4, 7)); System.out.println(isEven(10)); } }
Output
5.5 true
average divides by a plain 2, and the result still keeps its decimal because a and b are already doubles. The call passes the ints 4 and 7, which Java widens to doubles automatically since that conversion is safe.
isEven returns the comparison directly, since n % 2 == 0 already is a boolean. Wrapping it in an if that returns true or false would say the same thing in four extra lines. Both methods are marked static so that main, itself static, can call them.