Web/blog/java_3.md

175 lines
9 KiB
Markdown
Raw Normal View History

2019-10-11 23:51:35 +02:00
I've been thinking about how to structure this tutorial a lot, and I decided to teach you all about methods *before* I get into object orientation, so you'll have to wait a little while longer before we get into the real nitty-gritty. To understand this one, you should've already read and understood tutorials 1 and 2. If you haven't, you can get to them by clicking the "Previous Post" button in the navigation bar.
So, here goes!
# Methods
Methods are a way, in programming, to move certain code into a different location where it's more organized and, more importantly, where it can be called multiple times from multiple locations, possibly with different data. You'll see what exactly that means in a minute.
Let's create a simple method in our main class:
```java
public class Main {
public static void main(String[] args) {
// I've omitted the code from the previous tutorials for readability
}
public static void printInfo() {
System.out.println("This is some important information!");
}
}
```
Let's take a look at the `printInfo` method I created. In this tutorial, we'll only be talking about `public` and `static` methods, so you'll just have to take that part for granted for now. Following that, you write `void` and then the name of your method (which can be anything you want), followed by parentheses `()` and then braces `{}`. Similarly to the `if` statement and the `for` loop, the method's content goes between those two curly braces, as I have done in this example with the print statement.
As you can see, all a method is is pretty much a collection of code. At this point, you might've already noticed that that is exactly what the `main` structure we've previously been writing all of our code into is: `main` is just another method.
To *call* a method, that is to have the code inside of it be executed, all you have to do is write the following:
```java
public class Main {
public static void main(String[] args) {
// I've omitted the code from the previous tutorials for readability
printInfo();
}
public static void printInfo() {
System.out.println("This is some important information!");
}
}
```
There you go.
## Variables
It should be noted at this point that variables which are declared *inside* of a method, like the ones we've been using in the first two tutorials, are known as `local variables`. What this means is that they only exist *inside* of the method they are declared in. Check out this example:
```java
// This method declares a variable i that is set to 0
public static void methodOne() {
int i = 0;
}
// This method declares a *different* variable i that is set to 1
public static void methodTwo() {
int i = 1;
}
// This method will cause an error if you paste it into your IDE:
// You cannot declare two variables with the same name in one method.
public static void erroringMethod() {
int i = 0;
int i = 1;
}
```
This same behavior also counts for `if`, `for` and any other curly braces `{}` that you see: They close off any variables which are created inside of them and make them available to only that location.
# Parameters
Now you might be wondering what the point of methods is if all they do is execute a predefined list of code. Well... you can actually make a method *accept* a set of data that they can use to do their processing. The data given to a method is called *parameters*, and these parameters are simply variables that you declare between the method's parentheses `()` right after its name.
Let's take the following example:
```java
public static void printInfo(String strg) {
System.out.println("This is some important information about " + strg);
}
```
I modified the method by adding the parameter `strg` to it, which is of the type `String`. What this means is that now, when calling the method, it expects you to give it a string that it can use to do stuff with (in this case, print it out).
If you add that parameter to the code we previously wrote, you might notice that your IDE is now displaying an error to you. You can't just do this anymore:
```java
public static void main(String[] args) {
printInfo();
}
```
As we just said, `printInfo` now wants us to give it a string whenever we call it. To give it that string, simply put it between the parentheses `()` of your method call like this:
```java
String someString = "Some String";
printInfo(someString);
// or, optionally, the shorter form:
printInfo("Some String");
```
Running your code now should cause `This is some important information about Some String` to be displayed in your console.
In case you're thinking "I've seen that somewhere before", then you would be correct: This is exactly the same thing you do when you try to print something out to the console: You call the `println` method and give it the text you want to print out as the parameter.
The cool thing is that a method can also accept *multiple* parameters, so multiple bits of data can be passed into it when calling it. Let's look at this example:
```java
public class Main {
public static void main(String[] args) {
printInfo("Some String", 5);
}
public static void printInfo(String strg, int amount) {
for (int i = 0; i < amount; i = i + 1) {
System.out.println("This is some important information about " + strg);
}
}
}
```
As you can see, the `printInfo` method now takes two parameters, separated by a comma `,`. The code inside of the method should already be familiar to you: It's a simple for loop that prints the same message `amount` times.
So now, we have something that also demonstrates pretty well the versatility of methods: We can now call `printInfo` with any information that will be printed any amount of times:
```java
printInfo("Some String", 5);
printInfo("Some other String", 10);
```
# Returning
Another thing that methods can do that is really useful is the ability to *return* certain data. What this means is that they can, after their execution finishes, take the data they created or modified and give it back to the caller:
```java
public class Main {
public static void main(String[] args) {
int tenSquared = square(10);
System.out.println(tenSquared); // prints 100
System.out.println(square(5)); // prints 25
}
public static int square(int i) {
return i * i;
}
}
```
As you can see, I created a method `square` that returns its parameter `i`, but squared. To make a method return a value, two things have to be done:
- The method's *return type* has to be declared. For methods that don't return anything, the return type is `void`. For methods that return something, just replace `void` with the *type of variable* that it returns.
- To actually return a specific value after it has been calculated, just type `return`, followed by the value and a semicolon `;`.
Now, this method can be used as if it were just another number: We can set variables to it and print it out. But instead of it being just another number, it actually executes the code inside it every time.
## Stopping execution
A thing that should be noted about returning is that any code that comes after a return statement will *not* be executed. In other words: After returning a value, a method will stop its execution, no matter what comes next.
```java
public static int square(int i) {
return i * i;
System.out.println("This will never be called");
}
```
In this specific case, that isn't really useful - why write code that can never be executed? But take this other example:
```java
public static boolean isIGreaterThanJ(int i, int j) {
if (i > j) {
return true;
}
System.out.println("i is NOT greater than j!");
return false;
}
```
In this example, the print statement will not be executed if `i` is greater than `j` despite the fact that it's not wrapped in an `else`, because the method gets returned out of before it can be called.
## Requirements
If you create a method that has a return type other than `void` (which, again, means "this method doesn't return anything"), then every possible path that the execution can take inside the method *needs* to return *something*.
What this means is that you can't have something like this:
```java
public static boolean isIGreaterThanJ(int i, int j) {
if (i > j) {
return true;
}
System.out.println("i is NOT greater than j!");
}
```
Because when `i` is *not* greater than `j`, the print statement will be executed but then, the method doesn't know what value to return, so this code will give out an error before it even tries to execute.
# Conclusion
So yea, that's pretty much everything important there is to know about (static) methods. In one of the next tutorials, we'll finally get into actual object orientation and we'll soon be taking a look at non-static methods, which are even more useful than static methods.
As a little exercise, you might want to create some methods with different return types and different parameters and call them. Have some fun!
I hope you enjoyed reading, and of course: Happy coding!