当前位置:   article > 正文

java 可变参数

java 可变参数

java可变参数

前言:函数是指定义在类中的一段可以独立运行的小程序,如方法,构造器等。
1.java可变参数是指在调用方法时传入不定长度的参数,本质上是基于数组实现的。

    //参数为可变参数
    public static void element(Integer... args){ }
    //参数为数组
    public static void element(Integer[] args){ }
  • 1
  • 2
  • 3
  • 4

2.在定义方法时,在最后一个形参上加"…"就表示该形参可以接受多个参数值,多个参数值被当做数组传入。

public class Demo1 {

    //参数为可变参数
    public static void element(Integer... args) {
        for (int arg : args) {
            System.out.print(arg + "  ");
        }
        System.out.println();
    }
    
    public static void main(String[] args) {
        element();
        element(1);
        element(1, 2, 3);
    }
    
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

3.可变参数只能做为函数的最后一个参数,前面有没有其他参数都可以,一个函数最多只能有一个可变参数。

	//只有可变参数
	public static void element(Integer... args){ }
	//有其他参数
	public static void element_two(int age,int... args){ }

  • 1
  • 2
  • 3
  • 4
  • 5

4.可变参数在编译为字节码后,在方法签名中是以数组形态出现的,如果两个方法签名编译后的是一致的话,是不能编译通过的,不可以作为方法的重载

    //参数为可变参数
    public static void element(Integer... args){ }
    //参数为数组
    public static void element(Integer[] args){ }

  • 1
  • 2
  • 3
  • 4
  • 5

5.可变参数作为参数的方法可以传入数组类型的数据或者直接传入多个数据,但是数组作为参数的方法只能传入数组类型的数据。

public class Demo2 {

	//可变参数作为参数的方法
    public static void element(int... args) {
        for (int arg : args) {
            System.out.println(arg);
        }
    }
    
     public static void main(String[] args) {
      //都可以
      element(1,2,3);
      int[] array={1,2,3};
      element(array);
   }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
public class Demo2 {

	//数组作为参数的方法
    public static void element(int[] args) {
        for (int arg : args) {
            System.out.println(arg);
        }
    }
    
     public static void main(String[] args) {
     //不可以,编译错误
      element(1,2,3);
      //可以
      int[] array={1,2,3};
      element(array);
   }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

6.方法重载

1)调用一个被重载的方法时,如果此调用既能够和固定长度的重载方法匹配,又能和可变参数的重载方法匹配的话,会优先选择固定参数的重载方法。

public class Demo2 {
    
    public static void element(int... args){
        for (int arg : args) {
            System.out.println(arg);
        }
    }
    
    public static void element(int age,int money){
        System.out.println(age+"    "+money);
    }
    
    public static void main(String[] args) {
    	//会优先选择固定参数的方法
        element(1,2);
    }
    
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

2)当调用一个被重载的方法时,如果此调用能够和两个有可变参数的重载方法匹配,会出现编译错误。

public class Demo2 {

    public static void element(int... args) {
        for (int arg : args) {
            System.out.println(arg);
        }
    }

    public static void element(int age, int... args) {
        System.out.println(age);
        for (int arg : args) {
            System.out.println(arg);
        }
    }

    public static void main(String[] args) {
    	//会出现编译错误,不可以运行
        element(1, 2);
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

3)避免使用空值和null,当两个方法的方法名和其他参数都相同,只有可变参数不同的时候,传入空值或者null会产生编译错误。

public class Demo2 {

    public static void element(int age, int... args) {
        System.out.println(age);
        for (int arg : args) {
            System.out.println(arg);
        }
    }

    public static void element(int age, String... args) {
        System.out.println(age);
        for (String arg : args) {
            System.out.println(arg);
        }
    }

    public static void main(String[] args) {
    	//传入空值或者null,无法区分调用哪一个方法,会编译错误
        element(1);
        element(1,null);
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

修改方法:让编译器知道传入的null是什么类型的,好让他找到对应的方法。

public static void main(String[] args) {
        int[] array=null;
        element(1,array);
    }

  • 1
  • 2
  • 3
  • 4
  • 5

7.方法覆写
有一种十分特殊的情况,父类方法用的是可变参数,而子类覆写使用的是数组,虽然覆写的方法参数和父类不一样,但是可以编译通过,不过不建议采用。

public class Demo3 {

    public static void main(String[] args) {
        //可以编译成功,编译看左边,运行看右边
        Father father=new Sun();
        father.element(1);
        //不可以编译通过,编译看左边,参数
        Sun sun = new Sun();
        sun.element(1);
    }

    //父类
    public static class Father {
        public  void element(int... args) {
            System.out.println("可变参数");
        }
    }

    //子类
    public static class Sun extends Father {
        public  void element(int[] args) {
            System.out.println("数组");
        }
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

方法覆写必须满足以下条件:
1)覆写方法不能缩小访问权限。
2)参数列表必须和被覆写方法保持一致(包括表现形式)。
3)返回类型必须与被覆写方法相同或者是其子类。
4)覆写方法不能抛出新的异常,或者超出父类范围的异常,但是可以不抛出或者抛出范围更小的异常。

8.使用Object…作为可变参数会出现多种情况。

public class Demo4 {

    public static void element(Object... args){
        System.out.println(args.length);
    }

    public static void main(String[] args) {
        //Integer[]可以转型为Object[],可以作为一个对象数组
        element(new Integer[]{1,2,3});
        //多个参数的话,Integer[]会被当做一个单纯的数组对象
        element(1,new Integer[]{2,3});
        element(1,2,3);
        //int[] 无法转型为Object[],因此会被当做一个单纯的数组对象
        element(new int[]{1,2,3});
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

9.反射时,可变参数的注意事项。

public class Demo5 {

    public static void element(Integer... args){
        System.out.println(args.length);
    }

    public static void main(String[] args) {
        Integer[] arrry={1,2,3};
        try {
            //反射是运行时获取的,在运行时看来,可变参数和数组上是一致的。因而方法的签名为([java/lang/Integer;)V
            //Method对象的方法声明为Object invoke (Object obj,Object.. args)
            //args虽然是一个可变长度的参数,但是args的长度受限于该方法对象代表的真实方法的参数列表长度,从运行时签名来看,([java/lang/Integer;)V实际上是一个形参,即Integer[] args,因此invoke (Object obj,Object.. args)中可变参数args的实际参数长度只能为1。
            Method method = Demo5.class.getMethod("element", Integer[].class);
            //array的长度为3,不符合
            method.invoke(null,arrry);
            //将Integer[]转为Object[],长度还是为3,不符合
            method.invoke(null,(Object[])arrry);
            //将整个Integer[]转为一个Object,长度为1,符合
            method.invoke(null,(Object)arrry);
            //Object[]的长度为1,符合,和上面相同
            method.invoke(null,new Object[]{arrry});
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

整理借鉴了很多大佬写的,在此无法一一说明,这只是个人用来查漏补缺的文章,如果对你有帮助我很高兴。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/156076
推荐阅读
相关标签
  

闽ICP备14008679号