CodeGym /Blog Java /Ngẫu nhiên /Từ khóa trả về Java

Từ khóa trả về Java

Xuất bản trong nhóm
Như chúng ta đã biết, ngôn ngữ Java là ngôn ngữ lập trình hướng đối tượng. Nói cách khác, khái niệm nền tảng, tức là nền tảng của nền tảng, cho rằng mọi thứ đều là đối tượng. Các đối tượng được mô tả bằng cách sử dụng các lớp. Đến lượt mình, các lớp xác định trạng thái và hành vi. Ví dụ, một tài khoản ngân hàng có thể có trạng thái ở dạng số tiền trong tài khoản và có các hành vi làm tăng và giảm số dư tài khoản. Trong Java, các hành vi được thực hiện thông qua các phương thức. Học cách định nghĩa các phương thức xuất hiện ngay khi bạn bắt đầu học Java. Ví dụ, trong hướng dẫn chính thức của Oracle, dưới tiêu đề " Defining Methods ". Có hai điều quan trọng cần lưu ý ở đây:
  • Mỗi phương pháp có một chữ ký. Chữ ký bao gồm tên của phương thức và các tham số đầu vào của nó.
  • Một kiểu trả về phải được chỉ định cho các phương thức. Bạn khai báo kiểu trả về của phương thức trong phần khai báo phương thức của nó.
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à một ngôn ngữ được gõ mạnh và trình biên dịch muốn biết những kiểu nào được sử dụng và ở đâu, trước và càng nhiều càng tốt. Một lần nữa, điều này là để cứu chúng ta khỏi những sai lầm. Về cơ bản, đó là tất cả vì một lý do tốt. Và đối với tôi, dường như điều này một lần nữa thấm nhuần trong chúng ta văn hóa xử lý dữ liệu. Vì vậy, loại giá trị trả về được chỉ định cho các phương thức. Và từ khóa return trong Java được sử dụng để thực sự trả về. Từ khóa trả về Java - 1

Trả về làm gì trong Java

Từ khóa return là một câu lệnh luồng điều khiển, như được mô tả trong hướng dẫn của Oracle tại đây . Bạn cũng có thể đọc về cách trả về giá trị trong phần " Trả về giá trị từ phương thức " của hướng dẫn chính thức. Trình biên dịch theo dõi cẩn thận xem nó có thể đảm bảo rằng giá trị trả về của phương thức khớp với kiểu trả về được chỉ định của phương thức hay không. Hãy sử dụng IDE trực tuyến của Tutorialspoint để xem xét một ví dụ. Hãy xem ví dụ nguyên thủy:

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World");
    }
}
Như chúng ta có thể thấy, phương thức chính được thực thi ở đâ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 chính của chúng tôi không thể trả về giá trị. Nếu chúng ta cố trả về một giá trị ở đó, chúng ta sẽ gặp lỗi: "Error: Main method must return a value of type void" . Theo đó, phương pháp chỉ cần xuất ra màn hình. Bây giờ, hãy chuyển chuỗi ký tự thành một phương thức riêng để tạo thông báo:

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, chúng ta đã sử dụng từ khóa return để chỉ ra giá trị trả về, sau đó chúng ta chuyển giá trị này cho phương thức println . Việc khai báo phương thức getHelloMessage chỉ ra rằng phương thức này sẽ trả về một Chuỗi . Đ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 trả về được chỉ định trong khai báo phương thức có thể rộng hơn loại giá trị thực sự được trả về trong mã, tức là điều quan trọng là có thể chuyển đổi loại. Nếu không, chúng tôi sẽ gặp lỗi tại thời điểm biên dịch: "Error: in compatible types" . Nhân tiện, bạn có thể có một câu hỏi: Tại sao returnđược coi là một tuyên bố luồng điều khiển? Bởi vì nó có thể phá vỡ quy trình bình thường từ trên xuống của một chương trình. 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ư bạn có thể thấy từ ví dụ, chúng ta ngắt phương thức chính trong chương trình Java nếu nó được gọi mà không có đối số. Điều quan trọng cần nhớ là nếu bạn có mã sau câu lệnh return , mã đó sẽ không thể truy cập được. Trình biên dịch thông minh của chúng tôi sẽ nhận thấy điều đó và ngăn bạn chạy một chương trình như vậy. Ví dụ: mã này không biên dịch:

public static void main(String[] args) {
        System.out.println("1");
        return;
// we use output method after return statement, which is incorrect 
        System.out.println("2");
 }
Có một 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 câu lệnh return trong khối if :

if (2==2) {
    return;
}

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

Có một thứ khác rất phức tạp — chúng ta có thể sử dụng return kết hợp với xử lý lỗi. Tôi muốn nói ngay rằng việc sử dụng câu lệnh return trong khối catch là hình thức rất, rất xấu, vì vậy bạn nên tránh nó. Nhưng chúng ta cần một ví dụ, phải không? Đây là:

public class HelloWorld {

    public static void main(String[] args) {
        System.out.println("Value: " + getIntValue());
    }
    
    public static int getIntValue() {
        int value = 1;
        try {
            System.out.println("Something terrible happens");
            throw new Exception();
        } catch (Exception e) {
            System.out.println("Cached 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ì finally luôn được thực thi. Nhưng không, giá trị trả về sẽ là 1 và thay đổi đối với biến trong khối cuối cùng sẽ bị bỏ qua. Hơn nữa, giả sử giá trị đó chứa một đối tượng và chúng tôi nói giá trị = null trong khối cuối cùng . Sau đó, đối tượng đó, không phải null, sẽ được trả về trong khối bắt . Nhưng một câu lệnh return sẽ hoạt động chính xác trong khối cuối cùng . Rõ ràng, đồng nghiệp của bạn sẽ không cảm ơn bạn vì những bất ngờ nho nhỏ liên quan đến câu trả lời.

void.class

Và cuối cùng. Có một cấu trúc kỳ lạ mà bạn có thể viết: void.class . Hừm. Tại sao và nó có nghĩa là gì? Thực sự có nhiều khuôn khổ khác nhau và các trường hợp phức tạp liên quan đến Java Reflection API , nơi điều này có thể rất hữu ích. 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 nơi bạn cần thay thế mã thực trong các phương thức. Nhưng để làm được điều này, bạn cần hiểu phương thức hoạt động như thế nào (nghĩa là nó trả về kiểu gì). Ngoài ra còn có một cách thứ hai để triển khai phương thức chính trong đoạn mã trên:

public static void main(String[] args) {
        for (Method method : HelloWorld.class.getDeclaredMethods()) {
            System.out.println(method.getReturnType() == Void.TYPE);
        }
 }
Bạn có thể đọc một cuộc thảo luận khá thú vị về sự khác biệt giữa hai điều này trên Stack Overflow: Sự khác biệt giữa java.lang.Void và void là gì?
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION