1.String源码粗略解读
2.常用的 list.isEmpty() 为何突然报null?
3.StringUtilså¨commons-lang3åcommons-langä¸çåºå«
4.StringUtilsä¸isEmpty åisBlankçåºå«
String源码粗略解读
深入解析Java中的String类
String类作为Java中的基础类,几乎每一位开发者都与之紧密接触。了解其源码有助于深入理解类的实现细节。String类为final修饰,确保其不可变性,同时实现了Serializable、qq自动发消息源码Comparable、CharSequence接口。
String类的核心在于底层实现为char类型的数组,并缓存哈希值,此特性使得其在HashMap等集合框架中表现优异。
equal(Object)方法超越了基本的“==”比较,旨在验证两个字符串是否完全相同,通过比较长度和字符内容实现。
hashCode()方法基于字符数组进行计算,采用哈希值与相乘并加权的策略。尽管设计良好,通过dll查看源码仍可能产生冲突,因此需要结合equal()方法进行验证。
toString()方法调用Object类的同名方法,返回类名加上十六进制哈希值的字符串形式。
intern()方法提供了一种机制,通过本地方法实现,允许查找或创建常量池中的字符串实例,提升内存效率。行业概念公式源码
总结,String类提供了丰富的功能,包括但不限于isEmpty(),indexOf(),substring(),concat()等方法。探索其源码能够深化理解,对于提高编程技能大有裨益。闯关的口红 源码
常用的 list.isEmpty() 为何突然报null?
发现项目中常用方法突然报null,今天就来详细探讨下原因。
以往使用list集合判断是否为空时,通常会通过list.isEmpty()方法来判断返回值是否为true,以此继续执行业务流程。然而,近期这个方法突然报出null错误,这是微赞的源码怎么回事呢?
业务场景模拟:
创建一个父类,并在其中定义子类的list,main方法中给父类id赋值,但list未赋值。之后,尝试使用father.getSonList()方法时,遇到了空异常问题。而使用CollectionUtils进行判断时,则未出现此错误。
下面看一段代码示例:
原因分析:
深入探究源码后发现,CollectionUtils里确实也包含了isEmpty的判断。那么,为何它没有报出错误呢?
其实,我们知道&&和||都是短路操作符。&&要求两个条件都为真时,才会返回真值,一旦第一个条件为假,则后续条件不再执行,直接返回假值。而||只要第一个条件为真,就不再执行后续条件,直接返回真值。
因此,问题原因在于:CollectionUtils在先判断是否为null的同时,使用了短路模式,并通过||操作符确保了即使list为空,也能够提前返回真值,避免了空异常的发生。这样一来,业务流程得以正常进行,避免了null错误的产生。
StringUtilså¨commons-lang3åcommons-langä¸çåºå«
ï¼1ï¼å ¥åç±»åä¸åcommons.langä¸å ¥å为 Sring str
commons.lang3ä¸å ¥å为 CharSequence cs(éç¨èå´æ´å¹¿)
ï¼2ï¼å ¥åæ°éä¸å
commons.lang3ä¸æ¯æå¤å ¥å
æè¿ç»å¸¸éè¦å¯¹Stringåä¸äºå¤æåå¤çï¼äºæ¯å°±ç¨å°äºApacheæä¾çStringUtilsè¿ä¸ªå·¥å ·ç±»ï¼ç¨çæ¶ååç°æ两个ä¸åççæ¬ï¼ä¸ä¸ªçæ¬ä½äºorg.apache.commons.langä¸é¢ï¼å¦ä¸ä¸ªåä½äºorg.apache.commons.lang3ä¸é¢ã
æ¥äºä¸ä¸èµæï¼lang3æ¯Apache Commons å¢éåå¸çå·¥å ·å ï¼è¦æ±jdkçæ¬å¨1.5以ä¸ï¼ç¸å¯¹äºlangæ¥è¯´å®å ¨æ¯æjava5çç¹æ§ï¼åºé¤äºä¸äºæ§çAPIã该çæ¬æ æ³å ¼å®¹æ§æçæ¬ï¼äºæ¯ä¸ºäºé¿å å²çªæ¹å为lang3ãè¿äºä¸è¥¿å°±ä¸åç»è¯´äºï¼æ们æ¥ççStringUtilsä¸å¸¸ç¨çä¸äºæ¹æ³æä»ä¹æ¹åå§ã
å¯ä»¥çå°è¿å 个æ¹æ³é»è¾æ¯«æ ååï¼åªæ¯åæ°ç±»ååäºï¼ç±Stringå为CharSequenceãé£ä¹è¿ä¸ªCharSequenceæ¯ä»ä¹å¢ï¼æ们ççå®çæºç ï¼
CharSequenceæ¯ä¸ä¸ªå符åºåçæ¥å£ï¼å ¶ä¸å®ä¹äºä¸äºå¸¸ç¨çå¦length()ãsubSequence()çæ¹æ³ï¼Stringä¹å®ç°äºè¿ä¸ªæ¥å£ãå½ç¶å¤§å®¶å¯è½å¨Stringéç¨å°çé½æ¯subString()ï¼å®é ä¸Stringä¹å®ç°äºsubSequence()è¿ä¸ªæ¹æ³ï¼åªæ¯ç´æ¥æåäºsubString()ã
lang3ä¸ä½¿ç¨CharSequenceæ大ç好å¤å°±æ¯ä»¤è¿äºæ¹æ³ç¨å¤æ´å 广æ³ï¼ä¸æ¢å±éäºStringï¼å ¶ä»ä¸äºå®ç°äºè¯¥æ¥å£çç±»ä¹å¯ä»¥ä½¿ç¨StringUtilsä¸çè¿äºæ¹æ³å»è¿è¡ä¸äºæä½ãå¦å¤æåç°å¾å¤nioä¸çç±»é½å®ç°äºè¿ä¸ªæ¥å£ï¼ä¸ªäººçæµå¯è½ä¹æ为nioæå¡çç®çã
å¨langä¸ï¼ç¬¬ä¸æ¥æ¯å å¤æstr1æ¯å¦ä¸ºç©ºï¼èå¨lang3ä¸ï¼ç¬¬ä¸æ¥åæ¯å å¤æ两个对象æ¯å¦ç¸åãè¿ä¸ªä¸é¾ç解ï¼å¦æ两个对象çå°åç¸åï¼é£ä¹å®ä»¬æåçå°±æ¯åä¸ä¸ªå¯¹è±¡ï¼å 容è¯å®ç¸åã
å¨lang3ä¸ï¼è¿å å ¥äºä¸äºåæ¶å¤æå¤ä¸ªåæ°çæ¹æ³ï¼å¯ä»¥çå°å®é ä¸æ¯å°åæ°å表æ¾å ¥ä¸ä¸ªCharSequenceæ°ç»ä¸ï¼ç¶åéåè°ç¨ä¹åçisEmptyçæ¹æ³ãå¤æblankä¹æ类似çæ¹æ³ã
å¯è½æ人ä¼è§å¾ï¼å¾å¤æ¹æ³Stringæ¬èº«å°±æåï¼ä¸ºä»ä¹è¿è¦ç¨StringUtilsæä¾çå¢ï¼æå¼åæ°ç±»åä¸è°ï¼æ们å¯ä»¥çå°ï¼StringUtilsä¸çæ¹æ³å¤§å¤é½åäºç©ºæ ¡éªï¼å¦æ为空æ¶ä¼è¿åNullæè 空串ï¼èStringæ¬èº«çæ¹æ³å¨å¾å¤ä¼ å ¥åæ°æ对象æ¬èº«ä¸ºç©ºçæ¶åé½ä¼æ¥ç©ºæéé误ã
åèå°åï¼ StringUtilså¨commons-lang3åcommons-langä¸çåºå«
StringUtilsä¸isEmpty åisBlankçåºå«
ããStringUtilså¨commons-lang-2.2.jarå ä¸ï¼org.apache.commons.lang.StringUtils ;
ãã
ããStringUtilsæ¹æ³çæä½å¯¹è±¡æ¯java.lang.Stringç±»åç对象ï¼æ¯JDKæä¾çStringç±»åæä½æ¹æ³çè¡¥å ï¼å¹¶ä¸æ¯nullå®å ¨ç(å³å¦æè¾å ¥åæ°String为nullåä¸ä¼æåºNullPointerExceptionï¼èæ¯åäºç¸åºå¤çï¼ä¾å¦ï¼å¦æè¾å ¥ä¸ºnullåè¿åä¹æ¯nullçï¼å ·ä½å¯ä»¥æ¥çæºä»£ç )ã
ãã
ããé¤äºæé å¨ï¼StringUtilsä¸ä¸å ±æå¤ä¸ªæ¹æ³ï¼å¹¶ä¸é½æ¯staticçï¼æ以æ们å¯ä»¥è¿æ ·è°ç¨StringUtils.xxx()
ãã1. public static boolean isEmpty(String str)
ããå¤ææå符串æ¯å¦ä¸ºç©ºï¼ä¸ºç©ºçæ åæ¯str==nullæstr.length()==0
ããä¸é¢æ¯StringUtilså¤ææ¯å¦ä¸ºç©ºç示ä¾ï¼
ããStringUtils.isEmpty(null) = true
ããStringUtils.isEmpty("") = true
ããStringUtils.isEmpty(" ") = false //注æå¨StringUtilsä¸ç©ºæ ¼ä½é空å¤ç
ããStringUtils.isEmpty(" ") = false
ããStringUtils.isEmpty("bob") = false
ããStringUtils.isEmpty(" bob ") = false
ãã2. public static boolean isNotEmpty(String str)
ããå¤ææå符串æ¯å¦é空ï¼çäº!isEmpty(String str)
ããä¸é¢æ¯ç¤ºä¾ï¼
ããStringUtils.isNotEmpty(null) = false
ããStringUtils.isNotEmpty("") = false
ããStringUtils.isNotEmpty(" ") = true
ããStringUtils.isNotEmpty(" ") = true
ããStringUtils.isNotEmpty("bob") = true
ããStringUtils.isNotEmpty(" bob ") = true
ãã3. public static boolean isBlank(String str)
ããå¤ææå符串æ¯å¦ä¸ºç©ºæé¿åº¦ä¸º0æç±ç©ºç½ç¬¦(whitespace)ææ
ããä¸é¢æ¯ç¤ºä¾ï¼
ããStringUtils.isBlank(null) = true
ããStringUtils.isBlank("") = true
ããStringUtils.isBlank(" ") = true
ããStringUtils.isBlank(" ") = true
ããStringUtils.isBlank("\t \n \f \r") = true //对äºå¶è¡¨ç¬¦ãæ¢è¡ç¬¦ãæ¢é¡µç¬¦åå车符StringUtils.isBlank()åè¯ä¸ºç©ºç½ç¬¦
ããStringUtils.isBlank("\b") = false //"\b"为åè¯è¾¹ç符
ããStringUtils.isBlank("bob") = false
ããStringUtils.isBlank(" bob ") = false
ãã4. public static boolean isNotBlank(String str)
ããå¤ææå符串æ¯å¦ä¸ä¸ºç©ºä¸é¿åº¦ä¸ä¸º0ä¸ä¸ç±ç©ºç½ç¬¦(whitespace)ææï¼çäº!isBlank(String str)
ããä¸é¢æ¯ç¤ºä¾ï¼
ããStringUtils.isNotBlank(null) = false
ããStringUtils.isNotBlank("") = false
ããStringUtils.isNotBlank(" ") = false
ããStringUtils.isNotBlank(" ") = false
ããStringUtils.isNotBlank("\t \n \f \r") = false
ããStringUtils.isNotBlank("\b") = true
ããStringUtils.isNotBlank("bob") = true
ããStringUtils.isNotBlank(" bob ") = true
ããå ¶ä»æ¹æ³ä»ç»ï¼
ãã5. public static String trim(String str)
ããå»æå符串两端çæ§å¶ç¬¦(control characters, char <= ),å¦æè¾å ¥ä¸ºnullåè¿ånull
ããä¸é¢æ¯ç¤ºä¾ï¼
ããStringUtils.trim(null) = null
ããStringUtils.trim("") = ""
ããStringUtils.trim(" ") = ""
ããStringUtils.trim(" \b \t \n \f \r ") = ""
ããStringUtils.trim(" \n\tss \b") = "ss"
ããStringUtils.trim(" d d dd ") = "d d dd"
ããStringUtils.trim("dd ") = "dd"
ããStringUtils.trim(" dd ") = "dd"
ãã6. public static String trimToNull(String str)
ããå»æå符串两端çæ§å¶ç¬¦(control characters, char <= ),å¦æå为nullæ""ï¼åè¿ånull
ããä¸é¢æ¯ç¤ºä¾ï¼
ããStringUtils.trimToNull(null) = null
ããStringUtils.trimToNull("") = null
ããStringUtils.trimToNull(" ") = null
ããStringUtils.trimToNull(" \b \t \n \f \r ") = null
ããStringUtils.trimToNull(" \n\tss \b") = "ss"
ããStringUtils.trimToNull(" d d dd ") = "d d dd"
ããStringUtils.trimToNull("dd ") = "dd"
ããStringUtils.trimToNull(" dd ") = "dd"
ãã7. public static String trimToEmpty(String str)
ããå»æå符串两端çæ§å¶ç¬¦(control characters, char <= ),å¦æå为nullæ""ï¼åè¿å""
ããä¸é¢æ¯ç¤ºä¾ï¼
ããStringUtils.trimToEmpty(null) = ""
ããStringUtils.trimToEmpty("") = ""
ããStringUtils.trimToEmpty(" ") = ""
ããStringUtils.trimToEmpty(" \b \t \n \f \r ") = ""
ããStringUtils.trimToEmpty(" \n\tss \b") = "ss"
ããStringUtils.trimToEmpty(" d d dd ") = "d d dd"
ããStringUtils.trimToEmpty("dd ") = "dd"
ããStringUtils.trimToEmpty(" dd ") = "dd"
ãã8. public static String strip(String str)
ããå»æå符串两端ç空ç½ç¬¦(whitespace)ï¼å¦æè¾å ¥ä¸ºnullåè¿ånull
ããä¸é¢æ¯ç¤ºä¾(注æåtrim()çåºå«)ï¼
ããStringUtils.strip(null) = null
ããStringUtils.strip("") = ""
ããStringUtils.strip(" ") = ""
ããStringUtils.strip(" \b \t \n \f \r ") = "\b"
ããStringUtils.strip(" \n\tss \b") = "ss \b"
ããStringUtils.strip(" d d dd ") = "d d dd"
ããStringUtils.strip("dd ") = "dd"
ããStringUtils.strip(" dd ") = "dd"
ãã9. public static String stripToNull(String str)
ããå»æå符串两端ç空ç½ç¬¦(whitespace)ï¼å¦æå为nullæ""ï¼åè¿ånull
ããä¸é¢æ¯ç¤ºä¾(注æåtrimToNull()çåºå«)ï¼
ããStringUtils.stripToNull(null) = null
ããStringUtils.stripToNull("") = null
ããStringUtils.stripToNull(" ") = null
ããStringUtils.stripToNull(" \b \t \n \f \r ") = "\b"
ããStringUtils.stripToNull(" \n\tss \b") = "ss \b"
ããStringUtils.stripToNull(" d d dd ") = "d d dd"
ããStringUtils.stripToNull("dd ") = "dd"
ããStringUtils.stripToNull(" dd ") = "dd"
ãã. public static String stripToEmpty(String str)
ããå»æå符串两端ç空ç½ç¬¦(whitespace)ï¼å¦æå为nullæ""ï¼åè¿å""
ããä¸é¢æ¯ç¤ºä¾(注æåtrimToEmpty()çåºå«)ï¼
ããStringUtils.stripToNull(null) = ""
ããStringUtils.stripToNull("") = ""
ããStringUtils.stripToNull(" ") = ""
ããStringUtils.stripToNull(" \b \t \n \f \r ") = "\b"
ããStringUtils.stripToNull(" \n\tss \b") = "ss \b"
ããStringUtils.stripToNull(" d d dd ") = "d d dd"
ããStringUtils.stripToNull("dd ") = "dd"
ããStringUtils.stripToNull(" dd ") = "dd"