Wstęp
Jak wiemy, Java jest językiem programowania zorientowanym obiektowo. To jest podstawowa koncepcja, ponieważ powiedzieć, że podstawą podstaw jest to, że wszystko jest przedmiotem. Obiekty opisywane są za pomocą klas.
Klasy z kolei mają stan i zachowanie. Na przykład konto bankowe może mieć stan w postaci kwoty pieniędzy na koncie i zachowywać się w sposób zwiększający i zmniejszający saldo. Zachowanie w Javie jest implementowane za pomocą metod. Sposób opisywania metod zostanie przedstawiony na samym początku Twojej przygody z nauką języka Java. Na przykład w oficjalnym poradniku firmy Oracle: „
Definiowanie metod ”. Ważne są tutaj dwa aspekty:
- Każda metoda ma swój podpis. Sygnatura składa się z nazwy metody i jej parametrów wejściowych;
- Metody muszą określać typ zwracany;
- Typ zwracany nie jest częścią sygnatury metody.
Ponownie jest to konsekwencja faktu, że Java jest językiem o silnie typowanym typie i kompilator chce z wyprzedzeniem zrozumieć, które typy są używane gdziekolwiek, tak często, jak to możliwe. Jeszcze raz, aby chronić nas przed błędami. Ogólnie rzecz biorąc, wszystko jest na dobre. Cóż, wydaje mi się, że to po raz kolejny zaszczepia w nas kulturę postępowania z danymi. Zatem dla metod określony jest typ wartości. Aby zwrócić tę samą wartość z metod, używane jest słowo kluczowe
return
.
Instrukcja zwrotu słowa kluczowego w Javie
Słowo kluczowe instrukcji
return
odnosi się do „instrukcji przepływu sterowania”, jak omówiono w samouczku Oracle „
Instrukcje przepływu sterowania ”. O tym, jak zwracać wartości, możesz przeczytać także w oficjalnym poradniku: „
Zwracanie wartości z metody ”. Kompilator dokładnie monitoruje, najlepiej jak potrafi, czy wartość zwrócona przez metodę jest zgodna z typem wartości zwracanej określonym przez metodę. Jako przykład użyjmy
Online IDE z tutorialspoint . Spójrzmy na oryginalny przykład:
public class HelloWorld {
public static void main(String []args) {
System.out.println("Hello World");
}
}
Jak widzimy, wykonywana jest tutaj metoda
main
, która jest punktem wejścia do programu. Linie kodu są wykonywane od góry do dołu. Nasza
main
metoda nie może zwrócić wartości, w przeciwnym razie otrzymamy błąd: „
Error: Main method must return a value of type void
”. Dlatego metoda po prostu wyświetli wynik na ekranie. Przenieśmy teraz odbieranie ciągu znaków do osobnej metody odbierania wiadomości:
public class HelloWorld {
public static void main(String []args) {
System.out.println(getHelloMessage());
}
public static String getHelloMessage() {
return "Hello World";
}
}
Jak widać za pomocą słowa kluczowego
return
podaliśmy wartość zwracaną, którą wykorzystaliśmy w dalszej części metody
println
. W opisie (definicji) metody
getHelloMessage
wskazaliśmy, że zwróci nam ona
String
. Dzięki temu kompilator może sprawdzić, czy działania metody są zgodne ze sposobem, w jaki została zadeklarowana. Oczywiście typ wartości zwracanej określony w definicji metody może być szerszy niż typ wartości zwracanej z kodu, tj. Najważniejsze jest to, że typy są do siebie zredukowane. W przeciwnym razie otrzymamy błąd czasu kompilacji: „
error: incompatible types
”. Swoją drogą pewnie od razu pojawiło się pytanie: dlaczego
return
dotyczy to operatorów kontroli przepływu programu? Ale ponieważ może to zakłócić normalny przepływ programu od góry do dołu. Na przykład:
public class HelloWorld {
public static void main(String []args){
if (args.length == 0) {
return;
}
for (String arg : args) {
System.out.println(arg);
}
}
}
Jak widać na przykładzie, przerywamy wykonanie metody,
main
jeśli nasz program w Javie zostanie wywołany bez parametrów. Należy pamiętać, że jeśli wówczas będziesz
return
posiadał kod, stanie się on niedostępny. A nasz inteligentny kompilator to zauważy i nie pozwoli na uruchomienie takiego programu. Na przykład ten kod nie zostanie skompilowany:
public static void main(String []args) {
System.out.println("1");
return;
System.out.println("2");
}
Istnieje brudny sposób na obejście tego problemu. Na przykład w celach debugowania lub z innego powodu. Powyższy kod można naprawić, zawijając go
return
w
if
blok:
if (2==2) {
return;
}
Instrukcja return w obsłudze błędów
Jest jedna bardzo skomplikowana okoliczność - możemy jej użyć
return
w połączeniu z obsługą błędów. Od razu powiem, że używanie go
return
w
catch
bloku jest bardzo, bardzo złą formą, dlatego należy go unikać. Ale potrzebujemy przykładu, prawda? Tutaj jest:
public class HelloWorld {
public static void main(String []args) {
System.out.println("Value is: " + getIntValue());
}
public static int getIntValue() {
int value = 1;
try {
System.out.println("Something terrible happens");
throw new Exception();
} catch (Exception e) {
System.out.println("Catched value: " + value);
return value;
} finally {
value++;
System.out.println("New value: " + value);
}
}
}
Na pierwszy rzut oka wydaje się, że należy zwrócić 2, ponieważ
finally
jest ono zawsze wykonywane. Ale nie, wartość będzie wynosić 1, a zmiana zmiennej in
finally
zostanie zignorowana. Co więcej, gdyby
value
zawierał obiekt i powiedzieliśmy
finally
,
value = null
to
catch
nadal zwracałby referencję do obiektu, a nie
null
. Ale z bloku
finally
operator
return
działałby poprawnie. Koledzy z pewnością nie będą ci wdzięczni za taki prezent.
pusta.klasa
I w końcu. Możesz napisać dziwną konstrukcję, np
void.class
. . Wydawałoby się, dlaczego i o co chodzi? W rzeczywistości w różnych frameworkach i trudnych przypadkach, w których używany jest
interfejs Java Reflection API , może to być bardzo konieczne. Możesz na przykład sprawdzić, jaki typ zwraca metoda:
import java.lang.reflect.Method;
public class HelloWorld {
public void getVoidValue() {
}
public static void main(String[] args) {
for (Method method : HelloWorld.class.getDeclaredMethods()) {
System.out.println(method.getReturnType() == void.class);
}
}
}
Może to być przydatne w frameworkach testowych, gdzie konieczne jest zastąpienie prawdziwego kodu metod. Aby to jednak zrobić, musisz zrozumieć, jak zachowuje się ta metoda (tj. jakie typy zwraca). Istnieje drugi sposób wdrożenia metody
main
z powyższego kodu:
public static void main (String[] args) {
for (Method method : HelloWorld.class.getDeclaredMethods()) {
System.out.println(method.getReturnType() == Void.TYPE);
}
}
Dość interesującą dyskusję na temat różnic między nimi można przeczytać na stackoverflow:
Jaka jest różnica między java.lang.Void i void? #Wiaczesław
GO TO FULL VERSION