JavaRush /Java 博客 /Random-ZH /Java 中关于 NULL 的 9 件事
Sdu
第 17 级

Java 中关于 NULL 的 9 件事

已在 Random-ZH 群组中发布
Javanull齐头并进。几乎没有一个 Java 程序员没有遇到过“空指针异常”,这是一个悲伤的事实。就连“null”概念的发明者也称其为自己价值数十亿美元的错误,那么为什么 Java 支持它呢?null 已经存在很长时间了,我猜 Java 的创建者知道它产生的问题比它解决的问题还要多,所以为什么他们仍然忍受它。这更让我惊讶,因为 Java 的哲学是简化事物,这就是为什么他们不再搞指针、运算符重载和多重继承,但为什么是 null?关于 Java 中 NULL 的 9 件事 - 1好吧,我真的不知道这个问题的答案,但我所知道的是,无论 Java 程序员和开源社区对 null 有多少批评,我们都必须忍受它。与其后悔,不如多了解一些,并确保我们正确使用 null。

为什么要学习 Java 中的 null ?

因为如果你不注意 null,你可以肯定 Java 会让你遭受可怕的痛苦java.lang.NullPointerException,你会吸取教训,但你会走上一条艰难的道路。编写抗崩溃代码是一门艺术,您的团队、客户和用户都会欣赏它。根据我的经验,主要原因之一NullPointerException是缺乏对 Java 中 null 的了解。你们中的许多人已经熟悉 null,其余的人将能够了解有关 null 关键字的一些新旧知识。让我们回顾或学习有关 Java 中 null 的一些重要知识。

Java中什么是null

正如我所说,null 是 Java 中一个非常非常重要的概念。它最初被发明是为了指示某些东西的缺失,例如用户、资源或其他任何东西的缺失,但一直让许多 Java 程序员感到困惑null pointer exception。在本教程中,我们将了解有关 Java 中 null 关键字的基本事实,并学习一些避免出现问题并尽量null pointer exceptions减少 null 检查的技巧。
  1. 首先,null 是 Java 中的一个关键字,就像public,staticfinal。大小写敏感,不能将 null 写为 Null 或 NULL,编译器将无法识别并抛出错误。

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

    通常,从其他编程语言转过来的程序员会遇到这个问题,但是当使用现代 IDE 时,这个问题就变得微不足道了。如今,Eclipse 或 NetBeans 等 IDE 可以在您键入时修复此错误,但在记事本、Vim 和 Emacs 时代,这是一个常见问题,可能会占用大量宝贵时间。

  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)

    这段代码看起来非常简单而且无害。您只需计算一个数字在数组中出现的次数,这是查找重复项的经典技术。开发人员获取之前计数的数量,将其加一并将其插回到 中Map。他可能认为自动装箱会处理Integer到 的转换int,就像调用该方法时所做的那样put(),但他忘记了,如果尚未计算数字,该方法get()将返回HashMapnull,而不是零,因为默认值is Integer 这是 null,而不是 0,null pointer exception当尝试将 Integer 转换为变量时,自动装箱将会抛出异常int

  6. instanceof如果将任何值为 null 的引用变量或 null 本身指定为参数,则该运算符将返回 false。例子:

    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

    这是该运算符的一个重要属性instanceof,使其对于测试类型转换很有用。

  7. 您知道不能对空引用变量调用非静态方法,它会调用NullPointerException,但您可能不知道可以对空引用变量调用静态方法。因为 静态方法使用静态绑定,它们不会丢弃NullPointerException。这是一个例子:

    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. 您可以将 null 作为参数传递给接受任何引用类型的方法,例如:

    public void print(Object obj)

    可以这样称呼

    print(null)

    从编译器的角度来看,这是正常的,但后续行为完全取决于该方法。null 安全方法不会抛出异常NullPointerException,而只会优雅地退出。如果业务逻辑允许,建议编写空安全方法。

  9. 您可以使用==(等于)和!=(不等于)运算符来比较 null,但不能将其与其他算术或逻辑运算符(例如,<小于)或>(大于)一起使用。与 SQL 不同,Javanull == null将返回 true,如下所示:

    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
这就是 Java 中 null 的全部内容。通过获得一些 Java 编程经验并使用简单的技巧来避免NullPointerException,您可以使您的代码安全。因为 null 可以被视为空值或未初始化的值,这通常会造成混乱,这就是为什么在输入 null 值时记录方法的行为很重要。永远记住,null 是引用变量的默认值,并且您不能在 Java 中使用 null 引用来调用实例方法或访问实例变量。
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION