JAVA与SQL 中的null与NULL解析

目录
  • 一、前言
    • 看下面我做的一个简单的测试:
  • 二、Java中的null
    • 引发这个异常的情况有:
    • 2.1 大小写
    • 2.2 默认的初值
    • 2.3 类型
    • 2.4 对null的检查
      • == 与 !=
      • instanceof
      • equals
    • 2.5 静态方法
    • 2.6 参数传递
    • 2.7 用途
  • 三、SQL的NULL
    • NULL值具有以下三个规则:
    • 注意空值与NULL之间的差异:
  • 三、Java与SQL

一、前言

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。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • JAVA null详解

    前言 对于Java程序员来说,null是令人头痛的东西.时常会受到空指针异常(NPE)的骚扰.连Java的发明者都承认这是他的一项巨大失误.Java为什么要保留null呢?null出现有一段时间了,并且我认为Java发明者知道null与它解决的问题相比带来了更多的麻烦,但是null仍然陪伴着Java. 我越发感到惊奇,因为java的设计原理是为了简化事情,那就是为什么没有浪费时间在指针.操作符重载.多继承实现的原因,null却与此正好相反.好吧,我真的不知道这个问题的答案,我知道的是不管null

  • Java中关于Null的9个解释(Java Null详解)

    对于Java程序员来说,null是令人头痛的东西.时常会受到空指针异常(NPE)的骚扰.连Java的发明者都承认这是他的一项巨大失误.Java为什么要保留null呢?null出现有一段时间了,并且我认为Java发明者知道null与它解决的问题相比带来了更多的麻烦,但是null仍然陪伴着Java. 我越发感到惊奇,因为java的设计原理是为了简化事情,那就是为什么没有浪费时间在指针.操作符重载.多继承实现的原因,null却与此正好相反.好吧,我真的不知道这个问题的答案,我知道的是不管null被Ja

  • 在 SQL 语句中处理 NULL 值的方法

    在日常使用数据库时,你在意过NULL值么? 其实,NULL值在数据库中是一个很特殊且有趣的存在,下面我们一起来看看吧: 在查询数据库时,如果你想知道一个列(例如:用户注册年限 USER_AGE)是否为 NULL,SQL 查询语句该怎么写呢? 是这样: SELECT * FROM TABLE WHERE USER_AGE = NULL 还是这样? SELECT * FROM TABLE WHERE USER_AGE IS NULL 当然,正确的写法应该是第二种(WHERE USER_AGE IS

  • 详解mysql不等于null和等于null的写法

    1.表结构 2.表数据 3.查询teacher_name字段不能等于空并且也不能等于空字符 SELECT * FROM sys_teacher WHERE teacher_name IS NOT NULL AND teacher_name <>'' 查询结果: 4.查询teacher_name字段等于null或等于空字符 SELECT * FROM sys_teacher WHERE teacher_name = '' OR teacher_name IS NULL 查询结果: 到此这篇关于详

  • JAVA与SQL 中的null与NULL解析

    目录 一.前言 看下面我做的一个简单的测试: 二.Java中的null 引发这个异常的情况有: 2.1 大小写 2.2 默认的初值 2.3 类型 2.4 对null的检查 == 与 != instanceof equals 2.5 静态方法 2.6 参数传递 2.7 用途 三.SQL的NULL NULL值具有以下三个规则: 注意空值与NULL之间的差异: 三.Java与SQL 一.前言 null与NULL不都是表示空值吗?这有什么值得深入讨论的的?首先你在编写Java代码时使用过NULL吗?大概

  • Java 在PDF中添加骑缝章示例解析

    骑缝章是用于往来业务合同,以确保合同真实.有效的印章加盖方法,是一种防范风险的重要方式.在Java程序中,可以通过使用工具来辅助加盖这种骑缝章. 工具:Free Spire.PDF for Java (免费版) 工具获取及jar文件导入: 方式1:通过官网下载jar包,并解压,手动导入lib文件夹下的Spire.Pdf.jar文件. 方式2:通过创建Maven程序,在pom.xml中配置maven仓库路径并指定Free Spire.PDF for Java 的依赖,配置完成后,在IDEA中,点击

  • Oracle PL/SQL中异常高级特性示例解析

    PL/SQL(Procedural Language/SQL,过程语言/SQL)是结合了Oracel过程语言和结构化查询语言(SQL)的一种扩展语言. 优点: (1)PL/SQL具有编程语言的特点,它能把一组SQL语句放到一个模块中,使其更具模块化种序的特点. (2)PL/SQL可以采用过程性语言控制程序的结构. (3)PL/SQL有自动处理的异常处理机制. (4)PL/SQL程序块具有更好的可移植性,可移植到另一个Oracle数据库中. (5)PL/SQL程序减少了网络的交互,有助于提高程序性

  • SQL中WHERE变量IS NULL条件导致全表扫描问题的解决方法

    复制代码 代码如下: SET @SQL = 'SELECT * FROM Comment with(nolock) WHERE 1=1    And (@ProjectIds Is Null or ProjectId = @ProjectIds)    And (@Scores is null or Score =@Scores)' 印象中记得,以前在做Oracle开发时,这种写法是会导致全表扫描的,用不上索引,不知道Sql Server里是否也是一样呢,于是做一个简单的测试1.建立测试用的表结

  • Java在Excel中创建透视表方法解析

    本文内容介绍通过Java程序在Excel表格中根据数据来创建透视表. 环境准备 需要使用Excel类库工具-Free Spire.XLS for Java,这里使用的是免费版,可通过官网下载Jar包并解压,手动导入lib文件夹下的Spire.Xls.jar到Java程序:或者也可以通过Maven仓库下载导入. Java代码示例 import com.spire.xls.*; public class CreatePivotTable { public static void main(Strin

  • 深入浅析SQL中的group by 和 having 用法

    一.sql中的group by 用法解析: Group By语句从英文的字面意义上理解就是"根据(by)一定的规则进行分组(Group)". 作用:通过一定的规则将一个数据集划分成若干个小的区域,然后针对若干个小区域进行数据处理. 注意:group by 是先排序后分组! 举例说明:如果要用到group by 一般用到的就是"每"这个字, 例如现在有一个这样的需求:查询每个部门有多少人.就要用到分组的技术 select DepartmentID as '部门名称',

  • SQL 中 NULL值测试代码

    刚刚想从数据库中的表EXPERT_DETAILS中检索出修改人Modifier(类型 VARCHAR2(20),可为空)为空的那些记录,因为该字段的类型为VARCHAR2(20),我使用的SQL语句为 复制代码 代码如下: select * from expert_details twhere t.modifier = '' 没有检索出一条记录,而这与存储在该表中的记录是不相符的.后来想到即便是空字符型存储在数据库中也应该是NULL而不是''. 然后我使用下列SQL 语句,仍然没有检索出一条记录

  • SQL中IS NOT NULL与!=NULL的区别

    平时经常会遇到这两种写法:IS NOT NULL与!=NULL.也经常会遇到数据库有符合条件!=NULL的数据,但是返回为空集合.实际上,是由于对二者使用区别理解不透彻. 默认情况下,推荐使用 IS NOT NULL去做条件判断,因为SQL默认情况下对WHERE XX!= Null的判断会永远返回0行,却不会提示语法错误. 这是为什么呢? SQL Server文档中对Null值的比较运算定义了两种规则,如在SQL Server 2000中: 规则一是是ANSISQL(SQL-92)规定的Null

  • java 获取对象中为null的字段实例代码

    下面一段简单的代码给大家分享java 获取对象中为null的字段,具体代码如下所述: private static String[] getNullPropertyNames(Object source) { final BeanWrapper src = new BeanWrapperImpl(source); java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors(); Set<String> emptyNames

  • 在SQL中该如何处理NULL值

    在日常使用数据库时,你在意过NULL值么? 其实,NULL值在数据库中是一个很特殊且有趣的存在,下面我们一起来看看吧: 小伙伴想精准查找自己想看的MySQL文章?喏 → MySQL专栏目录 | 点击这里 在查询数据库时,如果你想知道一个列(例如:用户注册年限 USER_AGE)是否为 NULL,SQL 查询语句该怎么写呢? 是这样: SELECT * FROM TABLE WHERE USER_AGE = NULL 还是这样? SELECT * FROM TABLE WHERE USER_AGE

随机推荐