JavaRush /Blog Java /Random-PL /Instrukcja zwrotu w Javie
Viacheslav
Poziom 3

Instrukcja zwrotu w Javie

Opublikowano w grupie Random-PL

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. Instrukcja return w Javie - 1Klasy 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 returnodnosi 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 mainmetoda 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 returnpodaliśmy wartość zwracaną, którą wykorzystaliśmy w dalszej części metody println. W opisie (definicji) metody getHelloMessagewskazaliś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 returndotyczy 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, mainjeśli nasz program w Javie zostanie wywołany bez parametrów. Należy pamiętać, że jeśli wówczas będziesz returnposiadał 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 returnw ifblok:

if (2==2)  {
    return;
}

Instrukcja return w obsłudze błędów

Jest jedna bardzo skomplikowana okoliczność - możemy jej użyć returnw połączeniu z obsługą błędów. Od razu powiem, że używanie go returnw catchbloku 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ż finallyjest ono zawsze wykonywane. Ale nie, wartość będzie wynosić 1, a zmiana zmiennej in finallyzostanie zignorowana. Co więcej, gdyby valuezawierał obiekt i powiedzieliśmy finally, value = nullto catchnadal zwracałby referencję do obiektu, a nie null. Ale z bloku finallyoperator returndziałałby poprawnie. Koledzy z pewnością nie będą ci wdzięczni za taki prezent.
Co jeszcze warto przeczytać:

oświadczenie zwrotne

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 mainz 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
Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION