- GUI
- Windows API tutorial
- Introduction to Windows API
- Windows API main functions
- System functions in Windows API
- Strings in Windows API
- Date & time in Windows API
- A window in Windows API
- First steps in UI
- Windows API menus
- Windows API dialogs
- Windows API controls I
- Windows API controls II
- Windows API controls III
- Advanced controls in Windows API
- Custom controls in Windows API
- The GDI in Windows API
- PyQt4 tutorial
- PyQt5 tutorial
- Qt4 tutorial
- Introduction to Qt4 toolkit
- Qt4 utility classes
- Strings in Qt4
- Date and time in Qt4
- Working with files and directories in Qt4
- First programs in Qt4
- Menus and toolbars in Qt4
- Layout management in Qt4
- Events and signals in Qt4
- Qt4 Widgets
- Qt4 Widgets II
- Painting in Qt4
- Custom widget in Qt4
- The Breakout game in Qt4
- Qt5 tutorial
- Introduction to Qt5 toolkit
- Strings in Qt5
- Date and time in Qt5
- Containers in Qt5
- Working with files and directories in Qt5
- First programs in Qt5
- Menus and toolbars in Qt5
- Layout management in Qt5
- Events and signals in Qt5
- Qt5 Widgets
- Qt5 Widgets II
- Painting in Qt5
- Custom widget in Qt5
- Snake in Qt5
- The Breakout game in Qt5
- PySide tutorial
- Tkinter tutorial
- Tcl/Tk tutorial
- Qt Quick tutorial
- Java Swing tutorial
- JavaFX tutorial
- Java SWT tutorial
- wxWidgets tutorial
- Introduction to wxWidgets
- wxWidgets helper classes
- First programs in wxWidgets
- Menus and toolbars in wxWidgets
- Layout management in wxWidgets
- Events in wxWidgets
- Dialogs in wxWidgets
- wxWidgets widgets
- wxWidgets widgets II
- Drag and Drop in wxWidgets
- Device Contexts in wxWidgets
- Custom widgets in wxWidgets
- The Tetris game in wxWidgets
- wxPython tutorial
- Introduction to wxPython
- First Steps
- Menus and toolbars
- Layout management in wxPython
- Events in wxPython
- wxPython dialogs
- Widgets
- Advanced widgets in wxPython
- Drag and drop in wxPython
- Internationalisation
- Application skeletons in wxPython
- The GDI
- Mapping modes
- Creating custom widgets
- Tips and Tricks
- wxPython Gripts
- The Tetris game in wxPython
- C# Winforms Mono tutorial
- Java Gnome tutorial
- Introduction to Java Gnome
- First steps in Java Gnome
- Layout management in Java Gnome
- Layout management II in Java Gnome
- Menus in Java Gnome
- Toolbars in Java Gnome
- Events in Java Gnome
- Widgets in Java Gnome
- Widgets II in Java Gnome
- Advanced widgets in Java Gnome
- Dialogs in Java Gnome
- Pango in Java Gnome
- Drawing with Cairo in Java Gnome
- Drawing with Cairo II
- Nibbles in Java Gnome
- QtJambi tutorial
- GTK+ tutorial
- Ruby GTK tutorial
- GTK# tutorial
- Visual Basic GTK# tutorial
- PyGTK tutorial
- Introduction to PyGTK
- First steps in PyGTK
- Layout management in PyGTK
- Menus in PyGTK
- Toolbars in PyGTK
- Signals & events in PyGTK
- Widgets in PyGTK
- Widgets II in PyGTK
- Advanced widgets in PyGTK
- Dialogs in PyGTK
- Pango
- Pango II
- Drawing with Cairo in PyGTK
- Drawing with Cairo II
- Snake game in PyGTK
- Custom widget in PyGTK
- PHP GTK tutorial
- C# Qyoto tutorial
- Ruby Qt tutorial
- Visual Basic Qyoto tutorial
- Mono IronPython Winforms tutorial
- Introduction
- First steps in IronPython Mono Winforms
- Layout management
- Menus and toolbars
- Basic Controls in Mono Winforms
- Basic Controls II in Mono Winforms
- Advanced Controls in Mono Winforms
- Dialogs
- Drag & drop in Mono Winforms
- Painting
- Painting II in IronPython Mono Winforms
- Snake in IronPython Mono Winforms
- The Tetris game in IronPython Mono Winforms
- FreeBASIC GTK tutorial
- Jython Swing tutorial
- JRuby Swing tutorial
- Visual Basic Winforms tutorial
- JavaScript GTK tutorial
- Ruby HTTPClient tutorial
- Ruby Faraday tutorial
- Ruby Net::HTTP tutorial
- Java 2D games tutorial
- Java 2D tutorial
- Cairo graphics tutorial
- PyCairo tutorial
- HTML5 canvas tutorial
- Python tutorial
- Python language
- Interactive Python
- Python lexical structure
- Python data types
- Strings in Python
- Python lists
- Python dictionaries
- Python operators
- Keywords in Python
- Functions in Python
- Files in Python
- Object-oriented programming in Python
- Modules
- Packages in Python
- Exceptions in Python
- Iterators and Generators
- Introspection in Python
- Ruby tutorial
- PHP tutorial
- Visual Basic tutorial
- Visual Basic
- Visual Basic lexical structure
- Basics
- Visual Basic data types
- Strings in Visual Basic
- Operators
- Flow control
- Visual Basic arrays
- Procedures & functions in Visual Basic
- Organizing code in Visual Basic
- Object-oriented programming
- Object-oriented programming II in Visual Basic
- Collections in Visual Basic
- Input & output
- Tcl tutorial
- C# tutorial
- Java tutorial
- AWK tutorial
- Jetty tutorial
- Tomcat Derby tutorial
- Jtwig tutorial
- Android tutorial
- Introduction to Android development
- First Android application
- Android Button widgets
- Android Intents
- Layout management in Android
- Android Spinner widget
- SeekBar widget
- Android ProgressBar widget
- Android ListView widget
- Android Pickers
- Android menus
- Dialogs
- Drawing in Android
- Java EE 5 tutorials
- Introduction
- Installing Java
- Installing NetBeans 6
- Java Application Servers
- Resin CGIServlet
- JavaServer Pages, (JSPs)
- Implicit objects in JSPs
- Shopping cart
- JSP & MySQL Database
- Java Servlets
- Sending email in a Servlet
- Creating a captcha in a Servlet
- DataSource & DriverManager
- Java Beans
- Custom JSP tags
- Object relational mapping with iBATIS
- Jsoup tutorial
- MySQL tutorial
- MySQL quick tutorial
- MySQL storage engines
- MySQL data types
- Creating, altering and dropping tables in MySQL
- MySQL expressions
- Inserting, updating, and deleting data in MySQL
- The SELECT statement in MySQL
- MySQL subqueries
- MySQL constraints
- Exporting and importing data in MySQL
- Joining tables in MySQL
- MySQL functions
- Views in MySQL
- Transactions in MySQL
- MySQL stored routines
- MySQL Python tutorial
- MySQL Perl tutorial
- MySQL C API programming tutorial
- MySQL Visual Basic tutorial
- MySQL PHP tutorial
- MySQL Java tutorial
- MySQL Ruby tutorial
- MySQL C# tutorial
- SQLite tutorial
- SQLite C tutorial
- SQLite PHP tutorial
- SQLite Python tutorial
- SQLite Perl tutorial
- SQLite Ruby tutorial
- SQLite C# tutorial
- SQLite Visual Basic tutorial
- PostgreSQL C tutorial
- PostgreSQL Python tutorial
- PostgreSQL Ruby tutorial
- PostgreSQL PHP tutorial
- PostgreSQL Java tutorial
- Apache Derby tutorial
- SQLAlchemy tutorial
- MongoDB PHP tutorial
- MongoDB Java tutorial
- MongoDB JavaScript tutorial
- MongoDB Ruby tutorial
- Spring JdbcTemplate tutorial
- JDBI tutorial
Methods
In this part of the tutorial, you will learn about Java methods.
In object oriented programming, we work with objects. Objects are the basic building blocks of a program. Objects consists of data and methods. Methods change the state of the objects created. They are the dynamic part of the objects; the data is the static part.
A method is a code block containing a series of statements. Methods must be declared within a class. It is a good programming practice that methods do only one specific task. Methods bring modularity to programs. Proper use of methods bring the following advantages:
- Reducing duplication of code
- Decomposing complex problems into simpler pieces
- Improving clarity of the code
- Reuse of code
- Information hiding
Basic characteristics of methods are:
- Access level
- Return value type
- Method name
- Method parameters
- Parentheses
- Block of statements
Access level of methods is controlled with access modifiers. They set the visibility of methods. They determine who can call the method. Methods may return a value to the caller. In case our method returns a value, we declare its data type. If not, we use the void
keyword to indicate that our method does not return any value. Method parameters are surrounded by parentheses and separated by commas. Empty parentheses indicate that the method requires no parameters. The method block is surrounded with {}
characters. The block contains one or more statements that are executed when the method is invoked. It is legal to have an empty method block.
A method signature is a unique identification of a method for the Java compiler. The signature consists of a method name, and the type and kind (value, reference, or output) of each of its formal parameters. Method signature does not include the return type.
Any legal character can be used in the name of a method. By convention, method names begin with a lowercase letter. The method names are verbs or verbs followed by adjectives or nouns. Each subsequent word starts with an uppercase character. The following are typical names of methods in Java:
- execute
- findId
- setName
- getName
- checkIfValid
- testValidity
Simple example
We start with a simple example.
package com.zetcode; class Base { public void showInfo() { System.out.println("This is Base class"); } } public class ShowInfoMethod { public static void main(String[] args) { Base bs = new Base(); bs.showInfo(); } }
We have a showInfo()
method that prints the name of its class.
class Base { public void showInfo() { System.out.println("This is Base class"); } }
Each method must be defined inside a class. It must have a name. In our case the name is showInfo
. The keywords that precede the name of the method are access specifier and the return type. Parentheses follow the name of the method. They may contain parameters of the method. Our method does not take any parameters.
public static void main(String[] args) { ... }
This is the main()
method. It is the entry point to each console or GUI Java application. The method takes a string array of arguments.
Base bs = new Base(); bs.showInfo();
We create an instance of the Base
class. We call the showInfo()
method upon the object. We say that the method is an instance method. Because it needs an instance to be called. The method is called by specifying the object instance, followed by the member access operator — the dot, followed by the method name.
Method parameters
A parameter is a value passed to the method. Methods can take one or more parameters. If methods work with data, we must pass the data to the methods. We do it by specifying them inside the parentheses. In the method definition, we must provide a name and type for each parameter.
package com.zetcode; class AddValues { public int addTwoValues(int x, int y) { return x + y; } public int addThreeValues(int x, int y, int z) { return x + y + z; } } public class Addition { public static void main(String[] args) { AddValues a = new AddValues(); int x = a.addTwoValues(12, 13); int y = a.addThreeValues(12, 13, 14); System.out.println(x); System.out.println(y); } }
In the above example, we have an AddValues
class which has two methods. One of them takes two parameters, the other one takes three parameters.
public int addTwoValues(int x, int y) { return x + y; }
The addTwoValues()
method takes two parameters. These parameters have int
type. The method also returns an integer to the caller. We use the return
keyword to return a value from the method.
public int addThreeValues(int x, int y, int z) { return x + y + z; }
The addThreeValues()
is similar to the previous method. It takes three parameters.
int x = a.addTwoValues(12, 13);
We call the addTwoValues()
method of the AddValues
object. It takes two values. These values are passed to the method. The method returns a value which is assigned to the x
variable.
Variable number of arguments
Since Java 5, a method can take variable number of arguments. For this we use the ellipsis.
package com.zetcode; public class SumOfValues { public static int sum(int...vals) { int sum = 0; for (int val : vals) { sum += val; } return sum; } public static void main(String[] args) { int s1 = sum(1, 2, 3); int s2 = sum(1, 2, 3, 4, 5); int s3 = sum(1, 2, 3, 4, 5, 6, 7); System.out.println(s1); System.out.println(s2); System.out.println(s3); } }
We create a sum() method which can take variable number of arguments. The method will calculate the sum of integers passed to the method.
int s1 = sum(1, 2, 3); int s2 = sum(1, 2, 3, 4, 5); int s3 = sum(1, 2, 3, 4, 5, 6, 7);
We call the sum()
method three time. In each case, we pass different number of parameters to the method.
public static int sum(int...vals) { ... }
The sum()
method can take variable number of integer values. All values are added to an array.
int sum = 0; for (int val : vals) { sum += val; } return sum;
We compute the sum of the values and return the calculated sum.
$ java com.zetcode.SumOfValues 6 15 28
This is the output of the com.zetcode.SumOfValues
example.
Passing arguments by value
In Java, arguments are always passed by value to methods. When we pass primitive types, the copies of the values are sent to the methods. In case of objects, copies of the references are handed to the methods.
Java does not support passing arguments by reference, like C# or C++ languages.
package com.zetcode; class Cat {} class Dog {} public class PassByValue { private static void tryChangeInteger(int x) { x = 15; } private static void tryChangeObject(Object o) { Dog d = new Dog(); o = d; } public static void main(String[] args) { int n = 10; tryChangeInteger(n); System.out.println(n); Cat c = new Cat(); tryChangeObject(c); System.out.println(c.getClass()); } }
The example shows that it is not possible to change the values of primitive types and the references to objects inside methods.
private static void tryChangeInteger(int x) { x = 15; }
The value of the passed variable is copied to the local variable x
. Assigning a new value to the x
variable does not affect the outside variable.
private static void tryChangeObject(Object o) { Dog d = new Dog(); o = d; }
The same applies for objects. We are passing copies of references to methods. The o is a local variable that refers to the Dog
object. The object defined outside the tryChangeObject()
is not affected.
int n = 10; tryChangeInteger(n); System.out.println(n);
We define the n
variable and pass it to the tryChangeInteger()
method. Later we print it to check if it was modified.
Cat c = new Cat(); tryChangeObject(c); System.out.println(c.getClass());
We define a Cat
object and pass it to the tryChangeObject()
method.
$ java com.zetcode.PassByValue 10 class com.zetcode.Cat
From the output we can see that neither the primitive value nor the object were modified.
Method overloading
Method overloading allows the creation of several methods with the same name which differ in the type of the input.
What is method overloading good for? The Qt4 library gives a nice example for the usage. The QPainter
class has three methods to draw a rectangle. Their name is drawRect()
and their parameters differ. One takes a reference to a floating point rectangle object, another takes a reference to an integer rectangle object, and the last one takes four parameters: x
, y
, width
, and height
. If the C++ language, which is the language in which Qt is developed, didn't have method overloading, the creators of the library would have to name the methods like drawRectRectF()
, drawRectRect()
, drawRectXYWH()
. The solution with method overloading is more elegant.
package com.zetcode; class Sum { public int getSum() { return 0; } public int getSum(int x) { return x; } public int getSum(int x, int y) { return x + y; } } public class Overloading { public static void main(String[] args) { Sum s = new Sum(); System.out.println(s.getSum()); System.out.println(s.getSum(5)); System.out.println(s.getSum(5, 10)); } }
We have three methods called setSum()
. They differ in input parameters.
public int getSum(int x) { return x; }
This one takes one parameter.
System.out.println(s.getSum()); System.out.println(s.getSum(5)); System.out.println(s.getSum(5, 10));
We call all three methods. All methods have the same name. The compiler knows which method to call on the grounds of the method input.
$ java com.zetcode.Overloading 0 5 15
And this is what we get when we run the example.
Recursion
Recursion, in mathematics and computer science, is a way of defining methods in which the method being defined is applied within its own definition. In other words, a recursive method calls itself to do its job. Recursion is a widely used approach to solve many programming tasks. Every problem solved using a recursion can be worked out with the iteration too.
A typical example is the calculation of a factorial.
package com.zetcode; public class Recursion { static int factorial(int n) { if (n == 0) { return 1; } else { return n * factorial(n - 1); } } public static void main(String[] args) { System.out.println(factorial(6)); System.out.println(factorial(15)); } }
In this code example, we calculate the factorial of two numbers.
return n * factorial(n - 1);
Inside the body of the factorial method, we call the factorial method with a modified argument. The function calls itself. This is the essence of the recursion algorithm.
$ java com.zetcode.Recursion 720 2004310016
These are the results.
Method scope
A variable declared inside a method has a method scope. The scope of a name is the region of program text within which it is possible to refer to the entity declared by the name without the qualification of the name. A variable which is declared inside a method has a method scope. It is also called a local scope. The variable is valid only in this particular method.
package com.zetcode; class Test { int x = 1; public void exec1() { System.out.println(this.x); System.out.println(x); } public void exec2() { int z = 5; System.out.println(x); System.out.println(z); } } public class MethodScope { public static void main(String[] args) { Test ts = new Test(); ts.exec1(); ts.exec2(); } }
In the preceding example, we have the x variable defined outside the instance methods. The variable has a class scope. It is valid everywhere inside the definition of the Test
class, e.g. between its curly brackets.
public void exec1() { System.out.println(this.x); System.out.println(x); }
The x variable, also called the x field, is an instance variable. And so it is accessible through the this
keyword. It is also valid inside the exec1()
method and can be referred by its bare name. Both statements refer to the same variable.
public void exec2() { int z = 5; System.out.println(x); System.out.println(z); }
The x variable can be accessed also in the exec2() method. The z
variable is defined in the exec2() method. It has a method scope. It is valid only in this method.
$ java com.zetcode.MethodScope 1 1 1 5
This is the output of the com.zetcode.MethodScope program.
A variable defined inside a method has a local/method scope. If a local variable has the same name as an instance variable, it shadows the instance variable. The instance variable is still accessible inside the method by using the this
keyword.
package com.zetcode; class Test { int x = 1; public void exec() { int x = 3; System.out.println(this.x); System.out.println(x); } } public class Shadowing { public static void main(String[] args) { Test t = new Test(); t.exec(); } }
We declare an instance variable x
. We declare another x
variable inside the exec()
method. Both variables have the same name, but they are not in conflict because they reside in different scopes.
System.out.println(this.x); System.out.println(x);
The variables are accessed differently. The x
variable defined inside the method, also called the local variable, is simply accessed by its name. The instance variable can be referred by using the this
keyword.
$ java com.zetcode.Shadowing 1 3
This is the output of the com.zetcode.Shadowing
example.
Static methods
Static methods are called without an instance of the object. To call a static method, we use the name of the class and the dot operator. Static methods can only work with static variables. Static methods are often used to represent data or calculations that do not change in response to object state. An example is a math library which contains static methods for various calculations. We use the static
keyword to declare a static method or a static variable. When no static modifier is present, the method is said to be an instance method. We cannot use the this
keyword in static methods. It can be used in instance methods only.
package com.zetcode; class Basic { static int id = 2321; public static void showInfo() { System.out.println("This is Basic class"); System.out.format("The Id is: %d%n", id); } } public class StaticMethod { public static void main(String[] args) { Basic.showInfo(); } }
In our code example, we define a static ShowInfo()
method.
static int id = 2321;
A static method can only work with static variables. Static variables are not available to instance methods.
public static void showInfo() { System.out.println("This is Basic class"); System.out.format("The Id is: %d%n", id); }
This is our static ShowInfo()
method. It works with a static Id member.
Basic.showInfo();
To invoke a static method, we do not need an object instance. We call the method by using the name of the class and the dot operator.
$ java com.zetcode.StaticMethod This is Basic class The Id is: 2321
This is the output of the example.
Hiding methods
In case of static methods, a method in the derived class with the same signature as in the base class hides the one in the base class. The method to be called is determined at compile time. This process is referred to as early or static binding.
package com.zetcode; class Base { public static void showInfo() { System.out.println("This is Base class"); } } class Derived extends Base { public static void showInfo() { System.out.println("This is Derived class"); } } public class Hiding { public static void main(String[] args) { Base.showInfo(); Derived.showInfo(); } }
We have two classes. The Derived
and the Base
class. The Derived
class inherits from the Base
class. Both have a method called showInfo()
.
class Derived extends Base { public static void showInfo() { System.out.println("This is Derived class"); } }
The static class method showInfo()
of the Derived
class hides the showInfo()
method of the Base
class.
Base.showInfo(); Derived.showInfo();
We call the showInfo()
method for both classes. Each class calls its own method.
$ java com.zetcode.Hiding This is Base class This is Derived class
This is the output of the com.zetcode.Hiding
example.
Overriding methods
Overriding happens when we create an instance method of a derived class with the same signature and return type as an instance method in the base class. The method to be executed is determined at runtime. The determining of the method to be executed at runtime is called late or dynamic binding.
We might want to use the @Override
annotation that instructs the compiler that we intend to override a method in the superclass. It helps prevent some programming errors.
package com.zetcode; class Base { public void showInfo() { System.out.println("This is Base class"); } } class Derived extends Base { @Override public void showInfo() { System.out.println("This is Derived class"); } } public class Overriding { public static void main(String[] args) { Base[] objs = { new Base(), new Derived(), new Base(), new Base(), new Base(), new Derived() }; for (Base obj : objs) { obj.showInfo(); } } }
We create an array of the Base
and Derived
objects. We go through the array and invoke the showInfo()
method upon all of them.
@Override public void showInfo() { System.out.println("This is Derived class"); }
Here we are overriding the showInfo()
method of the Base
class.
Base[] objs = { new Base(), new Derived(), new Base(), new Base(), new Base(), new Derived() };
Here we create an array of Base
and Derived
objects. Note that we used the Base
type in our array declaration. The Derived
class can be converted to the Base
class, because it inherits from it. The opposite is not true. The only way to have defferent objects in one array is to use a type which is shared by all objects.
for (Base obj : objs) { obj.showInfo(); }
We traverse the array and call showInfo()
on all objects in the array. The method to be called is determined at runtime.
$ java com.zetcode.Overriding This is Base class This is Derived class This is Base class This is Base class This is Base class This is Derived class
This is the output.
Final methods
A final
method cannot be overriden or hidden by derived classes. This is used to prevent unexpected behavior from a subclass altering a method that may be crucial to the function or consistency of the class.
package com.zetcode; class Base { public void f1() { System.out.println("f1 of the Base"); } public final void f2() { System.out.println("f2 of the Base"); } } class Derived extends Base { @Override public void f1() { System.out.println("f1 of the Derived"); } // @Override // public void f2() { // // System.out.println("f2 of the Derived"); // } } public class FinalMethods { public static void main(String[] args) { Base b = new Base(); b.f1(); b.f2(); Derived d = new Derived(); d.f1(); d.f2(); } }
In this example we have a final method f2()
in the Base
class. This method cannot be overriden.
public final void f2() { System.out.println("f2 of the Base"); }
The f2()
method is declared to be final
. No overloading is possible.
@Override public void f1() { System.out.println("f1 of the Derived"); }
In the Derived class, we can override the f1()
method of the Base
class. We also use the @Override
annotation to inform the compiler that we are overriding a method.
// @Override // public void f2() { // // System.out.println("f2 of the Derived"); // }
These lines are commented, because otherwise the code example would not compile. The compiler would give the following error: Exception in thread "main" java.lang.VerifyError: class com.zetcode.Derived overrides final method f2.
d.f2();
Since it is not possible to override a final method, the above line will call the f2()
method of the Base
class.
$ java com.zetcode.FinalMethods f1 of the Base f2 of the Base f1 of the Derived f2 of the Base
This is the output.
In this part of the Java tutorial, we have covered methods.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论