JavaRush /Blog Java /Random-VI /Câu lệnh trả về trong Java
Viacheslav
Mức độ

Câu lệnh trả về trong Java

Xuất bản trong nhóm

Giới thiệu

Như chúng ta đã biết, Java là ngôn ngữ lập trình hướng đối tượng. Đó là, khái niệm cơ bản, bởi vì để nói cơ sở của các nguyên tắc cơ bản là mọi thứ đều là một đối tượng. Các đối tượng được mô tả bằng cách sử dụng các lớp. Câu lệnh trả về trong Java - 1Các lớp lần lượt có trạng thái và hành vi. Ví dụ: tài khoản ngân hàng có thể có trạng thái là số tiền trong tài khoản và có hành vi tăng giảm số dư. Hành vi trong Java được thực hiện bằng các phương thức. Cách mô tả các phương thức được giới thiệu ngay từ đầu hành trình học Java của bạn. Ví dụ: trong hướng dẫn chính thức của Oracle: “ Xác định các phương thức ”. Có hai khía cạnh quan trọng ở đây:
  • Mỗi phương pháp có một chữ ký. Chữ ký bao gồm tên phương thức và các tham số đầu vào của nó;
  • Các phương thức phải chỉ định kiểu trả về;
  • Kiểu trả về không phải là một phần của chữ ký phương thức.
Một lần nữa, đây là hệ quả của thực tế rằng Java là ngôn ngữ được định kiểu mạnh và trình biên dịch muốn hiểu trước loại nào được sử dụng ở nơi càng nhiều càng tốt. Một lần nữa, để bảo vệ chúng ta khỏi những sai lầm. Nói chung, mọi thứ đều tốt. Chà, đối với tôi, điều này một lần nữa thấm nhuần vào chúng ta văn hóa xử lý dữ liệu. Vì vậy, đối với các phương thức, loại giá trị được chỉ định. Và để trả về cùng giá trị này từ các phương thức, từ khóa được sử dụng return.

Câu lệnh trả về từ khóa trong Java

Từ khóa câu lệnh returnđề cập đến "câu lệnh luồng điều khiển" như được thảo luận trong hướng dẫn oracle " Câu lệnh luồng điều khiển ". Bạn cũng có thể đọc về cách trả về giá trị trong hướng dẫn chính thức: “ Trả về giá trị từ một phương thức ”. Trình biên dịch giám sát cẩn thận, với khả năng tốt nhất của nó, rằng giá trị được trả về từ một phương thức khớp với loại giá trị trả về được chỉ định bởi phương thức đó. Hãy sử dụng IDE trực tuyến từ tutorialspoint làm ví dụ . Hãy nhìn vào ví dụ ban đầu:
public class HelloWorld {
    public static void main(String []args) {
        System.out.println("Hello World");
    }
}
Như chúng ta có thể thấy, một phương thức được thực thi ở đây main, đây là điểm vào của chương trình. Các dòng mã được thực thi từ trên xuống dưới. Phương thức của chúng tôi mainkhông thể trả về giá trị, nếu không chúng tôi sẽ nhận được lỗi: " Error: Main method must return a value of type void". Do đó, phương thức sẽ chỉ xuất ra màn hình. Bây giờ chúng ta hãy chuyển việc nhận chuỗi sang một phương thức riêng để nhận tin nhắn:
public class HelloWorld {

    public static void main(String []args) {
        System.out.println(getHelloMessage());
    }

