JAVA: null或空值的判断处理 (判断对象是否为空)

1,错误用法一:

if (name == "") {
     //do something
}

2,错误用法二:

if (name.equals("")) {
//do something
}

3,错误用法三:

if (!name.equals("")) {
//do something
}

我们来解说一下:
上述错误用法1是初学者最容易犯,也最不容易被发现的错误,因为它们的语法本身没问题,Java编译器编译时不报错。但这种条件可能在运行时导致程序出现bug,永远也不会为true,也就是时说,if块里的语句永远也不会被执行。

上述用法二,用法三 的写法,是包括很多Java熟手也很容易犯的错误,为什么是错误的呢?也许你会感到纳闷。
对,它们的写法本身没错,但是,少了一个null判断的条件,试想,如果name=null的情况下,会发生什么后果呢?后果是,你的程序将抛出NullPointerException异常,系统将被挂起,不再提供正常服务。
当然,如果之前已经对name作了null判断的情况例外。

正确的写法应该先加上name != null的条件,如例:

if (name != null && !name.equals("")) {
//do something
}

或者

if (!"".equals(name)) {//将""写在前头,这样,不管name是否为null,都不会出错。
//do something
}

下面,我们举一个简单的例子:

TestNullOrEmpty.java

public class TestNullOrEmpty 
{

	public static void main(String[] args) 
	{
		String value = null;
		testNullOrEmpty(value);

		value = "";
		testNullOrEmpty(value);

		value = " ";
		testNullOrEmpty(value);

		value = "hello me! ";
		testNullOrEmpty(value);
	}

	static void testNullOrEmpty(String value) 
	{
		if (value == null ) 
		{ 
			//正确的写法
			System.out.println("value is null. ");
		} 
		else if ("".equals(value)) 
		{ 
			//正确的写法
			System.out.println("value is blank but not null. ");
		} 
		else {
			System.out.println("value is /" " + value + "/" ");
		}

		if (value == "") {  //NG 错误的写法
			//别用这种写法
		}
	}
}

编译执行:
c:/>javac TestNullOrEmpty.java

c:/>Java TestNullOrEmpty
value is null.
value is blank but not null.
value is ” ”
value is “hello me!”

java 中如何判断一个未知对象是否为空呢?

下面是一个通用的方法,判断字符串是否为空,集合是否为空,数组是否为空:

/**
	 * 判断对象或对象数组中每一个对象是否为空: 对象为null,字符序列长度为0,集合类、Map为empty
	 * 
	 * @param obj
	 * @return
	 */
	public static boolean isNullOrEmpty(Object obj) {
		if (obj == null)
			return true;

		if (obj instanceof CharSequence)
			return ((CharSequence) obj).length() == 0;

		if (obj instanceof Collection)
			return ((Collection) obj).isEmpty();

		if (obj instanceof Map)
			return ((Map) obj).isEmpty();

		if (obj instanceof Object[]) {
			Object[] object = (Object[]) obj;
			if (object.length == 0) {
				return true;
			}
			boolean empty = true;
			for (int i = 0; i < object.length; i++) {
				if (!isNullOrEmpty(object[i])) {
					empty = false;
					break;
				}
			}
			return empty;
		}
		return false;
	}

参考:org.apache.commons.lang.StringUtils

应用场景:

读取excel文件,转化为一个二维数组:Object[][] arrays

但是excel中有空行,所以需要过滤Object[][] arrays中的空的一维数组:

/***
	 * 过滤数组中的空元素
	 * 
	 * 
	 * @param arrays
	 * @return
	 */
	public static Object[][] filterEmpty(Object[][] arrays) {
		int sumNotNull = 0;
		/***
		 * 统计非空元素的总个数
		 */
		for (int i = 0; i < arrays.length; i++) {
			Object object = arrays[i];
			if (!ValueWidget.isNullOrEmpty(object)
					&& !SystemUtil.isNullOrEmpty((Object[]) object)) {// 判断元素是否为空
				sumNotNull = sumNotNull + 1;
			}
		}
		Object[][] filtedObjs = new Object[sumNotNull][];
		int index = 0;
		for (int i = 0; i < arrays.length; i++) {
			Object[] object_tmp = arrays[i];
			if (!ValueWidget.isNullOrEmpty(object_tmp)
					&& !SystemUtil.isNullOrEmpty((Object[]) object_tmp)) {// 判断元素是否为空
				filtedObjs[index++] = object_tmp;
			}
		}
		return filtedObjs;
	}

参阅附件中的方法com.common.util.SystemUtil.filterEmpty

判断对象的所有成员变量是否为空

/***
	 * Determine whether the object's fields are empty
	 * 
	 * @param obj
	 * @param isExcludeZero  :true:数值类型的值为0,则当做为空;----false:数值类型的值为0,则不为空
	 * 
	 * @return
	 * @throws SecurityException
	 * @throws IllegalArgumentException
	 * @throws NoSuchFieldException
	 * @throws IllegalAccessException
	 */
	public static boolean isNullObject(Object obj, boolean isExcludeZero)
			throws SecurityException, IllegalArgumentException,
			NoSuchFieldException, IllegalAccessException {
		if(ValueWidget.isNullOrEmpty(obj)){//对象本身就为null
			return true;
		}
		List<Field> fieldList = ReflectHWUtils.getAllFieldList(obj.getClass());
		boolean isNull = true;
		for (int i = 0; i < fieldList.size(); i++) {
			Field f = fieldList.get(i);
			Object propertyValue = null;
			try {
				propertyValue = getObjectValue(obj, f);
			} catch (NoSuchFieldException e) {
				e.printStackTrace();
			}

			if (!ValueWidget.isNullOrEmpty(propertyValue)) {// 字段不为空
				if (propertyValue instanceof Integer) {// 是数字
					if (!((Integer) propertyValue == 0 && isExcludeZero)) {
						isNull = false;
						break;
					}
				} else if (propertyValue instanceof Double) {// 是数字
					if (!((Double) propertyValue == 0 && isExcludeZero)) {
						isNull = false;
						break;
					}
				}else if (propertyValue instanceof Float) {// 是数字
					if (!((Float) propertyValue == 0 && isExcludeZero)) {
						isNull = false;
						break;
					}
				}else if (propertyValue instanceof Short) {// 是数字
					if (!((Short) propertyValue == 0 && isExcludeZero)) {
						isNull = false;
						break;
					}
				}else {
					isNull = false;
					break;
				}
			}
		}
		return isNull;
	}

测试:

@Test
	public void test_isNullObject() throws SecurityException,
			IllegalArgumentException, NoSuchFieldException,
			IllegalAccessException {
		Person2 p = new Person2();
		Assert.assertEquals(true, ReflectHWUtils.isNullObject(p, true));
		Assert.assertEquals(false, ReflectHWUtils.isNullObject(p, false));

		p.setAddress("beijing");
		Assert.assertEquals(false, ReflectHWUtils.isNullObject(p, true));
		Assert.assertEquals(false, ReflectHWUtils.isNullObject(p, false));

		p.setAddress(null);
		p.setId(0);
		Assert.assertEquals(true, ReflectHWUtils.isNullObject(p, true));
		Assert.assertEquals(false, ReflectHWUtils.isNullObject(p, false));

	}

Person2 源代码(省略getter,setter方法):

import java.sql.Timestamp;

public class Person2 {
	private int id;
	private int age;
	private double weight;
	private String personName;
	private Timestamp birthdate;
	public String identitify;
	protected String address;
	String phone;
	
}

 

Leave a Reply