java中的null与空值

本文深入解析Java中变量初始化的过程,包括基本类型、实例变量、初始化块及null的使用。详细阐述了成员变量与局部变量的初始化规则,null作为不确定对象的特性及其在引用类型判断和内存释放中的作用。同时,介绍了Java中字符串初始化的特殊方式及容器类型与null的关系。
初始化拿一个程序来说就是先加载基本的数据,拿变量来说就是给它一个初始值

分配内存,初始化实例变量的值,还有就是依次创建当前类所在继承链上的所有类的对象。如果有初始化块,会自动运行。

java中基本类型采用C与C++中相同的方法,不采用句柄的方式,基本类型的变量容纳了具体的值(固定长度),存在于堆栈中。

如果基本数据类型作为一个类的成员变量,即使不显示初始化(赋值),java中保证其获得一个默认初始值分别如下(C++没有这种功能):(这种赋默认值不适用与其作为局部变量的情况,不显示初始化会有编译期错误)
boolean false
char '\u0000'(null)
byte (byte)0
short (short)0
int 0
long 0L
float 0.0f
double 0.0d

java中除了八大基本类型一切都是对象,在声明变量时String s;只是获得了一个句柄,其并不指向一个对象,在使用时必然会出现运行期错误(空指针)。应该初始化String s = “abcd”;

这是字符串这种特殊类型的初始化方式,更通用的是用new关键字进行句柄与新对象的链接。

一、null指的是不确定的对象;
null用来判断引用类型是否分配了存储空间。
String s = null;已经分配了存储空间,只是不确定是什么类型,称为空对象。(其实就是不确定对象时初始化分配内存的一种状态,等待被真的指向一个某对象)。

Java中,变量的使用都遵循一个原则,先定义,并且初始化后,才可以使用。我们不能int a后,不给a指定值,就去打印a的值。这条对对于引用类型变量也是适用的。

null代表声明了一个空对象,对空对象做任何操作都不行,除了=和==(==比较的是引用类型存储的地址,基本类型的值。)。
“”是一个字符串了,只是这个字符串里面没有内容。
String s=null;只是定义了一个句柄,也就是说你有了这个引用,但是这个引用未指向任何内存空间。
String s="";这个应用已经指向了一块是空字符串的内存空间,是一个实际的对象了,可以应用所有Sting类型的方法。

String s = "aaa";与String s=new String("aaa");有本质的区别:
前者是在字符串池中写入一个字符串“aaa”,然后用s指向它,在栈上分配内存;
后者是在堆上创建一个内容为“aaa”的字符串对象。
String a="";String b="";
上面两者变量a、b指向同一内存地址。
String a=new String("");String b=new String("");
上面两者变量a、b指向不同内存地址。
字符串缓冲池
原因是String类维护着一个字符串池,对于前两者的赋值方法,String会在这个池中查找字符串是否已经在池中,如果在,就直接指向该地址,如果不在,则生成一个实例放入池中,再指向。之所以这样做,因为String是一个内容不可变的量,运用的是设计模式GOF.FlyWeight。

String s=null;String s="";String s;三者的区别
第一个是创建一个空字符串对象;
第二个是创建一个字符串为空的字符串对象;
第三个是声明一个字符串对象,但并没有分配内存,而第一个第二个已经分配了内存。
对于第三种,不能使用if(s==null),或者int length = s.length();不能通过编译,报没有初始化。

第一和第三有时候是等同的,有时候是不同的。
java为了安全原因不允许一个悬挂引用,没有赋值的引用地址一律自动赋值为null,防止访问到任意内存。(但是此点只限于成员变量)
在局部变量中是不同的,String s不会分配内存,需要显示赋值。
总结:
java中成员变量编译器会自动赋值,局部变量都要显示赋初值。

注意静态资源的使用方法。
Map<String, Object> n = ll.hh();
Map hh(){
//1、return new HashMap<String, Object>();
2、return null;
}
1、返回的是HashMap对象,2返回的是null对象。instanceof前者为真,后者为假。
这里编程的时候要考虑到函数返回值为null的情况。