    public static String getHelloMessage() {
        return "Hello World";
    }

}
Như chúng ta có thể thấy, bằng cách sử dụng từ khóa return, chúng ta đã chỉ định giá trị trả về mà chúng ta sẽ sử dụng sau này trong phương thức println. Trong phần mô tả (định nghĩa) của phương thức, getHelloMessagechúng tôi đã chỉ ra rằng nó sẽ trả về cho chúng tôi String. Điều này cho phép trình biên dịch kiểm tra xem các hành động của phương thức có phù hợp với cách nó được khai báo hay không. Đương nhiên, loại giá trị trả về được chỉ định trong định nghĩa phương thức có thể rộng hơn loại giá trị được trả về từ mã, tức là. Điều chính là các loại được giảm bớt lẫn nhau. Nếu không chúng ta sẽ gặp lỗi thời gian biên dịch: " error: incompatible types". Nhân tiện, câu hỏi có lẽ ngay lập tức nảy sinh: Tại sao returnnó lại áp dụng cho các toán tử điều khiển luồng chương trình? Nhưng vì nó có thể làm gián đoạn dòng chảy bình thường của chương trình từ trên xuống dưới. Ví dụ:
public class HelloWorld {

    public static void main(String []args){
        if (args.length == 0)  {
            return;
        }
        for (String arg : args)  {
            System.out.println(arg);
        }
    }

}
Như có thể thấy từ ví dụ, chúng tôi sẽ làm gián đoạn việc thực thi phương thức mainnếu chương trình java của chúng tôi được gọi mà không có tham số. Điều quan trọng cần nhớ là nếu sau đó bạn returncó mã, nó sẽ không thể truy cập được. Và trình biên dịch thông minh của chúng tôi sẽ nhận thấy điều này và sẽ không cho phép bạn chạy một chương trình như vậy. Ví dụ: mã này sẽ không biên dịch:
public static void main(String []args) {
        System.out.println("1");
        return;
        System.out.println("2");
 }
Có một cách hack bẩn để giải quyết vấn đề này. Ví dụ: vì mục đích gỡ lỗi hoặc vì một số lý do khác. Đoạn mã trên có thể được sửa bằng cách gói nó returntrong ifmột khối:
if (2==2)  {
    return;
}

Câu lệnh trả về trong xử lý lỗi

Có một tình huống rất phức tạp - chúng ta có thể sử dụng nó returncùng với việc xử lý lỗi. Tôi muốn nói ngay rằng việc sử dụng nó returntrong catchmột khối là một hình thức rất, rất xấu, vì vậy các bạn nên tránh nó. Nhưng chúng ta cần một ví dụ, phải không? Anh ta đây rồi:
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);
        }
    }

}
Thoạt nhìn, có vẻ như 2 nên được trả về vì finallynó luôn được thực thi. Nhưng không, giá trị sẽ là 1 và sự thay đổi của biến trong finallysẽ bị bỏ qua. Hơn nữa, nếu nó valuechứa một đối tượng và chúng ta finallyđã nói value = null, thì nó catchvẫn sẽ trả về một tham chiếu đến đối tượng đó chứ không phải null. Nhưng từ khối, finallytoán tử returnsẽ hoạt động chính xác. Đồng nghiệp rõ ràng sẽ không cảm ơn bạn vì một món quà như vậy.
Còn gì để đọc:

tuyên bố trở lại

void.class

Và cuối cùng. Bạn có thể viết một cấu trúc lạ như void.class. Có vẻ như tại sao và vấn đề là gì? Trên thực tế, trong nhiều khung công tác khác nhau và các trường hợp phức tạp khi sử dụng API Java Reflection , điều này có thể rất cần thiết. Ví dụ: bạn có thể kiểm tra loại phương thức trả về:
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);
        }
    }
}
Điều này có thể hữu ích trong các khung thử nghiệm khi cần thay thế mã phương thức thực. Nhưng để làm được điều này, bạn cần hiểu cách thức hoạt động của phương thức này (tức là nó trả về kiểu gì). Có cách thứ hai để triển khai phương thức maintừ đoạn mã trên:
public static void main (String[] args) {
        for (Method method : HelloWorld.class.getDeclaredMethods()) {
            System.out.println(method.getReturnType() == Void.TYPE);
        }
 }
Một cuộc thảo luận khá thú vị về sự khác biệt giữa chúng có thể được đọc trên stackoverflow: Sự khác biệt giữa java.lang.Void và void là gì? #Viacheslav
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION