CodeGym /Blog Java /Ngẫu nhiên /Hãy nói về từ khóa cuối cùng trong Java

Hãy nói về từ khóa cuối cùng trong Java

Xuất bản trong nhóm
Java có từ khóa này - cuối cùng. Nó có thể được áp dụng cho các lớp, phương thức, biến (bao gồm cả tham số của phương thức). Đối với một lớp, từ khóa final có nghĩa là lớp đó không thể có các lớp con, nghĩa là tính kế thừa bị cấm... Điều này rất hữu ích khi tạo các đối tượng bất biến (không thể thay đổi). Ví dụ, lớp String được khai báo là cuối cùng.

    public final class String {
    }
    
    class SubString extends String { // Compilation error
    }
Tôi cũng nên lưu ý rằng công cụ sửa đổi cuối cùng không thể được áp dụng cho các lớp trừu tượng (những lớp có từ khóa trừu tượng), bởi vì đây là những khái niệm loại trừ lẫn nhau. Đối với một phương thức cuối cùng, công cụ sửa đổi có nghĩa là phương thức đó không thể bị ghi đè trong các lớp con. Điều này hữu ích khi chúng tôi muốn ngăn chặn sự thay đổi của việc triển khai ban đầu.

    public class SuperClass {
        public final void printReport() {
            System.out.println("Report");
        }
    }

    class SubClass extends SuperClass { 
        public void printReport() { //Compilation error
            System.out.println("MyReport");
        }
    }
Đối với các biến kiểu nguyên thủy, từ khóa cuối cùng có nghĩa là giá trị sau khi được gán sẽ không thể thay đổi được. Đối với các biến tham chiếu, điều đó có nghĩa là sau khi một đối tượng được gán, bạn không thể thay đổi tham chiếu đến đối tượng đó. Cái này quan trọng! Tham chiếu không thể thay đổi, nhưng trạng thái của đối tượng có thể thay đổi. Java 8 đã giới thiệu một khái niệm mới: hiệu quả cuối cùng. Nó chỉ áp dụng cho các biến (bao gồm cả các tham số của phương thức). Điểm mấu chốt là mặc dù không có từ khóa final, nhưng giá trị của biến không thay đổi sau khi khởi tạo. Nói cách khác, từ khóa cuối cùng có thể được áp dụng cho một biến như vậy mà không có lỗi biên dịch. Các biến cuối cùng một cách hiệu quả có thể được sử dụng bên trong các lớp cục bộ (các lớp bên trong cục bộ), các lớp ẩn danh (các lớp bên trong ẩn danh) và các luồng (API luồng).

        public void someMethod() {
            // In the example below, both a and b are effectively final, since they are assigned values only once:
            int a = 1;
            int b;
            if (a == 2) b = 3;
            else b = 4;
            // c is NOT effectively final since its value changes
            int c = 10;
            c++;
            
            Stream.of(1, 2).forEach(s-> System.out.println(s + a)); // OK
            Stream.of(1, 2).forEach(s-> System.out.println(s + c)); // Compilation error
        }
Bây giờ, chúng ta hãy có một cuộc phỏng vấn nhỏ. Rốt cuộc, mục tiêu hoàn thành khóa học CodeGym là trở thành nhà phát triển Java và tìm được một công việc thú vị và được trả lương cao. Vì vậy, chúng ta hãy bắt đầu.
  1. Chúng ta có thể nói gì về một mảng được khai báo là cuối cùng?

  2. Chúng ta biết rằng lớp String là bất biến: lớp được khai báo là cuối cùng. Một giá trị chuỗi được lưu trữ trong một mảng char được đánh dấu bằng từ khóa cuối cùng.


public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

Chúng ta có thể thay thế giá trị của đối tượng Chuỗi (mà không thay đổi tham chiếu đến đối tượng) không? Đây là những câu hỏi phỏng vấn thực sự. Và thực tế cho thấy nhiều thí sinh không trả lời đúng. Hiểu cách từ khóa cuối cùng được sử dụng, đặc biệt là đối với các biến tham chiếu, là rất quan trọng. Khi bạn suy nghĩ về điều này, tôi sẽ đưa ra một yêu cầu nhỏ với nhóm CodeGym. Vui lòng cung cấp cho trình soạn thảo văn bản khả năng thêm một khối có nội dung có thể được hiển thị/ẩn khi bạn nhấp vào khối đó. câu trả lời:
  1. Một mảng là một đối tượng, vì vậy từ khóa cuối cùng có nghĩa là một khi tham chiếu đến mảng được gán, thì tham chiếu đó không thể thay đổi được. Điều đó nói rằng, bạn có thể thay đổi trạng thái của đối tượng.

    
            final int[] array = {1, 2, 3, 4, 5};
            array[0] = 9;	 // OK, because we're changing the contents of the array: {9, 2, 3, 4, 5}
            array = new int[5]; // Compilation error
    
  2. Vâng, chúng tôi có thể. Điều chính là để hiểu ý nghĩa của từ khóa gai góc cuối cùng khi được sử dụng với các đối tượng. Reflection API có thể được sử dụng để thay thế các giá trị.


import java.lang.reflect.Field;

class B {
    public static void main(String[] args) throws Exception {
        String value = "Old value";
        System.out.println(value);

        // Get the String class's value field
        Field field = value.getClass().getDeclaredField("value");
        // Make it mutable
        field.setAccessible(true);
        // Set a new value
        field.set(value, "CodeGym".toCharArray());

        System.out.println(value);

        /* Output:
         * Old value
         * CodeGym
         */
    }
}
Xin lưu ý rằng nếu chúng ta cố gắng thay đổi biến cuối cùng của kiểu nguyên thủy theo cách này thì sẽ không có gì xảy ra. Tôi khuyên bạn nên thuyết phục bản thân: tạo một lớp Java, chẳng hạn, với trường int cuối cùng và thử thay đổi giá trị của nó bằng cách sử dụng API Reflection. Chúc mọi người may mắn!
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION