欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JAVA與SQL 中的null與NULL解析

 更新時(shí)間:2021年08月24日 11:29:16   作者:FXBStudy  
這篇文章主要介紹了JAVA與SQL 中的null與NULL解析,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

一、前言

null與NULL不都是表示空值嗎?這有什么值得深入討論的的?首先你在編寫Java代碼時(shí)使用過NULL嗎?大概用IDE用習(xí)慣了,自動(dòng)給生成以及糾正沒有注意過也很正常。同樣道理在數(shù)據(jù)庫中的疑問我就不提問了。如果你不了解它們之間的區(qū)別,在Java操作數(shù)據(jù)庫的時(shí)候,很有可能會(huì)出現(xiàn)一系列的BUG。

看下面我做的一個(gè)簡單的測試:

實(shí)驗(yàn)一:使用null

實(shí)驗(yàn)二:使用NULL

預(yù)備知識(shí):當(dāng)聲明了變量或者類卻沒有賦初值,Java會(huì)自動(dòng)進(jìn)行賦初值。賦值原則是整數(shù)類型int、byte、short、long的自動(dòng)賦值為0,帶小數(shù)點(diǎn)的float、double自動(dòng)賦值為0.0,boolean的自動(dòng)賦值為false,其他各種引用類型變量自動(dòng)賦值為null。

二、Java中的null

首先聲明,null是Java的關(guān)鍵字,并且大小寫是敏感的。

Java是一種面向?qū)ο蟮母呒?jí)編程語言,但是null本身不是對象,也不是Objcet的實(shí)例,null表示類或?qū)ο?包括字符串)是不存在的,不代表任何對象或?qū)嵗?,可以將null賦給引用類型變量,但不可以將null賦給基本類型變量;

與其對應(yīng),也是最為常見的一個(gè)異常:java.lang.NullPointerException

引發(fā)這個(gè)異常的情況有:

  • 調(diào)用 null 對象的實(shí)例方法
  • 訪問或修改 null 對象的字段
  • 將 null 作為一個(gè)數(shù)組,獲得其長度
  • 將 null 作為一個(gè)數(shù)組,訪問或修改其時(shí)間片
  • 將 null 作為 Throwable 值拋出

上面的所有情況都是null所引發(fā)的,只知其然,而不知其所以然是在開發(fā)中經(jīng)常碰到這個(gè)異常的原因,要想盡量避免它,就必須深入的了解它。

2.1 大小寫

因?yàn)閚ull是大小寫敏感的,所以Null,NULL等這類寫法在Java代碼中都是非法的。但是現(xiàn)在的IDE的功能太過于強(qiáng)大了,會(huì)自動(dòng)修正或者填充,所以使用IDE基本不必考慮這個(gè)問題。

思考:因?yàn)镮DE過于方便,使得我們會(huì)忽略很多細(xì)節(jié),對于初學(xué)者而言建議從最簡單的文本編輯器與命令行的方式進(jìn)行學(xué)習(xí)。不要出現(xiàn)都學(xué)得挺多了,但是連一個(gè)main函數(shù)都敲不出來,那就尷尬了。

2.2 默認(rèn)的初值

null是任何引用類型的默認(rèn)值,不嚴(yán)格的說是所有object類型的默認(rèn)值。這對所有變量都是適用的,如成員變量、局部變量、實(shí)例變量、靜態(tài)變量(但當(dāng)你使用一個(gè)沒有初始化的局部變量,編譯器會(huì)警告你)。

2.3 類型

null 既不是對象也不是一種類型,它僅是一種特殊的值,你可以將其賦予任何引用類型,你也可以將null轉(zhuǎn)化成任何類型。

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。但是可以賦值給他們的包裝類類型,如上面的代碼中使用的。

正如這個(gè)特性,也會(huì)導(dǎo)致一個(gè)異常的發(fā)生:先將 null 賦給包裝類型,然后將包裝類型賦值給基本類型,編譯器完全是可以通過的,但是運(yùn)行時(shí)會(huì)拋出空指針異常。

當(dāng)然了編程的時(shí)候誰閑著沒事這樣做,但是很有可能無意中卻這樣做了,所以一定要謹(jǐn)慎。

這個(gè)異常時(shí)在自動(dòng)拆箱的過程中,關(guān)于自動(dòng)拆箱裝箱可以參考《JAVA 包裝類型 及 易錯(cuò)陷阱》。

2.4 對null的檢查

== 與 !=

這種比較是最為常用的比較,但是也有其缺點(diǎn)。

something == null,這種寫法完全沒有任何異常,但是很容易失誤導(dǎo)致錯(cuò)誤。因?yàn)檫@種寫法如果少一個(gè)等號(hào),這樣就變成了賦值,而代碼仍然是可以正常運(yùn)行的。所以更加安全的寫法是 null == something,當(dāng)我們將等號(hào)少寫一個(gè),會(huì)直接報(bào)異常,所以這種寫法更加安全。

注意:不能使用其他算法或者邏輯操作,例如小于或者大于。

instanceof

Java 中的 instanceof 運(yùn)算符是用來在運(yùn)行時(shí)指出對象是否是特定類的一個(gè)實(shí)例。instanceof 通過返回一個(gè)布爾值來指出,這個(gè)對象是否是這個(gè)特定類或者是它的子類的一個(gè)實(shí)例。

如果使用了帶有 null 值的引用類型變量,instanceof 操作將會(huì)返回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");
}

輸出結(jié)果為:

iAmNull is NOT an instance of Integer

equals

在比較的時(shí)候除了 == 之外,我們經(jīng)常會(huì)想到的就是 Object 類中就有的 equals() 方法,雖然許多類繼承并覆蓋了這個(gè)方法,但是大致上都差不多。因?yàn)镴ava中基本都是對象,所以都可以對其進(jìn)行調(diào)用,一再強(qiáng)調(diào)null的類型(詳見第一條),something.equals(null),當(dāng)something不是null時(shí)一切正常,可是如果是null的話,會(huì)拋出空指針異常,你要是不嫌麻煩,完全可以捕獲這個(gè)空指針異常,并直接做 null 處理,但是不建議。

public class ceshi{	
	static String a=null;	
	 public static void main(String args[]){
      if(a.equals(null)){
      	System.out.println("==");
      }                                 
   }
}

輸出結(jié)果

Exception in thread "main" java.lang.NullPointerException

at ceshi.main(ceshi.java:6)

2.5 靜態(tài)方法

你可能知道不能調(diào)用非靜態(tài)方法來使用一個(gè)值為 null 的引用類型變量。它將會(huì)拋出空指針異常,但是你可能不知道,你可以使用靜態(tài)方法來使用一個(gè)值為 null 的引用類型變量。因?yàn)殪o態(tài)方法使用靜態(tài)綁定,不會(huì)拋出空指針異常。

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");
   }
}

運(yùn)行結(jié)果:

I am static method, can be called by null reference
Exception in thread "main" java.lang.NullPointerException
at ceshi.main(ceshi.java:6)

我們可以看到對象完全沒有實(shí)例化但是卻正常的執(zhí)行了其靜態(tài)的方法,這其實(shí)也不奇怪,靜態(tài)方法完全可以使用類名直接使用,只不過繞了個(gè)彎,編譯器,所以不足為奇。

2.6 參數(shù)傳遞

我們可以將null傳遞給方法使用,這時(shí)方法可以接收任何引用類型,例如public void print(Object obj)可以這樣調(diào)用print(null)。從編譯角度來看這是可以的,但結(jié)果完全取決于方法。Null安全的方法,如在這個(gè)例子中的print方法,不會(huì)拋出空指針異常,只是優(yōu)雅的退出。如果業(yè)務(wù)邏輯允許的話,推薦使用null安全的方法。

2.7 用途

  • 判斷一個(gè)引用類型數(shù)據(jù)是否null。 用==來判斷。
  • 釋放內(nèi)存,讓一個(gè)非null的引用類型變量指向null。這樣這個(gè)對象就不再被任何對象應(yīng)用了。等待JVM垃圾回收機(jī)制去回收。

三、SQL的NULL

在數(shù)據(jù)庫中NULL表示 未知的。

NULL不等于零或空格,NULL 值不視作大于、小于或等于任何其它值。當(dāng)一個(gè)變量、列或常量具有NULL值時(shí),它的值是未知的、不確定的?!拔粗摹迸c空白或零或布爾值FALSE完全不同?!拔粗摹币馕吨撟兞扛緵]有值,因此不能與其他變量直接進(jìn)行比較。判斷某列或者變量為 NULL 是只能用IS(NOT) NULL 去判斷他的返回值是 true 還是 false。

NULL參與排序時(shí)總是作為最小值存在,即ORDER BY COL ASC時(shí)COL為NULL的行在最前面,反之在最后面。

NULL值是未知的,且占用空間,不走索引,DBA建議建表的時(shí)候最好設(shè)置字段是NOT NULL 來避免這種低效率的事情的發(fā)生。

NULL值具有以下三個(gè)規(guī)則:

  • 一個(gè)NULL不與其他任何值相等;一個(gè)NULL不與其他任何值不等;
  • 在對一個(gè)NULL值應(yīng)用函數(shù)時(shí),一般都會(huì)得到一個(gè)NULL值作為結(jié)果。
  • 一般而言,只要執(zhí)行涉及一個(gè)或多個(gè)NULL值的比較操作,那個(gè)比較的結(jié)果也是NULL值,它不同于TRUE或FALSE,因而這樣的比較除了失敗,沒有任何幫助作用。

注意空值與NULL之間的差異:

  • 在進(jìn)行count()統(tǒng)計(jì)某列的記錄數(shù)的時(shí)候,如果采用的NULL值,會(huì)被系統(tǒng)自動(dòng)忽略掉,但是空值是會(huì)進(jìn)行統(tǒng)計(jì)到其中的。(count(*)會(huì)將NULL統(tǒng)計(jì)上)
  • 判斷NULL 用IS NULL 或者 IS NOT NULL,SQL 語句函數(shù)中可以使用 ifnull() 函數(shù)來進(jìn)行處理,判斷空字符用 = 或者 <> 來進(jìn)行處理。
  • 對于MySQL特殊的注意事項(xiàng),對于timestamp數(shù)據(jù)類型,如果往這個(gè)數(shù)據(jù)類型插入的列插入NULL值,則出現(xiàn)的值是NULL。插入空值,則會(huì)出現(xiàn) '0000-00-00 00:00:00'

三、Java與SQL

Java中的 null 只能賦值給各種引用類型,不能賦值給基本類型,然而SQL中的可以將NULL賦給任何數(shù)據(jù)類型,因此這就會(huì)導(dǎo)致異常的出現(xiàn)。

這樣一來,我們從數(shù)據(jù)庫中讀取字段的值后,在Java程序中如何判斷讀取的值是否為 null 呢?用 name==null 嗎?顯然不行,==是判斷兩個(gè)變量或?qū)嵗遣皇侵赶蛲粋€(gè)內(nèi)存空間,除非這個(gè)name是String類型的。而equals()方法呢?是判斷兩個(gè)變量或?qū)嵗赶虻膬?nèi)存空間的值是不是相同。

java.sql.ResultSet接口中的boolean wasNull()方法可以解決這個(gè)問題:boolean wasNull();報(bào)告最后一個(gè)讀取的列是否具有值 SQL NULL。

注意,必須首先對列調(diào)用一個(gè)獲取方法嘗試讀取其值,然后調(diào)用wasNull ()方法查看讀取的值是否為 SQL NULL。如果發(fā)生數(shù)據(jù)庫訪問錯(cuò)誤將拋出SQLException。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • mybatis mapper.xml獲取insert后的自增ID問題

    mybatis mapper.xml獲取insert后的自增ID問題

    這篇文章主要介紹了mybatis mapper.xml獲取insert后的自增ID問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • Spring4下validation數(shù)據(jù)校驗(yàn)無效(maven)的解決

    Spring4下validation數(shù)據(jù)校驗(yàn)無效(maven)的解決

    這篇文章主要介紹了Spring4下validation數(shù)據(jù)校驗(yàn)無效(maven)的解決,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • mybatis-plus 表名添加前綴的實(shí)現(xiàn)方法

    mybatis-plus 表名添加前綴的實(shí)現(xiàn)方法

    這篇文章主要介紹了mybatis-plus 表名添加前綴的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 安裝elasticsearch-analysis-ik中文分詞器的步驟講解

    安裝elasticsearch-analysis-ik中文分詞器的步驟講解

    今天小編就為大家分享一篇關(guān)于安裝elasticsearch-analysis-ik中文分詞器的步驟講解,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • Java8新特性之Optional使用詳解

    Java8新特性之Optional使用詳解

    這篇文章主要介紹了Java8新特性之Optional使用詳解,為了解決空指針異常更加優(yōu)雅,Java8?提供了?Optional?類庫,Optional?實(shí)際上是個(gè)容器,它可以保存類型T的值,或者僅僅保存null,,需要的朋友可以參考下
    2023-08-08
  • Java中的線程生命周期核心概念

    Java中的線程生命周期核心概念

    這篇文章主要介紹了Java中的線程生命周期核心概念,通過使用一個(gè)快速的圖解展開文章內(nèi)容,需要的小伙伴可以參考一下
    2022-06-06
  • Java中l(wèi)ist集合為空或?yàn)閚ull的區(qū)別說明

    Java中l(wèi)ist集合為空或?yàn)閚ull的區(qū)別說明

    這篇文章主要介紹了Java中l(wèi)ist集合為空或?yàn)閚ull的區(qū)別說明,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • jdk17+springboot使用webservice的踩坑實(shí)戰(zhàn)記錄

    jdk17+springboot使用webservice的踩坑實(shí)戰(zhàn)記錄

    這篇文章主要給大家介紹了關(guān)于jdk17+springboot使用webservice踩坑的相關(guān)資料,網(wǎng)上很多教程是基于jdk8的,所以很多在17上面跑不起來,折騰兩天,直接給答案,需要的朋友可以參考下
    2024-01-01
  • 詳解Spring Data操作Redis數(shù)據(jù)庫

    詳解Spring Data操作Redis數(shù)據(jù)庫

    Redis是一種NOSQL數(shù)據(jù)庫,Key-Value形式對數(shù)據(jù)進(jìn)行存儲(chǔ),其中數(shù)據(jù)可以以內(nèi)存形式存在,也可以持久化到文件系統(tǒng)。Spring data對Redis進(jìn)行了很好的封裝,用起來也是十分的得心應(yīng)手,接下來通過本文給大家分享Spring Data操作Redis數(shù)據(jù)庫,需要的朋友參考下
    2017-03-03
  • 教你安裝eclipse2021并配置內(nèi)網(wǎng)maven中心倉庫的圖文詳解

    教你安裝eclipse2021并配置內(nèi)網(wǎng)maven中心倉庫的圖文詳解

    本文能通過圖文并茂的形式給大家介紹安裝eclipse2021并配置內(nèi)網(wǎng)maven中心倉庫的相關(guān)知識(shí),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-09-09

最新評(píng)論