• Java不定参数使用及一些注意情况


    一、背景

    在项目中使用到了StringUtils.isAllBlack(String …css)方法。可以很方便地传递不定数量的参数进行空判。
    但开发过程中遇到了一些问题,所以特地记录一下。

    二、不定参数传参

    不定参数的传参本质上是一个泛型的数组。参数数量大于等于两个的时候,系统会把传入的参数都放到一个对应类型的数组里面。
    但传单个参数的时候存在一些需要注意的情况,不注意可能会出现空指针异常

    2.1、通过引用传单个null
    public class Test {
    	public static void test1(Object... css) {
    		System.out.println(css);
    		for (Object o : css) {
    			System.out.println(o);//null
    		}
    	}
    	public static void main(String[] args) {
    		String s=null;
    		test1(s);
    	}
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    上述代码运行结果是输出:null
    程序把传入的null当成一个元素放到了参数数组里面。
    在这里插入图片描述

    2.2、直接传单个null
    public class Test {
    	public static void test1(Object... css) {
    		System.out.println(css);//null
    		for (Object o : css) {//NullPointException
    			System.out.println(o);
    		}
    	}
    	public static void main(String[] args) {
    		test1(null);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    上述代码并没有把直接传的null当成参数数组的一个元素,而是直接让参数数组为null。因为没有明确告诉程序这个null是什么类型的,系统直接把null的类型转换成不定参数对应的Object[]类型。因此css为空。
    在这里插入图片描述

    2.3、验证直接传null的默认效果
    public class Test {
    	public static void test1(Object... css) {
    		System.out.println(css);
    		for (Object o : css) {
    			System.out.println(o);
    		}
    	}
    	public static void main(String[] args) {
    		test1((Object[]) null);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    上述代码的运行结果和直接传单个null一样,符合预期。
    在这里插入图片描述

    2.4、直接传单个null(加类型强转)
    public class Test {
    	public static void test1(Object... css) {
    		System.out.println(css);
    		for (Object o : css) {
    			System.out.println(o);
    		}
    	}
    	public static void main(String[] args) {
    		test1((Object) null);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    上述代码,因为强转告诉系统参数的数据类型,系统又把null当成了参数数组里面的一个元素来处理。这里的类型强转和2.1、的传参方式本质上是一样的。
    在这里插入图片描述

    2.5、注意

    直接传单个null的时候效果相当于传(T[]) null,css会为空。

    三、StringUtils.isAnyBlank(String …css)注释

    	1.StringUtils.isAnyBlank((String) null)    = true
    	2.StringUtils.isAnyBlank((String[]) null)  = false
    	3.StringUtils.isAnyBlank(null, "foo")      = true
    	4.StringUtils.isAnyBlank(null, null)       = true
    	5.StringUtils.isAnyBlank("", "bar")        = true
    	6.StringUtils.isAnyBlank("bob", "")        = true
    	7.StringUtils.isAnyBlank("  bob  ", null)  = true
    	8.StringUtils.isAnyBlank(" ", "bar")       = true
    	9.StringUtils.isAnyBlank(new String[] {})  = false
    	10.StringUtils.isAnyBlank(new String[]{""}) = true
    	11.StringUtils.isAnyBlank("foo", "bar")     = false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    一个一个解释上面的调用方式,在org.apache.commons.lang3.StringUtils中。
    首先,这个方法是用来判断传入的参数是否存在为空或空串。
    第一个,相当于传入了一个null放在参数数组里面,有一个元素,并且为null,因此为真。
    第二个,默认类型为String[],相当于css为空,也就是参数数组为空,相当于没有传入元素,没有传入参数也就不会有参数为空,因此为假。和StringUtils.isAnyBlank(null)效果一样
    第三个,传入了两个参数,第一个为null,因此为真。
    第四个,传入两个null,多个参数情况下,默认类型是String,两个null,因此为真。
    第五个,第一个参数传入空串,因此为真。
    第六个,第二个参数传入空串,因此为真。
    第七个,第二个参数传入null,因此为真。
    第八个,第一个参数传入空格,空格也在black的判断里面,因此为真。
    第九个,传入一个容量为0的空字符串数组,因为里面没有元素,也就没有元素为空或空串,因此为假。
    第十个,传入一个数组,里面有一个空串,因此为真。
    第十一个,传入两个字符串,都不为空或空串,因此为假。
    再加一种情况,传入一个容量不为0的空字符串数组,因为数组里面默认填充null,因此为真。

    重点需要考虑的就是不同查找时候,对于参数数组为null的情况的处理。
    总的来说可以这样理解:存在xxx,就看元素是否存在xxx,存在就为真,不存在就为假(参数数组都为null的情况当然是不存在)。全部xxx,就查询元素是否存在反xxx,存在就为假,不存在就为真(参数数组都为null的情况当然是不存在)。
    也正是因为如此,存在和全部这两种判断在遇到参数数组为空的时候判断结果才完全相反。

  • 相关阅读:
    为什么要进行数据治理
    线程池执行流程
    第70章 单元测试的定义实现
    【JS面试题】面试官问我:遍历一个数组用 for 和 forEach 哪个更快?
    造轮子之多语言管理
    无人机/飞控--ArduPilot、PX4学习记录(4)
    【gitlab】本地项目上传gitlab
    上交所Binary行情接口demo
    ERP项目施行计划的目的是什么?
    MySQL性能调优关注点和思路
  • 原文地址:https://blog.csdn.net/weixin_43975276/article/details/132733816