JAVA与SQL 中的null与NULL解析
作者:FXBStudy 发布时间:2023-06-23 11:51:18
一、前言
null与NULL不都是表示空值吗?这有什么值得深入讨论的的?首先你在编写Java代码时使用过NULL吗?大概用IDE用习惯了,自动给生成以及纠正没有注意过也很正常。同样道理在数据库中的疑问我就不提问了。如果你不了解它们之间的区别,在Java操作数据库的时候,很有可能会出现一系列的BUG。
看下面我做的一个简单的测试:
实验一:使用null
实验二:使用NULL
预备知识:当声明了变量或者类却没有赋初值,Java会自动进行赋初值。赋值原则是整数类型int、byte、short、long的自动赋值为0,带小数点的float、double自动赋值为0.0,boolean的自动赋值为false,其他各种引用类型变量自动赋值为null。
二、Java中的null
首先声明,null是Java的关键字,并且大小写是敏感的。
Java是一种面向对象的高级编程语言,但是null本身不是对象,也不是Objcet的实例,null表示类或对象(包括字符串)是不存在的,不代表任何对象或实例,可以将null赋给引用类型变量,但不可以将null赋给基本类型变量;
与其对应,也是最为常见的一个异常:java.lang.NullPointerException
引发这个异常的情况有:
调用 null 对象的实例方法
访问或修改 null 对象的字段
将 null 作为一个数组,获得其长度
将 null 作为一个数组,访问或修改其时间片
将 null 作为 Throwable 值抛出
上面的所有情况都是null所引发的,只知其然,而不知其所以然是在开发中经常碰到这个异常的原因,要想尽量避免它,就必须深入的了解它。
2.1 大小写
因为null是大小写敏感的,所以Null,NULL等这类写法在Java代码中都是非法的。但是现在的IDE的功能太过于强大了,会自动修正或者填充,所以使用IDE基本不必考虑这个问题。
思考:因为IDE过于方便,使得我们会忽略很多细节,对于初学者而言建议从最简单的文本编辑器与命令行的方式进行学习。不要出现都学得挺多了,但是连一个main函数都敲不出来,那就尴尬了。
2.2 默认的初值
null是任何引用类型的默认值,不严格的说是所有object类型的默认值。这对所有变量都是适用的,如成员变量、局部变量、实例变量、静态变量(但当你使用一个没有初始化的局部变量,编译器会警告你)。
2.3 类型
null 既不是对象也不是一种类型,它仅是一种特殊的值,你可以将其赋予任何引用类型,你也可以将null转化成任何类型。
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 可以赋值给引用变量,你不能将 null 赋给基本类型变量,例如int、double、float、boolean。但是可以赋值给他们的包装类类型,如上面的代码中使用的。
正如这个特性,也会导致一个异常的发生:先将 null 赋给包装类型,然后将包装类型赋值给基本类型,编译器完全是可以通过的,但是运行时会抛出空指针异常。
当然了编程的时候谁闲着没事这样做,但是很有可能无意中却这样做了,所以一定要谨慎。
这个异常时在自动拆箱的过程中,关于自动拆箱装箱可以参考《JAVA 包装类型 及 易错陷阱》。
2.4 对null的检查
== 与 !=
这种比较是最为常用的比较,但是也有其缺点。
something == null,这种写法完全没有任何异常,但是很容易失误导致错误。因为这种写法如果少一个等号,这样就变成了赋值,而代码仍然是可以正常运行的。所以更加安全的写法是 null == something,当我们将等号少写一个,会直接报异常,所以这种写法更加安全。
注意:不能使用其他算法或者逻辑操作,例如小于或者大于。
instanceof
Java 中的 instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例。instanceof 通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。
如果使用了带有 null 值的引用类型变量,instanceof 操作将会返回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");
}
输出结果为:
iAmNull is NOT an instance of Integer
equals
在比较的时候除了 == 之外,我们经常会想到的就是 Object 类中就有的 equals() 方法,虽然许多类继承并覆盖了这个方法,但是大致上都差不多。因为Java中基本都是对象,所以都可以对其进行调用,一再强调null的类型(详见第一条),something.equals(null),当something不是null时一切正常,可是如果是null的话,会抛出空指针异常,你要是不嫌麻烦,完全可以捕获这个空指针异常,并直接做 null 处理,但是不建议。
public class ceshi{
static String a=null;
public static void main(String args[]){
if(a.equals(null)){
System.out.println("==");
}
}
}
输出结果
Exception in thread "main" java.lang.NullPointerException
at ceshi.main(ceshi.java:6)
2.5 静态方法
你可能知道不能调用非静态方法来使用一个值为 null 的引用类型变量。它将会抛出空指针异常,但是你可能不知道,你可以使用静态方法来使用一个值为 null 的引用类型变量。因为静态方法使用静态绑定,不会抛出空指针异常。
public class ceshi{
public static void main(String args[]){
ceshi 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");
}
}
运行结果:
I am static method, can be called by null reference
Exception in thread "main" java.lang.NullPointerException
at ceshi.main(ceshi.java:6)
我们可以看到对象完全没有实例化但是却正常的执行了其静态的方法,这其实也不奇怪,静态方法完全可以使用类名直接使用,只不过绕了个弯,编译器,所以不足为奇。
2.6 参数传递
我们可以将null传递给方法使用,这时方法可以接收任何引用类型,例如public void print(Object obj)可以这样调用print(null)。从编译角度来看这是可以的,但结果完全取决于方法。Null安全的方法,如在这个例子中的print方法,不会抛出空指针异常,只是优雅的退出。如果业务逻辑允许的话,推荐使用null安全的方法。
2.7 用途
判断一个引用类型数据是否null。 用==来判断。
释放内存,让一个非null的引用类型变量指向null。这样这个对象就不再被任何对象应用了。等待JVM垃圾回收机制去回收。
三、SQL的NULL
在数据库中NULL表示 未知的。
NULL不等于零或空格,NULL 值不视作大于、小于或等于任何其它值。当一个变量、列或常量具有NULL值时,它的值是未知的、不确定的。“未知的”与空白或零或布尔值FALSE完全不同。“未知的”意味着该变量根本没有值,因此不能与其他变量直接进行比较。判断某列或者变量为 NULL 是只能用IS(NOT) NULL 去判断他的返回值是 true 还是 false。
NULL参与排序时总是作为最小值存在,即ORDER BY COL ASC时COL为NULL的行在最前面,反之在最后面。
NULL值是未知的,且占用空间,不走索引,DBA建议建表的时候最好设置字段是NOT NULL 来避免这种低效率的事情的发生。
NULL值具有以下三个规则:
一个NULL不与其他任何值相等;一个NULL不与其他任何值不等;
在对一个NULL值应用函数时,一般都会得到一个NULL值作为结果。
一般而言,只要执行涉及一个或多个NULL值的比较操作,那个比较的结果也是NULL值,它不同于TRUE或FALSE,因而这样的比较除了失败,没有任何帮助作用。
注意空值与NULL之间的差异:
在进行count()统计某列的记录数的时候,如果采用的NULL值,会被系统自动忽略掉,但是空值是会进行统计到其中的。(count(*)会将NULL统计上)
判断NULL 用IS NULL 或者 IS NOT NULL,SQL 语句函数中可以使用 ifnull() 函数来进行处理,判断空字符用 = 或者 <> 来进行处理。
对于MySQL特殊的注意事项,对于timestamp数据类型,如果往这个数据类型插入的列插入NULL值,则出现的值是NULL。插入空值,则会出现 '0000-00-00 00:00:00'
三、Java与SQL
Java中的 null 只能赋值给各种引用类型,不能赋值给基本类型,然而SQL中的可以将NULL赋给任何数据类型,因此这就会导致异常的出现。
这样一来,我们从数据库中读取字段的值后,在Java程序中如何判断读取的值是否为 null 呢?用 name==null 吗?显然不行,==是判断两个变量或实例是不是指向同一个内存空间,除非这个name是String类型的。而equals()方法呢?是判断两个变量或实例所指向的内存空间的值是不是相同。
java.sql.ResultSet接口中的boolean wasNull()方法可以解决这个问题:boolean wasNull();报告最后一个读取的列是否具有值 SQL NULL。
注意,必须首先对列调用一个获取方法尝试读取其值,然后调用wasNull ()方法查看读取的值是否为 SQL NULL。如果发生数据库访问错误将抛出SQLException。
来源:https://fanxiaobin.blog.csdn.net/article/details/52817928
猜你喜欢
- 最近在公司,项目不是很忙了,偶尔看见一个兄台在CSDN求助,帮忙要一个自定义的渐变色进度条,我当时看了一下进度条,感觉挺漂亮的,就尝试的去自
- spring boot框架中已经集成了redis,在1.x.x的版本时默认使用的jedis客户端,现在是2.x.x版本默认使用的lettuc
- 所谓文件的断点续传,就是一个线程传输文件,另一个线程控制传输标识,以达到暂停文件效果、恢复文件上传的效果。本demo使用最基本的线程之间的通
- 背景在实际开发过程中,会遇到需要编写各类打印模板模板的需求,当然这些在WPF开发中更为常见,但是使用XAML写编辑的打印模板又不能直接发送给
- 前言前面的篇幅里有提到通过InitializingBean和Disposable等接口可以对bean的初始化和销毁做一些自定义操作,那么有一
- 1.封装什么是封装,谈谈自己对封装的理解,封装就是将类的信息(比如说类的属性)隐藏在类的内部,不允许外部程序直接访问。此时就要提到一个关键字
- 本文实例演示了visual C#下一个类的定义及实现方法,虽然是一个较为基础的C#代码实例,对于新手来说仍然有很好的参考价值。具体的实例代码
- 在一次源码查看ThreadGroup的时候,看到一段代码,为以下:/* * @throws NullPointer
- 包含默认敏感词过滤和自定义敏感词过滤。导入依赖<dependency> <groupId>com.git
- 路径分隔符:Windows下是“\”unix|linux下是“/”考虑到程序的可移植性,创建文件时建议大家选用"/",因
- 本文实例为大家分享了Java通过Fork/Join优化并行计算的具体代码,供大家参考,具体内容如下Java代码:package Thread
- 1.项目介绍这是一款基于 Java 开发的移动端安卓小游戏——大家来拼图2.项目原理把选定的一张图片
- 需要引入命名空间:using System;using System.Text;解码: public static string
- 笔者计划为大家介绍分布式文件系统,用于存储应用的图片、word、excel、pdf等文件。在开始介绍分布式文件系统之前,为大家介绍一下使用本
- 本文实例为大家分享了java实现Dijkstra算法的具体代码,供大家参考,具体内容如下1 问题描述何为Dijkstra算法?Dijkstr
- tomcat中文乱码问题这几天测试的兄弟发现了项目中存在乱码问题 经过排查发现是tomcat中的问题 于是在server.xml中添加了如下
- 实践过程效果代码public partial class Form1 : Form {
- 众所周知,当你点击一个超链接进行跳转时,WebView会自动将当前地址作为Referer(引荐)发给服务器,因此很多服务器端程序通过是否包含
- 一、国际化准备资源文件,资源文件的命名格式如下:baseName_language_country.propertiesbaseName_l
- 目录前言if-thenif-then-elseswitch使用 Stringwhiledo-whileforbreakcontinueret