In today's class we look at what happens a client invokes a method.
When you invoke a method, the compiler needs to determine if the method exists, if the method has been invoked with the correct argument types, and which version of the method should be used.
The compiler uses 3 steps to determine if a method invocation is correct:
Each step can be complicated. We only sketch what happens in the following slides.
The first step the compiler takes is to deduce the class that contains the method. The compiler does this by looking at the type of the class or object used to invoke the method:
import type.lib.*; public class MethodExample1 { public static void main(String[] args) { Rectangle2.width = 8; Rectangle2.height = 3; int area2 = Rectangle2.getArea(); Rectangle3 rect = new Rectangle3(); rect.width = 5; rect.height = 5; int area3 = rect.getArea(); } }
In the example above, we have two methods named getArea
.
The compiler deduces that the first method invocation belongs to the
class named Rectangle2
(because the name
Rectangle2
was used before the method name).
The compiler deduces that the second method invocation belongs to
the class named Rectangle3
because the object
rect
used to invoke the method has the type
Rectangle3
.
The second step the compiler takes is to deduce which version
of the method is being invoked. This is necessary because
Java allows the implementer to use the same method name
for different versions of the method. Methods in a class that
share the same name are called overloaded methods.
Consider the two methods named nextInt
in java.util.Scanner
:
int nextInt()
int nextInt(int radix)
In the example above, there are two methods named
nextInt
that have a different number
of parameters.
Or consider the family of methods named min
in java.lang.Math
:
static double min(double a, double b)
static float min(float a, float b)
static int min(int a, int b)
static long min(long a, long b)
Here, all of the methods have the same number of parameters but the parameters have different types.
The compiler will search for all methods that are compatible with the method invocation. A compatible method is one that has the same number of parameters as the number of arguments supplied by the client, and the parameter types must match or be compatible with the types of the arguments supplied by the client.
Consider the two methods named nextInt
in java.util.Scanner
:
int nextInt()
int nextInt(int radix)
import java.io.InputStream; import java.io.PrintStream; import java.util.Scanner; public class MethodExample2 { public static void main(String[] args) { InputStream in = System.in; PrintStream out = System.out; Scanner input = new Scanner(in); int first = input.nextInt(); int second = input.nextInt(16); out.print("The first number is: "); out.println(first); out.print("The second number is: "); out.println(second); } }
In the example above, the compiler determines which method to use based on the number of arguments supplied by the client.
Consider the family of methods named min
in java.lang.Math
:
static double min(double a, double b)
static float min(float a, float b)
static int min(int a, int b)
static long min(long a, long b)
public class MethodExample3 { public static void main(String[] args) { double min = Math.min(10.0, 20.0); } }
In the above example, there is only compatible version
of the method named min
, namely
min(double a, double b)
.
public class MethodExample4 { public static void main(String[] args) { int min = Math.min(10, 20); } }
In the above example, all versions
of the method named min
are compatible
based on their signature
because the int
arguments 10
and 20
can be promoted to long
,
float
, or double
.
When there are multiple compatible method signatures, the Java compiler will try to pick the most specific method.
Consider the family of methods named min
in java.lang.Math
:
static double min(double a, double b)
static float min(float a, float b)
static int min(int a, int b)
static long min(long a, long b)
public class MethodExample5 { public static void main(String[] args) { double minDouble = Math.min(10.0, 20.0); int minInt = Math.min(10, 20); } }
static double min(double a, double b)
static float min(float a, float b)
static int min(int a, int b)
static long min(long a, long b)
Which version of min
is selected by the compiler for each
of the following statements?
Math.min( 1F, 2.0F );
Math.min( 1L, 2L );
Math.min( 1, 2L );
Math.min( 1F, 2.0 );
Math.min(float a, float b)
float
Math.min(long a, long b)
long
Math.min(long a, long b)
int
argument can be promoted to
long
but not vice versaMath.min(double a, double b)
float
argument can be promoted to
double
but not vice versaThe final step the compiler performs is to determine if the most specific method is appropriate. One thing that the compiler checks is if a non-static method is called in a static way (which is illegal):
import java.io.InputStream;
import java.io.PrintStream;
import java.util.Scanner;
public class MethodExample6
{
public static void main(String[] args)
{
InputStream in = System.in;
PrintStream out = System.out;
int first = Scanner.nextInt();
}
}
In the example above, the expression in red is illegal
because the method nextInt
is not static and
can only be called using an object.
When you invoke a method, the compiler computes the values of each of the arguments from left to right. The compiler then passes the values (not the variables!) to the method.
Consider the following program:
public class MethodExample7 { public static void main(String[] args) { int x = 10; int y = 20; int z = Math.min(y, x); } }
The method min
receives the values 20
and 10
; it knows nothing about the variables
x
and y
.
Java's mechanism for passing arguments to methods is called pass by value. What is the implication of method only receiving the value of the arguments?
Consider the following hypothetical method in the utility
MakeBelieve
:
static void swap(int a, int b)
Swaps the values of a
and b
.
Parameters:
a
– a value
b
– another value
public class MethodExample8 { public static void main(String[] args) { int x = 10; int y = 20; MakeBelieve.swap(x, y); System.out.print("x : "); System.out.println(x); System.out.print("y : "); System.out.println(y); } }
What does the program print?