二、null本身不是对象,也不是Object的实例。
null本身虽然能代表一个不确定的对象,但就null本身来说,它不是对象,也不知道什么类型,也不是java.lang.Object的实例。

三、容器类型与null
List:允许重复元素,可以加入任意多个null。
Set:不允许重复元素,最大可以加入一个null。
Map:Map的key最多可以加入一个null,value字段没有限制。
数组:基本类型数组,定以后,如果不给定初始值,则java运行时会自动给定值。引用类型数组,不给定初始值,则所有的元素值为null。

四、null的其他作用
1、判断一个引用类型数据是否null。用==来判断。
2、释放内存,让一个非null的引用类型变量指向null。这样这个对象不再被任何句柄应用,会等待JVM垃圾回收机制去回收。

http://lavasoft.blog.51cto.com/62575/79243

http://www.360doc.com/content/12/1107/09/600840_246328536.shtml


引用类型当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。 JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地 址,但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。
对于引用类型之间进行equals比较,在没有覆写equals方法的情况下,他们之间的比较还是基于他们在内存中的存放位置的地址值的,因为Object的equals方法也是用双等号(==)进行比较的,所以比较后的结果跟双等号(==)的结果相同。

java中初始化是指分配内存
java中初始化顺序:

1,在new B一个实例时首先要进行类的装载。(类只有在使用New调用创建的时候才会被java类装载器装入)
2,在装载类时,先装载父类A,再装载子类B
3,装载父类A后,完成静态动作(包括静态代码和变量,它们的级别是相同的,安装代码中出现的顺序初始化)
4,装载子类B后,完成静态动作
类装载完成,开始进行实例化
1,在实例化子类B时,先要实例化父类A
2,实例化父类A时,先成员实例化(非静态代码)
3,父类A的构造方法
4,子类B的成员实例化(非静态代码)
5,子类B的构造方法
<think>我们正在讨论Java中如何判断变量是否为空值。根据引用内容,我们可以总结出几种常见的方法,并针对不同类型的变量(如对象、字符串、数组等)进行说明。 注意:在Java中,判断空值需要区分变量是基本类型还是引用类型,以及具体的数据结构(如字符串、集合、数组等)。 根据引用[1]和引用[2]: - 对于对象(引用类型),我们可以使用`Objects.isNull()``null`直接比较。 - 对于字符串,除了判断是否为`null`,还要判断是否为字符串("")格字符串(引用[4]提到了格,但要注意中英文格的区别,但Java中通常使用`String`的`isEmpty()``isBlank()`(Java 11+)来检查)。 - 对于数组,可以使用`ArrayUtils.isEmpty()`(来自Apache Commons Lang)判断数组是否为`null`且长度大于0。 - 对于集合(如List、Set等),可以使用`CollectionUtils.isEmpty()`(来自Apache Commons Collections)自行判断是否为`null`且集合大小大于0。 另外,引用[2]提到:boolean基本类型的默认值是false,而Boolean包装类的默认值是null。 下面我们分情况讨论: 1. 判断对象是否为null: ```java Object obj = ...; if (obj == null) { // 对象为null } // 者使用Java 7的Objects类 if (Objects.isNull(obj)) { // 对象为null } ``` 2. 判断字符串是否为null字符串): ```java String str = ...; // 使用Java内置方法 if (str == null || str.isEmpty()) { // 字符串为null字符串 } // 如果考虑格(白字符串),可以使用Java 11的isBlank if (str == null || str.isBlank()) { // 注意:isBlank()在Java 11引入 // 字符串为null只包含白字符(包括格、制表符等) } // 者使用Apache Commons Lang的StringUtils(兼容旧版本Java) if (StringUtils.isEmpty(str)) { // 检查null字符串 // ... } if (StringUtils.isBlank(str)) { // 检查null字符串和白字符串 // ... } ``` 3. 判断数组是否为null长度为0): ```java Object[] array = ...; // 使用原生方法 if (array == null || array.length == 0) { // 数组为 } // 使用Apache Commons Lang的ArrayUtils if (ArrayUtils.isEmpty(array)) { // 数组为 } ``` 4. 判断集合是否为null没有元素): ```java Collection<?> collection = ...; // 使用原生方法 if (collection == null || collection.isEmpty()) { // 集合为 } // 使用Apache Commons Collections的CollectionUtils if (CollectionUtils.isEmpty(collection)) { // 集合为(包括null集合) } ``` 5. 对于Map,判断方式集合类似: ```java Map<?, ?> map = ...; if (map == null || map.isEmpty()) { // map为 } ``` 6. 对于基本类型的包装类(如Integer、Boolean等),判断是否为null: ```java Integer num = ...; if (num == null) { // 为null } ``` 7. 对于基本类型(如int、boolean等),它们不能为null,所以不需要判断null。但要注意它们的默认值(如int默认为0,boolean默认为false)是否符合业务逻辑。 8. 如果变量是自定义对象,且需要判断其内部属性是否为,则需要根据业务需求进行递归判断(通常使用工具类自定义方法)。 9. 使用工具类简化操作(如Apache Commons LangGuava): - Apache Commons Lang: `ObjectUtils.isEmpty(obj)` 可以判断多种类型(包括CharSequence、Collection、Map、Array等)是否为。注意:对于对象,它只判断是否为null,对于其他类型会调用相应的检查(如String会检查是否为字符串,Collection会检查是否为集合等)。 - Guava: 提供了类似的工具,例如`Strings.isNullOrEmpty(str)`用于字符串。 示例:使用`ObjectUtils.isEmpty()`(来自Apache Commons Lang 3) ```java import org.apache.commons.lang3.ObjectUtils; // 对于字符串 String str = null; System.out.println(ObjectUtils.isEmpty(str)); // 输出 true str = ""; System.out.println(ObjectUtils.isEmpty(str)); // 输出 true // 对于集合 List<String> list = null; System.out.println(ObjectUtils.isEmpty(list)); // 输出 true list = new ArrayList<>(); System.out.println(ObjectUtils.isEmpty(list)); // 输出 true // 对于数组 String[] array = null; System.out.println(ObjectUtils.isEmpty(array)); // 输出 true array = new String[0]; System.out.println(ObjectUtils.isEmpty(array)); // 输出 true ``` 10. 使用Java 8的Optional来避免指针: ```java Optional<String> optional = Optional.ofNullable(str); if (optional.isPresent()) { // 不为,可以使用optional.get()获取值 // 者使用optional.orElse(defaultValue)来提供默认值 } ``` 总结: 根据不同的数据类型选择合适的空值判断方法,优先使用标准库(如Java 7的Objects、Java 11的String方法)成熟的工具库(如Apache Commons Lang)来简化代码并提高健壮性。 注意:在判断空值时,要结合业务需求,有时“”可能包含多种情况(比如字符串为多个格,业务上可能视为,此时应该用`isBlank`而不是`isEmpty`)。 根据引用[3]和[4],我们还需要注意白字符(包括格、制表符等)的判定,特别是在处理用户输入时。Java 11的`isBlank()`方法可以识别所有白字符(包括全角格?注意:Java的`isBlank()`方法根据Unicode标准判断白字符,包括全角格吗?实际上,全角格(U+3000)在Java 11中不被认为是白字符,所以如果需要识别全角格,可能需要额外处理。但通常,中文环境下,我们可能还需要考虑全角格,这时可以自定义方法使用`StringUtils.isBlank`(Apache Commons Lang可以处理全角格吗?根据文档,它只能处理半角格,所以需要先替换全角格?)。因此,在涉及中文格时,建议先进行标准化处理使用能够识别全角格的库。 由于引用[4]提到中英文格的区别,在判断字符串是否为时,如果需要忽略全角格,可以这样处理: ```java // 替换字符串中的全角格为半角格,然后判断 if (str != null) { str = str.replace(' ', ' '); // 全角格替换为半角格 } if (StringUtils.isBlank(str)) { // 现在可以处理全角格了吗?实际上替换后全角格变成了半角格,所以可以被识别 // ... } ``` 但更简单的方法是使用支持全角格的工具,者自定义一个方法: ```java public static boolean isBlankIncludingFullWidth(String str) { if (str == null) { return true; } // 将全角格替换为半角格,然后调用isBlank(Java 11+) str = str.replace(' ', ' '); return str.isBlank(); } ``` 不过,在大多数情况下,用户输入的格可能是混合的,所以替换处理是一种可行方案。 最后,根据用户需求,我们给出一个通用的判断变量是否为的指导,具体实现需要根据变量类型和业务场景灵活选择。</think>在 Java 中判断变量是否为空值需要根据变量类型采用不同的方法。以下是针对不同数据类型的详细判断方法,结合引用内容进行说明: ### 一、基本类型判断 1. **基本数据类型**(int, double, boolean等): ```java int num = 0; if (num == 0) { // 基本类型不能为null,但可检查默认值 // 处理空值逻辑 } ``` > 注意:boolean 默认 false,Boolean 默认 null[^2] 2. **包装类**(Integer, Double, Boolean等): ```java Integer num = null; if (num == null) { // 直接判断null // 处理空值逻辑 } ``` ### 二、引用类型判断 #### 1. 字符串空值判断 ```java String str = null; // 方法1:标准判断(推荐) if (str == null || str.isEmpty()) { // 包含null字符串"" } // 方法2:Apache Commons(需引入依赖) import org.apache.commons.lang3.StringUtils; if (StringUtils.isEmpty(str)) { // 处理空值逻辑 } // 方法3:包含白字符判断(Java 11+) if (str == null || str.isBlank()) { // 包含null、""和纯格 } ``` > 注意中文格问题:全角格` `需特殊处理[^4] #### 2. 集合空值判断 ```java List<String> list = null; // 方法1:标准判断 if (list == null || list.isEmpty()) { // 处理集合 } // 方法2:Apache Commons import org.apache.commons.collections4.CollectionUtils; if (CollectionUtils.isEmpty(list)) { // 处理集合 } ``` #### 3. 数组空值判断 ```java String[] array = null; // 方法1:原生判断 if (array == null || array.length == 0) { // 处理数组 } // 方法2:Apache Commons import org.apache.commons.lang3.ArrayUtils; if (ArrayUtils.isEmpty(array)) { // 处理数组[^1] } ``` #### 4. 对象空值判断 ```java // 方法1:Objects工具类(Java 7+) import java.util.Objects; if (Objects.isNull(obj)) { // 对象为null[^1] } // 方法2:Apache Commons import org.apache.commons.lang3.ObjectUtils; if (ObjectUtils.isEmpty(obj)) { // 对象为null集合/数组[^1] } ``` ### 三、通用最佳实践 1. **防御式编程**: ```java // 使用三元运算符提供默认值 String result = (str != null) ? str : "default"; // 使用Optional(Java 8+) Optional.ofNullable(obj).orElse(defaultValue); ``` 2. **链式空值检查**: ```java // 避免多层嵌套判断 if (obj != null && obj.getList() != null && !obj.getList().isEmpty()) { // 安全操作 } ``` 3. **自定义工具类**: ```java public class NullUtils { public static boolean isNullOrEmpty(Object obj) { if (obj == null) return true; if (obj instanceof String) return ((String) obj).isEmpty(); if (obj instanceof Collection) return ((Collection) obj).isEmpty(); if (obj instanceof Map) return ((Map) obj).isEmpty(); if (obj.getClass().isArray()) return Array.getLength(obj) == 0; return false; } } ``` ### 四、不同场景推荐方案 | 数据类型 | 推荐方法 | 注意事项 | |----------------|----------------------------------|----------------------------| | 字符串 | `str == null || str.isEmpty()` | 中文格需特殊处理[^4] | | 集合 | `CollectionUtils.isEmpty()` | 需添加Apache Commons依赖 | | 数组 | `ArrayUtils.isEmpty()` | 支持多维数组 | | 通用对象 | `Objects.isNull()` | Java原生方法,无需依赖 | | 复杂对象嵌套 | 自定义工具类 + Optional | 避免深层嵌套 | > **关键提示**:空值判断应考虑业务场景: > 1. 用户输入:需过滤格(`trim()`) > 2. API响应:需区分`null`和集合 > 3. 数据库查询:需处理SQL NULL
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值