精华内容
下载资源
问答
  • Optional可以让你的代码具有可读性,且会避免出现空指针异常。下面这篇文章主要给大家介绍了关于利用Java8 Optional如何避免空指针异常的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下。
  • 主要介绍了Java字符串比较方法equals的空指针异常的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • 空指针的定义.doc

    2020-12-09 15:12:37
    1、问题:空指针的定义 曾经看过有的.h文件将NULL定义为0L,为什么? 答案与分析: 这是一个关于空指针宏定义的问题。指针在C语言中是经常使用的,有时需要将一个指针置为空指针,例如在指针变量初始化的时候。 ...
  • 空指针

    千次阅读 2020-02-10 21:35:05
    空指针 空指针:它“保证与任何对象或函数的指针值都不相等”。也就是说,空指针不会指向任何地方,它不是任何对象或函数的地址。每种指针类型都有一个空指针,而不同类型的空指针的内部表示可能不尽相同。取地址操作符&...

    空指针

    空指针:它“保证与任何对象或函数的指针值都不相等”。也就是说,空指针不会指向任何地方,它不是任何对象或函数的地址。每种指针类型都有一个空指针,而不同类型的空指针的内部表示可能不尽相同。取地址操作符&永远也不会返回空指针。同样对ma11oc的成功调用也不会返回空指针。(如果失败,ma11oc的确返回空指针,这是空指针的典型用法:表示“未分配”或者“尚未指向任何地方”的“特殊”指针值。) 初始化的指针则可能指向任何地方。空指针的名称是“0”,但空指针的名称却被叫做“NULL”。
    空指针常量:一个值为0的整型常量表达式,可能被转换成了void*类型。
    NULL:定义为0或(void *)0,只能用作指针。
    NULL的含义:
    (1)概念上的空指针。
    (2)空指针的内部(或运行时)表示形式,这可能并不是全零,而且对不同的指针类型可能不同。
    (3)空指针常量,这是一个常整数0。
    (4)NULL宏后边,它被定义为0。
    (5)ASCI空字符(NUL),它的确是全零,但它和空指针除了在名称上相似以外,没有关系。
    (6)“空串”( null string),它是内容为空的字符串(mn)。
    注意:
    (1)当在源码中需要空指针常量时,用“0”或“NULL”。
    (2)如果在函数调用中“0”或“NULL”用作参数,把它转换成被调函数需要的指针类型。

    展开全文
  • 空指针异常

    2013-05-22 20:20:06
    空指针异常进行举例,并对实例进行解释,
  • http://blog.csdn.net/zhufuing/article/details/27807813 博文演示demo Android setOnClickListener报空指针异常错误demo
  • 为实现基于静态分析技术充分地检测出C程序中的空指针引用缺陷,提出了一种基于属性可靠分析的缺陷检测方法。首先介绍了空指针引用缺陷模式及特征。然后针对空指针引用缺陷的检测特点提出了属性可靠分析理论,并将...
  • 已通过测试 调用方法如下 public static void main(String[] args) { EChannel test = new EChannel(); test.setBizType("12321");...biztype不会被修改,调用其他属性会报空指针的属性将被附上初始值
  • java空指针异常:预防及解决办法

    千次阅读 2020-02-11 11:26:27
    这是我16年在博客园发的一篇博客,彼时还在学校。...空指针就是空引用,java空指针异常就是引用本身为空,却调用了方法,这个时候就会出现空指针异常。可以理解,成员变量和方法是属于对象的(除...

     

    一.什么是java空指针异常

        我们都知道java是没有指针的,这里说的"java指针"指的就是java的引用,我们不在这里讨论叫指针究竟合不合适,而只是针对这个异常本身进行分析。空指针就是空引用,java空指针异常就是引用本身为空,却调用了方法,这个时候就会出现空指针异常。可以理解,成员变量和方法是属于对象的(除去静态),在对象中才存在相对应的成员变量和方法,然后通过对象去调用这些成员变量和方法。对于空指针来说,它不指向任何对象,也就没有所谓的成员变量和方法,这个时候用它去调用某些属性和方法,当然会出现空指针异常。

    public class Test {
        private int a=1;
        private int b=2;
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Test t1 = new Test();
            Test t2 = null;
            System.out.println(t1.a);
            System.out.println(t2.a);
            System.out.println(t2.c());
        }
        public String c(){
            return "123";
        }
    }

    我们分析上面这段示例代码,在Test类中,有两个成员变量a和b,和一个方法c()。然后在main()方法中,我们创建了两个对象t1和t2,其中t1指向通过构造方法实例出的Test对象,而t2只是声明,并指向了空,并没有指向实际的对象。调试的时候,第一条输出语句是可以通过编译的,而执行到第二条输出语句的时候,由于空指针调用了不属于它的a,程序终止,报告空指针异常。同样,注释第二条输出语句,程序在执行到第三条输出语句的时候,由于调用了不属于它的c()方法,会出现一样的错误。

     

    二.如何解决

        对于每一个java程序员来说,几乎都避免不了遇到空指针异常,特别是经验不足的初学者。而且由于它的调试和查找相对其它异常来说比较困难,常常需要花费很大的精力去解决它。

        知己知彼,才能百战不殆。

        首先认识一下java中的null

        null是Java中一个很重要的概念。null设计初衷是为了表示一些缺失的东西,例如缺失的用户、资源或其他东西。但是,一年后,令人头疼的空指针异常给Java程序员带来不少的骚扰。

        null是java中的关键字,因此,它不能写成NULL,Null,只能是null。

        null是所有引用类型的默认值,如果没有让一个引用指向一个实际存在的对象,它的默认值就是null。null本质上是一个值,这跟int的默认值是0,boolean的默认值是false一样。现在,我们通常都使用像eclipse、idea等的集成开发环境进行开发,一般在定义变量的时候都会进行初始化(这也是写代码的一个良好的习惯),如果没有进行初始化,系统会进行提示。

    报空指针异常的原因有以下几种: 

    1、字符串变量未初始化; 
    2、接口类型的对象没有用具体的类初始化,比如: 
    List it;会报错 。(当时,eclipse等确实会对这行代码报错,现在又试了一下,不初始化也不报错了
    List it = new ArrayList();则不会报错了 
    3、当一个对象的值为空时,你没有判断为空的情况。你可以试着把下面的代码前加一行代码: 
    if(rb!=null && rb!="") 
    改成: 
    if(rb==null); 
    if(rb!==null&&rb!="") 或者if("").equals(rb)) 
    空指针的解决办法: 
           解决空指针问题的核心是找到“谁是空”,“为什么产生了空”。重点关注报错发生的所在行,通过空指针异常产生的两条主要原因诊断具体的错误。同时为了避免空指针的发生,最好在做判断处理时将“null”或者空值放于 设定的值之前。 
    常见空指针异常的简要分析: 
    (1)空指针错误 
        Java中的8种基本数据类型,变量的值可以有其默认值,加入没有对其正常赋值,java虚拟机是不能 正确编译通过的,因此使用基本的Java数据类型一般是不会引起空指针异常的。实际开发中,大多数的空指针异常主要与对象的操作相关。 
        下面列出可能发生空指针异常的几种情况及相应解决方案: 
        代码段1: 
      out.println(request.getParameter("username")); 
      分析:代码段1的功能十分简单,就是输出用户输入"username"的值。 
           说明:看上去,上面的语句找不出什么语法错误,而且在大多数情况下也遇不到什么问题。但是,如果某个用户在输入数据时并没有提供表单 域"username" 的值,或通过某种途径绕过表单直接输入时,此request.getParameter("username")的值为空(注意不是空字符串,是空对象 null。),out对象的println方法是无法直接对空对象操作的,因此代码段1所在的JSP页面将会抛出 "Java.lang.NullPointerException"异常。而且即使对象可能为空时,也调用Java.lang.Object或 Object对象本身的一些方法如toString(), equal(Object obj)等操作。 
        代码段2: 
      String userName = request.getParameter("username"); 
      If (userName.equals("root")) 
      {....} 
      分析:代码段2的功能是检测用户提供的用户名,如果是用户名称为"root"的用户时,就执行一些特别的操作。                                                                        
          说明:在代码段2中,如果有用户没有提供表单域"username"的值时,字符串对象userName为null值,不能够将一个null的对象与另一 个对象直接比较,同样,代码段2所在的JSP页面就会抛空指针错误。 
         一个小技巧,也几乎是实际开发中所有字符串比较采取的方法:如果要把某个方法的返回值与常量做比较,把常量放在前面,可以避免调用null对象的equals方法。譬如:  
        If ("root".equals(userName)) 
      {....} 
        即使userName对象返回了null对象,这里也不会有空指针异常,可以照常运转。 
        代码段3: 
      String userName = session.getAttribute("session.username").toString(); 
            分析:代码段3的功能是将session中session.username的值取出,并将该值赋给字符串对象userName。 
           说明:在一般情况下,如果在用户已经进行某个会话,则不会出现什么问题;但是,如果此时应用服务器重新启动,而用户还没有重新登录,(也可能是用户关闭浏 览器,但是仍打开原来的页面。)那么,此时该session的值就会失效,同时导致session中的session.username的值为空。对一个 为 null的对象的直接执行toString()操作,就会导致系统抛出空指针异常。 
        代码段4: 
    public static void main(String args[]){ 
           Person p=null; 
           p.setName("张三"); 
           System.out.println(p.getName()); 

    分析:声明一个Person对象,并打印出该对象的中的Name名字。 
    说明:这个时候你的p就出现空指针异常,因为你只是声明了这个Person类型的对象并没有创建对象,所以它的堆里面没有地址引用,切忌你要用对 象掉用方法的时候一定要创建对象。

     

     

       

     

    展开全文
  • 空指针和野指针

    千次阅读 2018-05-02 15:54:35
    空指针常量0、0L、'\0'、3 - 3、0 * 17 (它们都是“integer constant expression”)以及 (void*)0 等都是空指针常量。至于系统选取哪种形式作为空指针常量使用,则是实现相关的。一般的 C 系统选择 (void*)0 或者...

    空指针常量

    0、0L、'\0'、3 - 3、0 * 17 (它们都是“integer constant expression”)以及 (void*)0 等都是空指针常量。至于系统选取哪种形式作为空指针常量使用,则是实现相关的。一般的 C 系统选择 (void*)0 或者 0 的居多(也有个别的选择 0L);至于 C++ 系统,由于存在严格的类型转化的要求,void* 不能象 C 中那样自由转换为其它指针类型,所以通常选 0 作为空指针常量(C++标准推荐),而不选择 (void*)0。


    空指针

    如果 p 是一个指针变量,则 p = 0; p = 0L; p = '\0'; p = 3 - 3; p = 0 * 17; 中的任何一种赋值操作之后(对于 C 来说还可以是 p = (void*)0;), p 都成为一个空指针,由系统保证空指针不指向任何实际的对象或者函数。反过来说,任何对象或者函数的地址都不可能是空指针。(比如这里的(void*)0就是一个空指针。把它理解为null pointer还是null pointer constant会有微秒的不同,当然也不是紧要了)。其实空指针只是一种编程概念,就如一个容器可能有空和非空两种基本状态。

    在程序中,得到一个空指针最直接的方法就是运用预定义的NULL,这个值在多个头文件中都有定义。

    如果要初始化一个空指针,我们可以这样, 

    int *ip = NULL;  

    校验一个指针是否为一个有效指针时,我们更倾向于使用这种方式

    if(ip != NULL)  

     而不是

    if(ip)  
    为什么有人会用if(ip)这种方式校验一个指针非空,而且在C++中不会出现错误呢?而且现在很多人都会这样写。
    原因是这样的,
    // Define   NULL   pointer   value   
    #ifndef   NULL   
    #   ifdef   __cplusplus   //如果是C++文件
    #     define   NULL      0   
    #   else   
    #     define   NULL      ((void   *)0)   
    #   endif   
    #endif //   NULL   
    在现在的C/C++中定义的NULL即为0,而C++中的true为≠0,所以此时的if(ip)和if(ip != NULL)是等效的。


    空指针指向内存的什么地方?

    标准并没有对空指针指向内存中的什么地方这一个问题作出规定,也就是说用哪个具体的地址值(0x0 地址还是某一特定地址)表示空指针取决于系统的实现。我们常见的空指针一般指向 0 地址,即空指针的内部用全 0 来表示(zero null pointer,零空指针);也有一些系统用一些特殊的地址值或者特殊的方式表示空指针(nonzero null pointer,非零空指针),具体请参见C FAQ。

    在实际编程中不需要了解在我们的系统上空指针到底是一个 zero null pointer 还是 nonzero null pointer,我们只需要了解一个指针是否是空指针就可以了——编译器会自动实现其中的转换,为我们屏蔽其中的实现细节。注意:不要把空指针的内部表示等同于整数 0 的对象表示——如上所述,有时它们是不同的。


    对空指针实现的保护政策

    逻辑地址和物理地址

    既然我们选择了0作为空的概念。在非法访问空的时候我们需要保护以及报错。因此,编译器和系统提供了很好的政策。我们程序中的指针其实是windows内存段偏移后的地址,而不是实际的物理地址,所以不同的地址中的零值指针指向的同一个0地址,其实在内存中都不是物理内存的开端的0,而是分段内存的开端,这里我们需要简单介绍一下windows下的内存分配和管理制度:
    windows下,执行文件(PE文件)在被调用后,系统会分配给它一个额定大小的内存段用于映射这个程序的所有内容(就是磁盘上的内容)并且为这个段进行新的偏移计算,也就是说我们的程序中访问的所有near指针都是在我们“自家”的段里面的,当我们需要访问far指针的时候,我们其实是跳出了“自家的院子”到了他人的地方,我们需要一个段偏移资质来完成新的偏移(人家家里的偏移)所以我们的指针可能是OE02:0045就是告诉我们要访问0E02个内存段的0045号偏移,然后windows会自动给我们找到0E02段的开始偏移,然后为我们计算真实的物理地址。
    所以程序A中的零值指针和程序B中的零值指针指向的地方可能是完全不同的。

    保护政策:  

    我们的程序在使用的是系统给定的一个段,程序中的零值指针指向这个段的开端,为了保证NULL概念,系统为我们这个段的开头64K内存做了苛刻的规定,根据虚拟内存访问权限控制,我们程序中(低访问权限)访问要求高访问权限的这64K内存被视作是不容许的,所以会必然引发Access Volitation 错误,而这高权限的64K内存是一块保留内存(即不能被程序动态内存分配器分配,不能被访问,也不能被使用),就是简单的保留,不作任何使用。

    我们在直接定义一个指针后并不知道这个指针指向何处(而不是有些程序员认为的如同JAVA等语言会自动零值初始化。请看下面详细讲解),所以我们一旦非法地直接访问这些未知地内容时,极其有可能会触碰到程序所不能触碰地内存(这时类似64K限制地保护政策又会起效,就如同你不仅随意闯入了陌生人的家(野指针),而且拿着刀子要问他要钱(访问),警察(WINDOWS内存访问保护政策)当然请你去警察局(报错)谈谈),所以养成良好的指针初始化(赋值为NULL)以及使用FREE(或者时DELETE)之后立即再初始化为空是十分必要的!   

    add:

    为了更好地贯彻零开销原则(C++之父Bjarne在设计C++语言时所遵循的原则之一,即“无须为未使用的东西付出代价”),编译器一般不会对一般变量进行初始化,当然也包括指针。所以负责初始化指针变量的只有程序员自己。

    使用未初始化的指针是相当危险的。因为指针直接指向内存空间,所以程序员很容易通过未初始化的指针改写该指针随机指向的存储区域。而由此产生的后果却是不确定的,这完全取决于程序员的运气。

    但是对于全局变量来说,编译器会悄悄对变量进行完成初始化(赋值为0)。

    (PS:定义静态局部变量时编译器自动赋值为0或者空字符串)


    为什么空指针访问会出现异常

    NULL指针分配的分区:其范围是从 0x00000000到0x0000FFFF。这段空间是空闲的,对于空闲的空间而言,没有相应的物理存储器与之相对应,所以对这段空间来说,任何读写操作都是会引起异常的。空指针是程序无论在何时都没有物理存储器与之对应的地址。为了保障“无论何时”这个条件,需要人为划分一个空指针的区域,固有上面NULL指针分区。


     野指针

    “野指针”不是NULL指针,是指向“垃圾”内存的指针。

    2.1 “野指针”的成因主要有两种:

    1)指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。例如:
         char *p = NULL;
         char *str = (char *) malloc(100);

    2)指针p被free或者delete之后,没有置为NULL,让人误以为p是个合法的指针。

    free和delete只是把指针所指的内存给释放掉,但并没有把指针本身干掉。free以后其地址仍然不变(非NULL),只是该地址对应的内存是垃圾,p成了“野指针”。如果此时不把p设置为NULL,会让人误以为p是个合法的指针。如果程序比较长,我们有时记不住p所指的内存是否已经被释放,在继续使用p之前,通常会用语句if (p != NULL)进行防错处理。很遗憾,此时if语句起不到防错作用,因为即便p不是NULL指针,它也不指向合法的内存块。

    char *p = (char *) malloc(100);
    strcpy(p, “hello”);
    free(p);   // p 所指的内存被释放,但是p所指的地址仍然不变
         …
    if(p != NULL)      // 没有起到防错作用
    {
        strcpy(p, “world”);      // 出错
    }

    3)指针操作超越了变量的作用范围。这种情况让人防不胜防,示例程序如下:

    class A 
    {      
    public:
         void Func(void){ cout << “Func of class A” << endl; }
    };
    void Test(void)
    {
        A *p;
       {
          A a;
          p = &a; // 注意 a 的生命期 ,只在这个程序块中(花括号里面的两行),而不是整个test函数
       }
         p->Func();  // p是“野指针”
    }
    函数Test在执行语句p->Func()时,对象a已经消失,而p是指向a的,所以p就成了“野指针”。
    展开全文
  • Android 防止空指针异常

    千次阅读 2019-07-29 10:23:40
    文章目录空指针异常防止空指针异常Java 注解Java 8 中的 Optional 类型Kotlin总结 空指针异常 先复习下异常。 异常分为 Exception 和 Error,Exception 和 Error 类都继承自Throwable类。 Exception(程序可恢复)...

    空指针异常

    先复习下异常。

    异常分为 ExceptionError,Exception 和 Error 类都继承自Throwable类。

    • Exception(程序可恢复):表示程序可以处理的异常,可以捕获并且可恢复。遇到这类异常,应该尽可能处理异常,使程序恢复运行,而不应该随意终止异常。
    • Error(程序不可恢复):一般指虚拟机相关的问题,如系统崩溃,虚拟机错误,内存空间不足,方法调用栈溢出等。这于这类错误,Java编译器不去检查也会导致应用程序中断,仅靠程序本身无法恢复和预防,遇到这样的错误,建议程序终止。

    Exception 又分为运行时异常受检查的异常

    • 运行时异常:如空指针,参数错误等。
    • 受检查异常:这类异常如果没有try/catch语句也没有throws抛出,编译不通过。

    空指针异常(NullPointerException)属于运行时异常,当应用程序试图在需要对象的地方使用 null 时,抛出该异常。这种情况包括:

    • 调用 null 对象的实例方法。
    • 访问或修改 null 对象的字段。
    • 将 null 作为一个数组,获得其长度。
    • 将 null 作为一个数组,访问或修改其时间片。
    • 将 null 作为 Throwable 值抛出。

    遇到该异常,如果又没有try/catch语句,就将导致应用程序终止。从应用程序线上问题统计中发现,空指针异常是比较常见的。所以防止空指针异常非常有必要。


    防止空指针异常

    要防止空指针异常,可以从三方面来入手:

    1. Java 注解辅助
    2. 引入 Java 8 中的 Optional 类型
    3. 使用 Kotlin 区分可空类型和非空类型

    Java 注解

    Java 注解可以用来表达值的可空性,帮助静态扫描工具找到可能抛出 NullPointerException 的地方。

    Android 提供了可空注解@NonNull 和 非空注解@NonNull

        @Nullable
        public Fragment findFragment(@NonNull FragmentActivity activity, @NonNull String tag) {
            FragmentManager fragmentManager = activity.getSupportFragmentManager();
            return fragmentManager.findFragmentByTag(tag);
        }
    

    在使用者使用的时候,如果没有正确的使用可空类型和非空类型,就会得到编译器的提示:
    在这里插入图片描述
    在这里插入图片描述
    所以注解只能用来提示使用者在使用的时候是可空类型还是非空类型,但并不能限定使用者传递的是可空类型还是非空类型。

    Java 8 中的 Optional 类型

    Java 8 中引入了 Optional 类型,它是一个可能包含或不包含非空值的容器对象,用更优雅的方式来防止 NullPointerException

    Optional 类 提供的主要方法:

    方法名字表示意思
    of返回具有 Optional的当前非空值的Optional。
    ofNullable返回一个 Optional指定值的Optional,如果非空,则返回一个空的 Optional 。
    isPresent如果存在值,则返回 true ,否则为 false 。
    get如果 Optional中存在值,则返回值,否则抛出 NoSuchElementException 。
    map如果存在值,则应用提供的映射函数,如果结果不为空,则返回一个Optional结果的Optional 。 否则返回一个空的Optional 。
    flatMap如果一个值存在,应用提供的Optional映射函数给它,返回该结果,否则返回一个空的Optional 。 这种方法类似于map(Function) ,但是提供的映射器是一个结果已经是Optional映射器,如果被调用, flatMap不会用额外的Optional 。
    orElse返回值如果存在,否则返回 other 。

    测试例子:

    创建一个User类:

    public class User {
    	private String nickname;
    	private Address address;
    
    	public User() {
    	}
    
    	public Optional<Address> getAddress() {
    		return Optional.ofNullable(address);
    	}
    
    	public void setAddress(Address address) {
    		this.address = address;
    	}
    
    	public String getNickname() {
    		return nickname;
    	}
    
    	public void setNickname(String nickname) {
    		this.nickname = nickname;
    	}
    
    }
    

    获取 Nickname:

    	private String getUserNickname(User user) {
    		return Optional.ofNullable(user).map(new Function<User, String>() {
    
    			@Override
    			public String apply(User t) {
    				return t.getNickname();
    			}
    		}).orElse("default");
    	}
    	
    	String nickname = getUserNickname(null);
        //运行结果:nickname="default"
    

    ofNullable 方法主要将对象包装成一个Optional对象(用的就是组合):

    
        private static final Optional<?> EMPTY = new Optional<>();
    
        private final T value;
    
        private Optional() {
            this.value = null;
        }
    
        public static<T> Optional<T> empty() {
            @SuppressWarnings("unchecked")
            Optional<T> t = (Optional<T>) EMPTY;
            return t;
        }
    
        private Optional(T value) {
            this.value = Objects.requireNonNull(value);
        }
    
        public static <T> Optional<T> of(T value) {
            return new Optional<>(value);
        }
    
        public static <T> Optional<T> ofNullable(T value) {
            return value == null ? empty() : of(value);
        }
    

    map 方法会检测当前值是否为空,如果为空就返回一个空的Optional对象,否则将接口Function的回调方法apply的返回值包装成一个新的Optional对象。

        public boolean isPresent() {
            return value != null;
        }
    
        public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
            Objects.requireNonNull(mapper);
            if (!isPresent()) {
                return empty();
            } else {
                return Optional.ofNullable(mapper.apply(value));
            }
        }
    

    orElse 方法检测当前值是否为空,如果为空,就返回传入的默认值:

        public T orElse(T other) {
            return value != null ? value : other;
        }
    

    从上面可以 看出,使用 Optional 类,主要是将对象包装成 Optional 对象来防止 NullPointerException

    Optional 类 还可以解决在实际开过程中,经常遇到的一些链式调用引起的NullPointerException

    下面通过User 类,获取 Country 类 的属性,一般会这样写:

    		String countryName = null;
    		Address address = user.getAddress();
    		if(address!=null) {
    			Country country = address.getCountry();
    			if(country !=null) {
    				countryName = country.getName();
    			}
    		}
    

    上面代码中不得不对过程中遇到的每一个对象做判空处理,如果调用链很长,代码就会越不友好。修改user.getAddress()address.getCountry() 方法的返回值:

    	public Optional<Address> getAddress() {
    		return Optional.ofNullable(address);
    	}
    
    	public Optional<Country> getCountry() {
    		return Optional.ofNullable(country);
    	}
    

    使用Optional 类 ,将链式调用中遇到的任何一个对象都包装成 Optional对象:

    	private String  getCountryName(User user) {
    		return Optional.ofNullable(user).flatMap(new Function<User, Optional<Address>>() {
    
    			@Override
    			public Optional<Address> apply(User t) {
    				return t.getAddress();
    			}
    		}).flatMap(new Function<Address, Optional<Country>>() {
    
    			@Override
    			public Optional<Country> apply(Address t) {
    				return t.getCountry();
    			}
    		}).map(new Function<Country, String>() {
    
    			@Override
    			public String apply(Country t) {
    				return t.getName();
    			}
    		}).orElse("default");
    	}
    	
    	String countryName = getCountryName(user);
    	//运行结果:countryName = "default"
    

    在上面链式方法调用中,中间如果有任何一个对象为空,都不可能抛出空指针异常。

    虽然 Optional 可以防止NullPointerException,但是代码还是很冗长,并且额外的包装接口还会影响运行时的性能。

    Kotlin

    Kotlin 区分可空类型和非空类型,并会在编译期间对可空类型和非空类型检查。

    可空类型,问号添加在类型的后面表示这个类型的变量可以存储 null 引用:

        fun findFragment(activity: FragmentActivity?, tag: String?): Fragment? {
            val fragmentManager = activity?.supportFragmentManager
            return fragmentManager?.findFragmentByTag(tag)
        }
    

    如果没有正确使用,将得到编译器的错误提示,并无法编译:
    在这里插入图片描述
    非空类型,没有问号添加在类型的后面表示这个类型的变量不可以存储 null 引用:

        fun findFragment(activity: FragmentActivity, tag: String): Fragment? {
            val fragmentManager = activity.supportFragmentManager
            return fragmentManager?.findFragmentByTag(tag)
        }
    

    同样,如果没有正确使用,将得到编译器的错误提示,并无法编译:
    在这里插入图片描述
    可空类型和非空类型在运行时并没有什么区别,只是在编译期间对类型进行检查。所以,使用Kotlin 的可空类型并不会在运行时带来额外的开销。

    对于可空类型的判断,Kotlin 还提供了安全调用运算符?.Elvis 运算符?:安全转换符as?非空断言!!来防止空指针异常,这里不再一一介绍。


    总结

    防止空指针异常,有三种方法:使用Java 注解辅助,引入 Java 8 中的 Optional 类型, 使用 Kotlin 区分可空类型和非空类型。使用Java 注解辅助,只能提示使用者在使用的时候是可空类型还是非空类型,并不能限定使用者传递的是可空类型还是非空类型;引入 Java 8 中的 Optional 类型,能防止空指针异常,但是代码还是很冗长,并且额外的包装接口还会影响运行时的性能;使用 Kotlin 区分可空类型和非空类型,会在编译期间对类型进行检查,并且不会在运行时带来额外的开销。总之,使用 Kotlin 是防止空指针异常的最好方式。

    展开全文
  • java空指针异常-解决办法

    千次阅读 2019-09-09 15:45:53
    空指针异常一般都是由于没有对创建的对象进行初始化,即指向的对象为空(null),当操作这个对象时,就会报空指针异常。当操作一个对象不存在的方法时,也会报空指针异常。 解决办法:根据报错信息,检查设置的对象...
  • java避免空指针异常 空指针异常是Java中最常见,最烦人的异常。 在这篇文章中,我想避免这种不希望的异常。 首先让我们创建引发空指针异常的示例 private Boolean isFinished(String status) { if (status....
  • 关于空指针

    千次阅读 2018-06-14 22:34:30
    臭名昭著的空指针到底是什么?... 永远也不能得到空指针, 同样对 malloc() 的成功调用也不会返回空指针, 如果失败, malloc() 的确返回空指针, 这是空指针的典型用法: 表示 "未分配" 或者...
  • Java空指针异常的几种情况

    千次阅读 2020-05-11 23:42:44
    Java空指针异常的几种情况 NullPointerException 说法一 NullPointerException由RuntimeException派生出来,是一个运行级别的异常。意思是说可能会在运行的时候才会被抛出,而且需要看这样的运行级别异常是否会...
  • 空指针异常主要原因以及解决方案

    万次阅读 2020-03-23 00:14:44
    空指针异常产生的主要原因如下: (1)当一个对象不存在时又调用其方法会产生异常obj.method() // obj对象不存在 (2)当访问或修改一个对象不存在的字段时会产生异常obj.method() // method方法不存在 (3)字符串...
  • 二叉树空指针个数的理解

    千次阅读 2020-11-08 12:58:24
    引言 二叉树在使用链式存储时,每一...空指针的个数为n+1是众所周知的事,虽然不论哪种证明方法都仅仅是恒等式变形的结果,但去分析等式两边的意义是十分有助于理解关系本质的。 几种理解 1.以节点数为切入点 ...
  • 传入的实体类 ``` public class F728040Req { ...三个值全部都是有的,SQL语句也没有问题,放数据库就能跑,但就是报空指针的错误,即使把参数全都用常量替代,直接放数据库能成功,但这就是报空指针
  • java空指针异常解决Java programming language provides the Null Pointer Exception type in order to handle object creation related errors and misuse. In this tutorial, we will learn what is Null Pointer ...
  • 1、指针是地址,而不是具体的标量值,这是指针的精髓,不管是一级指针、二级 指针、 整型指针、浮点数指针、结构体指针等等等等所有类型的指针,内容都是个地址,而指针本身当然也是有地址的,而且容易忽略的是,...
  • 空指针引用故障(空指针解引用)

    千次阅读 2019-01-09 18:52:45
    C语言中的指针机制使得它灵活高效,但由于指针操作不当产生的动态内存错误也有很多,比如内存泄漏(Memory Leakage)、内存的重复释放、空指针解引用(NullPointer Dereference)。 其中空指针引用故障,也叫空指针解...
  • 输入为:二叉树的先序遍历结果(用&代表空指针的遍历结果) 例如:①输入a&&则返回的指针指向的二叉树应该就是仅有一个节点,值为a. ②输入12&&3&&则返回的指针指向的二叉树应该就是,根节点(1),左子树只有一...
  • Java应用中抛出的空指针异常是解决空指针的最好方式,也是写出能顺利工作的健壮程序的关键。 避免Java中的空指针异常的常用技巧(同时避免大量的非空检查): 1) 从已知的String对象中调用equals()和...
  • 空指针异常 NullPointException

    千次阅读 2019-08-26 23:00:11
    空指针异常 NullPointException 空指针异常,是运行时异常,及时编写代码时出现了空指针异常,编译器(javac) 会编译通过不报错,但是运行时Runtime阶段会抛出NullPointException 一.空指针异常可能的情况 1.调用null...
  • 空指针异常是什么意思?        这里我们首先要明确什么是指针,指针指的是什么? 指针:我所理解的指针指的是java程序中的对象 那什么是空?      &...
  • 前者返回一个流对象,后者如果出来的值是空的,再.findfirst()等其他的方法就会出现空指针,所以最好给map的取值结果加个默认值,去stream.map(aa-> Maputils.getstring(aa,key,默认值))
  • 空指针常见原因和解决办法

    千次阅读 2021-01-22 11:22:09
    容易出现空指针异常的场景 在调用对象方法时 比如处理字符串常用的replace方法,数组的length方法,map的size方法等等; str.replace(…) 如果str为null,这里就直接空指针了 判断一个str是否等于"test",你直接str...
  • java 避免空指针异常

    千次阅读 2018-07-05 18:17:37
    Java应用中抛出的空指针异常是解决空指针的最好方式,也是写出能顺利工作的健壮程序的关键。熟话说“预防胜于治疗”,对于这么令人讨厌的空指针异常,这句话也是成立的。值得庆幸的是运用一些防御性的编码技巧,跟踪...
  • 解决命令行下报NullPointException异常 java环境变量配置
  • Java造成空指针异常的原因

    千次阅读 2020-05-29 11:24:13
    map.get("aa").toString() map取值为null,转字符串会报空指针

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 734,977
精华内容 293,990
关键字:

空指针