JavaRush /Blog Java /Random-VI /9 điều về NULL trong Java
Sdu
Mức độ

9 điều về NULL trong Java

Xuất bản trong nhóm
Javanull đi đôi với nhau. Hầu như không có lập trình viên Java nào mà không gặp phải " ngoại lệ con trỏ null " và đó là một thực tế đáng buồn. Ngay cả người phát minh ra khái niệm "null" cũng gọi đó là sai lầm tỷ đô của mình, vậy tại sao Java lại hỗ trợ nó? null đã tồn tại từ lâu và tôi đoán những người tạo ra Java biết rằng nó tạo ra nhiều vấn đề hơn là giải quyết được, vậy tại sao họ vẫn tiếp tục chấp nhận nó. Và điều này còn làm tôi ngạc nhiên hơn nữa vì triết lý của Java là đơn giản hóa mọi thứ, đó là lý do tại sao họ không còn loay hoay với con trỏ, nạp chồng toán tử và đa kế thừa nữa, nhưng tại sao lại rỗng? 9 điều về NULL trong Java - 1Chà, tôi thực sự không biết câu trả lời cho câu hỏi đó, nhưng điều tôi biết là cho dù các lập trình viên Java và cộng đồng nguồn mở có chỉ trích null đến mức nào đi chăng nữa thì chúng ta cũng phải chấp nhận nó. Thay vì hối tiếc, tốt hơn hết bạn nên tìm hiểu thêm và chắc chắn rằng chúng ta sử dụng null một cách chính xác.

Tại sao bạn nên tìm hiểu về null trong Java?

Bởi vì nếu bạn không chú ý đến null, bạn có thể chắc chắn rằng Java sẽ khiến bạn đau khổ khủng khiếp java.lang.NullPointerExceptionvà bạn sẽ rút ra được bài học nhưng bạn sẽ đi vào một con đường khó khăn hơn. Viết mã chống sự cố là một nghệ thuật và nhóm của bạn, khách hàng cũng như người dùng sẽ đánh giá cao điều đó. Theo kinh nghiệm của tôi, một trong những nguyên nhân chính NullPointerExceptionlà do thiếu kiến ​​thức về null trong Java. Nhiều bạn đã quen với null, những bạn còn lại sẽ có thể tìm hiểu một số điều cũ và mới về từ khóa null. Hãy xem lại hoặc tìm hiểu một số điều quan trọng về null trong Java.

Giá trị rỗng trong Java là gì

Như tôi đã nói, null là một khái niệm rất, rất quan trọng trong Java. Ban đầu nó được phát minh để biểu thị sự vắng mặt của thứ gì đó, chẳng hạn như sự vắng mặt của người dùng, tài nguyên hoặc bất cứ thứ gì, nhưng đã khiến các lập trình viên Java bối rối với rất nhiều null pointer exception. Trong hướng dẫn này, chúng ta sẽ tìm hiểu những thông tin cơ bản về từ khóa null trong Java và tìm hiểu một số thủ thuật để tránh rắc rối null pointer exceptionsvà giảm thiểu việc kiểm tra null.
  1. Đầu tiên, null là một từ khóa trong Java, giống như public, statichoặc final. Phân biệt chữ hoa chữ thường, bạn không thể viết null dưới dạng Null hoặc NULL, trình biên dịch sẽ không nhận ra nó và sẽ xảy ra lỗi.

    Object obj = NULL; // Not Ok
    Object obj1 = null //Ok

    Điều này thường gặp phải đối với những lập trình viên đã chuyển từ ngôn ngữ lập trình khác sang, nhưng khi sử dụng các IDE hiện đại, vấn đề trở nên không đáng kể. Ngày nay, các IDE như Eclipse hay NetBeans có thể sửa lỗi này khi bạn gõ, nhưng trong thời đại của Notepad, Vim và Emacs, đây là một vấn đề phổ biến có thể ngốn rất nhiều thời gian quý báu.

  2. Так же, How каждый примитив имеет meaning по умолчанию, например, у int это 0, у boolean это false, null это meaning по умолчанию любых ссылочных типов, проще говоря, для всех an objectов. Так же, How при создании логической переменной ее meaning по умолчанию равно false, так и любые ссылочные переменные в Java по умолчанию будут равны null. Это истинно для всех типов переменных: переменной-члена or локальной переменной, переменной экземпляра or статической переменной, кроме того, компилятор будет ругаться, если Вы используете локальную переменную не проинициализировав ее.

    private static Object myObj;
    public static void main(String args[]){
        System.out.println("What is value of myObjc : " + myObj);
    }
    What is value of myObjc : null

    Это истинно How для статических, так и для не статических an objectов, How Вы можете видеть здесь, я сделал myObj статической ссылкой, так что я могу использовать ее непосредственно в методе main, который является статическим методом и не позволяет обращаться к не статическим переменным изнутри.

  3. Несмотря на распространенное заблуждение, null это не an object (Object) и ни тип. Это просто специальное meaning, которое может быть назначено любому ссылочному типу, и Вы можете привести null к любому типу, How показано ниже:

    String str = null; // null can be assigned to String
    Integer itr = null; // you can assign null to Integer also
    Double dbl = null; // null can also be assigned to Double
    String myStr = (String) null; // null can be type cast to String
    Integer myItr = (Integer) null; // it can also be type casted to Integer
    Double myDbl = (Double) null; // yes it's possible, no error

    Как Вы можете видеть, приведение null к любому ссылочному типу пройдет успешно How во время компиляции, так и во время выполнения программы. В отличии от того, что многие из Вас возможно подумали, это не приведет к выбрасыванию NullPointerException.

  4. null может быть назначен только ссылочному типу, Вы не можете назначить null примитивной переменной вроде int, double, float or boolean. Компилятор выразит Вам свое недовольство если Вы сделаете How показано ниже:

    int i = null; // type mismatch : cannot convert from null to int
    short s = null; // type mismatch : cannot convert from null to short
    byte b = null: // type mismatch : cannot convert from null to byte
    double d = null; //type mismatch : cannot convert from null to double
    
    Integer itr = null; // this is ok
    int j = itr; // this is also ok, but NullPointerException at runtime

    Как Вы можете видеть, когда мы непосредственно присваиваем null примитиву, то получаем ошибку процесса компиляции, но, если присвоить null an objectу класса-обертки, а затем присвоить этот an object соответствующему примитивному типу, компилятор не отреагирует, но мы будем вознаграждены null pointer exception во время выполнения. Это происходит из-за авто упаковки (autoboxing) в Java, и мы еще встретимся с ним в следующем пункте.

  5. Любой класс-обертка со meaningм null будет выбрасывать java.lang.NullPointerException когда Java распакует(unbox) его в примитивную переменную. Некоторые программисты делают ошибку допуская, что авто упаковка(autoboxing) позаботится о конвертации null в meaning по умолчанию для соответствующего примитивного типа, например, 0 для int, false для boolean и т.д., но это не верно, в чем можно убедиться ниже:

    Integer iAmNull = null;
    int i = iAmNull; // Remember - No Compilation Error

    Но, когда Вы запустите данный фрагмент codeа, в консоли Вы увидите

    Exception in thread "main" java.lang.NullPointerException

    Это часто происходит при работе с HashMap и Integer key. Выполнение codeа, показанного ниже прервется, How только Вы его запустите.

    import java.util.HashMap;
    import java.util.Map;
    /**
    * An example of Autoboxing and NullPointerExcpetion
    *
    * @author WINDOWS 8
    */
    public class Test {
        public static void main(String args[]) throws InterruptedException {
            Map numberAndCount = new HashMap<>();
            int[] numbers = {3, 5, 7,9, 11, 13, 17, 19, 2, 3, 5, 33, 12, 5};
            for(int i : numbers){
                int count = numberAndCount.get(i);
                numberAndCount.put(i, count++); // NullPointerException here
            }
        }
    }

    Output: Exception in thread "main" java.lang.NullPointerException at Test.main(Test.java:25)

    Mã này trông rất đơn giản và vô hại. Bạn chỉ cần đếm số lần một số xuất hiện trong một mảng, một kỹ thuật cổ điển để tìm các số trùng lặp. Nhà phát triển lấy số lượng đã đếm trước đó, tăng lên một đơn vị và chèn lại vào Map. Anh ta có thể nghĩ rằng auto-boxing sẽ đảm nhiệm việc chuyển đổi Integerthành int, giống như khi phương thức được gọi put(), nhưng anh ta quên rằng nếu số đó chưa được đếm thì phương thức get()sẽ trả về HashMapnull, chứ không phải 0, vì giá trị mặc định là Số nguyên, đây là null, không phải 0 và tính năng tự động đánh quyền anh sẽ xuất hiện null pointer exceptionkhi cố gắng chuyển đổi Số nguyên thành một biến int.

  6. Toán tử instanceofsẽ trả về false nếu bất kỳ biến tham chiếu nào có giá trị null hoặc null được chỉ định làm tham số. Ví dụ:

    Integer iAmNull = null;
    if(iAmNull instanceof Integer){
        System.out.println("iAmNull is instance of Integer");
    }else{
        System.out.println("iAmNull is NOT an instance of Integer");
    }

    Output : iAmNull is NOT an instance of Integer

    Đây là một thuộc tính quan trọng của toán tử instanceofgiúp nó hữu ích cho việc thử nghiệm các kiểu ép kiểu.

  7. Bạn biết rằng bạn không thể gọi một phương thức không tĩnh trên biến tham chiếu null, nó sẽ gọi NullPointerException, nhưng bạn có thể không biết rằng bạn có thể gọi một phương thức tĩnh trên biến tham chiếu null. Bởi vì các phương thức tĩnh sử dụng liên kết tĩnh, chúng không loại bỏ các tệp NullPointerException. Đây là một ví dụ:

    public class Testing {
        public static void main(String args[]){
            Testing myObject = null;
            myObject.iAmStaticMethod();
            myObject.iAmNonStaticMethod();
        }
        private static void iAmStaticMethod(){
            System.out.println("I am static method, can be called by null reference");
        }
        private void iAmNonStaticMethod(){
            System.out.println("I am NON static method, don't date to call me by null");
        }
    }

    Output: I am static method, can be called by null reference
    Exception in thread "main" java.lang.NullPointerException
    at Testing.main(Testing.java:11)
  8. Bạn có thể truyền null làm tham số cho một phương thức chấp nhận bất kỳ loại tham chiếu nào, ví dụ:

    public void print(Object obj)

    có thể được gọi như thế

    print(null)

    Điều này là bình thường theo quan điểm của trình biên dịch, nhưng hành vi tiếp theo hoàn toàn phụ thuộc vào phương thức. Một phương thức an toàn null sẽ không ném NullPointerExceptionmà chỉ thoát ra một cách duyên dáng. Nếu logic nghiệp vụ cho phép, bạn nên viết các phương thức null-safe.

  9. Bạn có thể so sánh null bằng cách sử dụng toán ==tử (bằng) và !=(không bằng), nhưng bạn không thể sử dụng nó với các toán tử số học hoặc logic khác như <(nhỏ hơn) hoặc >(lớn hơn). Không giống như SQL, Java null == nullsẽ trả về true như dưới đây:

    public class Test {
    	public static void main(String args[]) throws InterruptedException {
    		String abc = null;
    		String cde = null;
    		if(abc == cde){
    			System.out.println("null == null is true in Java");
    		}
    		if(null != null){
    			System.out.println("null != null is false in Java");
    		}
    		// classical null check
    		if(abc == null){
    			// do something
    		}
    		// not ok, compile time error
    		if(abc > null){
    
    		}
    	}
    }

    Output:
    null == null is true in Java
Đây là tất cả về null trong Java. Bằng cách tích lũy một số kinh nghiệm về lập trình Java và sử dụng các thủ thuật đơn giản để tránh NullPointerException, bạn có thể làm cho mã của mình an toàn. Bởi vì null có thể được coi là giá trị trống hoặc chưa được khởi tạo, điều này thường gây nhầm lẫn, đó là lý do tại sao việc ghi lại hành vi của một phương thức khi nhập giá trị null là rất quan trọng. Hãy luôn nhớ rằng null là giá trị mặc định của các biến tham chiếu và bạn không thể gọi các phương thức phiên bản hoặc truy cập các biến phiên bản bằng cách sử dụng tham chiếu null trong Java.
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION