用JDBC做批量导入报错,在提交的时候,空指针异常?

PS:这里要说两句了,拷贝过来的文章标题清除了格式,保存还是失败了,编辑器的问题吗?感觉编辑器怎么用着很不舒服。

  回归正文,Java空指针异常带来不少问题和麻烦,现在Java8提供了Optional特性,我们可以试试了。

  有大牛说:“如果没有处理过空指针异常(NullPointerException),就不能算是真正的Java程序员”。开个玩笑的说法,不过可以看出空指针异常存在的普遍性,空(null)引用是许多问题的根源,因为经常将null表示一个空值。Java SE8引进了一个新类叫java.util.Optional,它将缓解这些问题的发生。

 下面让我们从一个小例子中看看null的危害性。如下图1示,用一个嵌入对象结构代表一台计算机:

  看着上图,看看下面的代码可会会发生什么样的问题呢?

    哈哈,上面一一行代码看起来合情合理(译者注:实际中我们会不经意间的自然流畅的写出这样的代码)。然而,许多计算机(比如:Respberry Pi)实际上没有搭载声卡,所以getSoundCard()返回的结果是什么呢?

 通常的实践(译者注:这也是一个不好的实践,我所在的公司Java开发规范文档中有明确的一条规定就是不能返回null)做法是返回一个空引用来表示没有声卡。不幸的是,这意味着调用getUSB()方法时将试图返回一个空引用的USB端口,最终将返回一个运行时的空指针异常(NullPointerException),并且进一步阻止程序继续运行。想像一下,如果你的程序运行在客户的机器上,毫无疑问,在客户看来你的程序是失败的。

     追随计算机编程的发展历史背景,计算机科学巨匠-Tony Hoare 曾经写道:"在1965年发明了空(null)引用,我把它称为百万美元的错误——我曾经禁不住空引用的诱惑,因为它太容易实现了。"

     我们如何阻止这种无意识的空指针异常呢?你可以主动的添加检查来阻止空引用,如下代码清单1:

   然而,你很快就看到了代码清单1中的代码由于嵌套坚持变得丑陋难看。很不幸,我们需要许多这样类似的样板代码来确保不得到一个NullPointerException.此外,我们会抱怨这种检查妨碍了业务逻辑,事实上,它们会使我们的程序可读性下降。

   此外,上面这种方式是一个容易出错的过程,如果你忘记了检查一个可能为null的属性嗯?我在文中用null来表示一个不存在的值是一个错误的方法。我们需要一个更好的方式来表示一个值存在和不存在的模型。

  根据上文,我们简要看看其他编程语言是如何提供这种处理模型的。

有什么可以代替Null呢?

 如Groovy语言有安全导航操作符”?.“表示,其能安全的操作潜在的空引用。(注:Groovy实现之后不久,C#也提供了,有人也在JavaSE7中提议过,但是最终没能发行。),它的工作方式如下:

   此外Groovy也包含了Elvis操作符"?:",(哈哈,你从侧面看看这个符合,你可能会认为这个猫王的头发)。当需要一个默认值的时候,它可以被用来作为一个简单的例子。如下面代码,如果表达式用安全导航操作符返回null,这个默认值就是”UNKNOWN“,否则它将返回版本号。

其它函数语言中,如Haskell和Scala,提出不同的观点。Haskell包含一个Maybe类型,它包括了一个可选值。一个Maybe类型的值包含了指定类型的值或者什么也没有。没有空引用的概念。Scala有一个相似的结构体Option[T]来封装T类型的值存在或不存在。你可以明确的在一个可选类型是进行存在或不存在值检查。当然不能忘记对“null"复杂检查,因为这是系统类型。

   上面说了这么多,听起来真的很抽象,下面看看JavaSE8中是如何处理这个问题的。

   JavaSE8引入了一个新的类 java.util.Optional<T>,它的灵感源于Haskell和Scale的启发,它封装了一个可选值。下面代码清代2和图2,你可以把Optional看作一个容器,里面包含一个存在的值或者不存在的值(可选,不可选),如图2.


 下面我们可以用Optional来更新我们的模型,如下代码清代2:

     从上面代码(代码清单2)中可以清楚的看出,一个计算机可能有或者肯能没有声卡(因为可选),此外还能看出声卡的USB端口也是可选的。这是一种金币,这个新的模型清楚的反映出来出来给定的值是否可以不存在,类似的实现在Guava的类库中也有实现。

    但是实际上你并不想去处理Optional<SoundCard>这个对象,你想要获取的是USB端口的版本号。简而言之,Optional类提供了处理值存在或者不存在的方法。相比于空引用的优势在于Optional显式的强制你考虑值不存在的可能情况,这样做的后果是你将避免了空指针异常的发生。

   需要重要的注意一点是Optional并不是替代空引用,相反,它的目的在于帮助设计更可理解的API和可阅读的方法。你可以选择Optional来告诉自己希望一个可选的值,这样迫使你积极的打开一个不存在的值的可选值。

  不多废话,上代码。我们先看看null-check模式使用Optional的重写。在文章结尾我们将明白如何使用Optional了。下面是代码清代1中的的null-check重写代码:

首先,怎么创建Optional对象能?下面采用几种方式:

如果值存在,可以继续做事
    现在有一个Optional对象,你可以访问方法,明确的显示处理值存在与否。以前,我们用null-check,如下:

    你将不用显式的进行null-check,它将有系统类型强制实施。如果Optional对象是空,上述代码中将什么都不打印。

    你可以使用isPresent()方法来在Optional对象中查看值是否存在。此外,如果存在,它的get()方法及将返回Optional中包含的值。否则,它将抛出NoSuchElementException。这两个方法组合使用,能否阻止异常发生。

  然而,这是Optional不推荐的用法(因为它与null-check相对并没有多少提升),下面有很多通用的替代方式。

   一个典型的方式是在你确定操作结果返回是null的情况下设定默认值。通常你可以使用三目运算操作来做到这一点。


   使用Optional对象,你可以使用orElse()方法来重写上面代码,如果Optional是空的时候,它提供了一个默认值。


  相似的方式,你可以使用orElseThrow()方法,如果Optional是空的时候,它提供一个默认值,即就是一个异常对象。

参见google Guava库的API: (有时可能无法访问)可以参考这个:

}

今天要谈的主题是关于求职,求职是在每个技术人员的生涯中都要经历多次。对于我们大部分人而言,在进入自己心仪的公司之前少不了准备工作,有一份全面细致面试题将帮助我们减少许多麻烦。在跳槽季来临之前,特地做这个系列的文章,一方面帮助自己巩固下基础,另一方面也希望帮助想要换工作的朋友。

封装,继承,多态,这个应该是人人皆知,有时候也会加上抽象。

允许不同类对象对同一消息做出响应,即同一消息可以根据发送对象的不同而采用多种不同的行为方式(发送消息就是函数调用)。主要有以下优点:

  1. 可替换性:多态对已存在代码具有可替换性

  2. 可扩充性:增加新的子类不影响已经存在的类结构

  3. 接口性:多态是超类通过方法签名,向子类提供一个公共接口,由子类来完善或者重写它来实现的。

这点在四种引用类型中已经做了解释,这里简单说明一下即可: 
虽然 WeakReference 与 SoftReference 都有利于提高 GC 和 内存的效率,但是 WeakReference ,一旦失去最后一个强引用,就会被 GC 回收,而软引用虽然不能阻止被回收,但是可以延迟到 JVM 内存不足的时候。

为什么要有不同的引用类型

不像C语言,我们可以控制内存的申请和释放,在Java中有时候我们需要适当的控制对象被回收的时机,因此就诞生了不同的引用类型,可以说不同的引用类型实则是对GC回收时机不可控的妥协。有以下几个使用场景可以充分的说明:

  1. 利用软引用和弱引用解决OOM问题:用一个HashMap来保存图片的路径和相应图片对象关联的软引用之间的映射关系,在内存不足时,JVM会自动回收这些缓存图片对象所占用的空间,从而有效地避免了OOM的问题.

  2. 通过软引用实现Java对象的高速缓存:比如我们创建了一Person的类,如果每次需要查询一个人的信息,哪怕是几秒中之前刚刚查询过的,都要重新构建一个实例,这将引起大量Person对象的消耗,并且由于这些对象的生命周期相对较短,会引起多次GC影响性能。此时,通过软引用和 HashMap 的结合可以构建高速缓存,提供性能。

==是运算符,用于比较两个变量是否相等,而equals是Object类的方法,用于比较两个对象是否相等。默认Object类的equals方法是比较两个对象的地址,此时和==的结果一样。换句话说:基本类型比较用==,比较的是他们的值。默认下,对象用==比较时,比较的是内存地址,如果需要比较对象内容,需要重写equal方法。

hashCode()是Object类的一个方法,返回一个哈希值。如果两个对象根据equal()方法比较相等,那么调用这两个对象中任意一个对象的hashCode()方法必须产生相同的哈希值。
如果两个对象根据eqaul()方法比较不相等,那么产生的哈希值不一定相等(碰撞的情况下还是会相等的。)



如何判断一个对象是否应该被回收

这就是所谓的对象存活性判断,常用的方法有两种:/postedit/

poll() 和 remove() 都是从队列中取出一个元素,但是 poll() 在获取元素失败的时候会返回空,但是 remove() 失败的时候会抛出异常。

PriorityQueue 是一个优先级队列,保证最高或者最低优先级的的元素总是在队列头部,但是 LinkedHashMap 维持的顺序是元素插入的顺序。当遍历一个 PriorityQueue 时,没有任何顺序保证,但是 LinkedHashMap 课保证遍历顺序是元素插入的顺序。

WeakHashMap 的工作与正常的 HashMap 类似,但是使用弱引用作为 key,意思就是当 key 对象没有任何引用时,key/value 将会被回收。

最明显的区别是 ArrrayList底层的数据结构是数组,支持随机访问,而 LinkedList 的底层数据结构是双向循环链表,不支持随机访问。使用下标访问一个元素,ArrayList 的时间复杂度是 O(1),而 LinkedList 是 O(n)。

  1. Array可以容纳基本类型和对象,而ArrayList只能容纳对象。

 
 

Comparable 接口用于定义对象的自然顺序,而 comparator 通常用于定义用户定制的顺序。Comparable 总是只有一个,但是可以有多个 comparator 来定义对象的顺序。

详情直接参见上面的白话异常机制,不做解释了。

VM 中堆和栈属于不同的内存区域,使用目的也不同。栈常用于保存方法帧和局部变量,而对象总是在堆上分配。栈通常都比堆小,也不会在多个线程之间共享,而堆被整个 JVM 的所有线程共享。

  1. 基本数据类型比变量和对象的引用都是在栈分配的。

  2. 堆内存用来存放由new创建的对象和数组。

  3. 类变量(static修饰的变量),程序在一加载的时候就在堆中为类变量分配内存,堆中的内存地址存放在栈中。

  4. 实例变量:当你使用java关键字new的时候,系统在堆中开辟并不一定是连续的空间分配给变量,是根据零散的堆内存地址,通过哈希算法换算为一长串数字以表征这个变量在堆中的”物理位置”,实例变量的生命周期–当实例变量的引用丢失后,将被GC(垃圾回收器)列入可回收“名单”中,但并不是马上就释放堆中内存。

  5. 局部变量: 由声明在某方法,或某代码段里(比如for循环),执行到它的时候在栈中开辟内存,当局部变量一但脱离作用域,内存立即释放。


java当中采用的是大端还是小端?

XML解析的几种方式和特点

  • DOM:消耗内存:先把xml文档都读到内存中,然后再用DOM API来访问树形结构,并获取数据。这个写起来很简单,但是很消耗内存。要是数据过大,手机不够牛逼,可能手机直接死机

  • SAX:解析效率高,占用内存少,基于事件驱动的:更加简单地说就是对文档进行顺序扫描,当扫描到文档(document)开始与结束、元素(element)开始与结束、文档(document)结束等地方时通知事件处理函数,由事件处理函数做相应动作,然后继续同样的扫描,直至文档结束。

  • PULL:与 SAX 类似,也是基于事件驱动,我们可以调用它的next()方法,来获取下一个解析事件(就是开始文档,结束文档,开始标签,结束标签),当处于某个元素时可以调用XmlPullParser的getAttributte()方法来获取属性的值,也可调用它的nextText()获取本节点的值。



}

本文介绍了Spark在执行jdbc保存时给出空指针异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

当我执行以下代码行时,我得到以下堆栈跟踪:

我尝试调试它,我相信查询执行会给出空指针异常

我不确定这意味着什么.我在我的本地机器上运行它,而不是在任何集群上

我想通了(Alteast 我认为这就是原因).对于面临类似情况的其他人:在创建表时,我将每一列都设置为空,因此我认为它允许在表中插入空值.但是我正在构建数据框的 Avro 模式具有可空性 = false.因此,dataframe.create 正在读取 null 并因此引发 NPE 错误.当我执行 Dataframe.write 时出现错误(这让我认为这是一个 jdbc 错误)但实际的 NPE 在创建数据帧时发生

这篇关于Spark在执行jdbc保存时给出空指针异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

}

我要回帖

更多关于 邮件规则导入后报错 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信