Java doesn't actually have plain functions: all functions must belong to a class, and thus must be methods. Java does this in an effort to enforce object-oriented programming practice. Luckily, this doesn't mean that all methods must have a subject. Methods specified as static
can be called on the class itself instead of instances of the class.
Types are important in Java methods as well as variables. When you create a new method, you have to declare the return type. Here's an example of a static method that returns an integer:
public static int getTwenty() { return 20; }
The parts of the method signature are important:
public
): This sets the accessibility for the method. public
methods can be called by any class, private
methods can be called only from within the class.static
): Means this can be called without an instance of the class as the subject. If the method is not static, just skip to the next part. (We'll see more examples of that later.int
): Specifies the return type of the method. If the method is void (meaning, there's no return value) then put void
here.getTwenty
): The method name. In Java, method names should always be written in camelCase!Notice that the body of the method is indented with respect to the method header, just like in Python. After the body, the close-squiggly brace (indented back with the header line) ends the method. The compiler doesn't actually care whether the body is indented, but other programmers will, so keep up the good indenting practice!
Usually the main method is the last method in a class, so let's add the above method to our code like the following:
public class CodeToRun { public static int getTwenty() { return 20; } public static void main(String[] args) { System.out.println("Hello, World!"); } }
That code should compile happily. Let's change the main method to invoke that method:
public static void main(String[] args) { System.out.println("Hello, World!"); System.out.println("Should be 30: " + (10 + getTwenty()) ); }
Let's write a method that has a parameter. Just like all variables, parameters need to be typed. This method adds five to an integer:
public static int addFiveTo(int x) { return x + 5; }
addFive
can be invoked just like you'd expect:
public static void main(String[] args) { System.out.println("Hello, World!"); System.out.println("Should be 30: " + (10 + getTwenty()) ); int thirteen = addFiveTo(8); System.out.println("Should be 13: " + thirteen); }
Part of the reason Java is a stickler about types is that it prevents some semantic errors and exceptions by enforcing that all the types work out at compile time. Try changing your code by adding another line to our main method:
public static void main(String[] args) { System.out.println("Hello, World!"); System.out.println("Should be 30: " + (10 + getTwenty()) ); int thirteen = addFiveTo(8); System.out.println("Should be 13: " + thirteen); int broken = addFiveTo("A monkey did it!"); System.out.println("broken: " + broken); }
Attempting to compile this gives us an error:
$ javac *.java CodeToRun.java:18: error: method addFiveTo in class CodeToRun cannot be applied to given types; int broken = addFiveTo("A monkey did it!"); ^ required: int found: String reason: actual argument String cannot be converted to int by method invocation conversion 1 error
Notice that the compilation error tells us exactly what's going on: the method requires an int
, but a String
is given there instead.
If we really wanted to define a version of addFiveTo
that takes a string, we can! We can have two different versions of the method with the same name, so long as the signatures are different some other way. Here, we'll give them different parameter types (and return types). Add this method to your code:
public static String addFiveTo(String string) { return string + " five"; }
Since that version of addFiveTo
also says that it returns a String, we'll have to change the type of the variable broken
. Change that line to:
String broken = addFiveTo("A monkey did it!");
Compile and run your method again. You should see:
$ javac *.java $ java CodeToRun Hello, World! Should be 30: 30 Should be 13: 13 broken: A monkey did it! five
Having methods with the same name with different types of parameters is known as method overloading. Since Python is a "weakly typed" language (as opposed to Java, "strongly typed") it doesn't support overloading.
At compile time, Java chooses the method with the appropriate signature. (This does not prevent dynamic method invocation between subclasses. We'll show examples of that later.)
Let's write a method that takes two integer parameters:
public static int addInts(int x, int y) { return x + y; }
Python allows users to multiply integers with strings, like this:
x = 3 * "monkey"
Let's write a method to do it instead! This method takes two parameters of different types (and is also an example of recursion):
public static String repeatString(String string, int amount) { if (amount <=0) { return ""; } else { return string + repeatString(string, amount - 1); } }
We can test it out in our main method:
public static void main(String[] args) { System.out.println("Hello, World!"); System.out.println("Three monkeys: " + repeatString("monkey", 3)); System.out.println("Should be 30: " + (10 + getTwenty()) ); int thirteen = addFiveTo(8); System.out.println("Should be 13: " + thirteen); int broken = addFiveTo("A monkey did it!"); System.out.println("broken: " + broken); }
Compile and run that to make sure everything works.
Rewrite your Monkey class to include a new static void method, printMonkey
. This method should take four parameters: a string (the monkey's name), a boolean (whether or not the monkey is funny), an integer (a count of the monkey's teeth), and a floating-point (the length of the monkey's tail). The static method should print out the same sentence that was previously in your main method. Make two calls to the new method in your main method with very different arguments.