什么是Java方法?

Java方法,也就是函数,就是就是用来解决一类问题的代码的有序组合,是一个功能模块。

方法的声明

  1. 访问修饰符 返回类型 方法名(参数列表) {
  2. 方法体
  3. }
  4. public static void main(String[] args) {
  5. System.out.println("Hello,World!");
  6. }

访问修饰符

访问修饰符就是方法允许被访问的范围,如上述中的main方法,public就是访问修饰符,表示公共的,可以在Java程序的任意位置被访问。static表示静态的,表示谁可以使用该方法,类和类的对象都可以使用。

返回类型

返回类型可以是void和其他任何类型的数据(包括自己创造的数据类型)。void表示空,即该方法没有返回值。
如果一个方法存在返回值,则方法定义上的返回值类型就是该返回值的类型(可以是任意类型,包括自己创建的类型)

方法名

方法名需要满足标识符的全部规则外还需要满足驼峰原则。

参数列表

参数列表可以省略,既没有参数,同样参数可以有多个,每个参数之间使用逗号间隔,参数由数据类型和参数名构造,类似变量的定义。

方法的分类

根据参数和返回值,方法可以分为四类:

  1. 无参无返回值;
  2. 无参有返回值;
  3. 带参无返回值;
  4. 带参有返回值;

无参无返回值的方法


Java方法 - 图1
如图所示,现有要求需要我们在多个场景来打印文字上下方的*符号串,对于这样一种重复的行为,我们希望将这条打印语句放置在一个方法里面,然后每次遇到同样的要求,只需要调用方法就可以了。

  1. public class Practice {
  2. // 打印输出星号的方法
  3. public void printStar() {
  4. System.out.println("********************************");
  5. }
  6. public static void mian (String[] args) {
  7. //对于一个没有使用static修饰的方法,需要使用类的对象来调用
  8. //创建一个Practice类的对象prc
  9. Practice prc=new Practice();
  10. //使用对象名.方法名()去调用方法
  11. prc.printStar();
  12. //如果是static修饰的方法,调用可以是类的调用方法或者直接调用,如Practice.printStar()或printStra()
  13. System.out.println("欢迎来到Java的世界!");
  14. prc.printStar();
  15. }
  16. }
  17. 在方法上的文档注释可以作为该方法的说明,当光标停滞在方法上时,会有弹窗说明。
  18. 文档注释一般放在方法上,构造器上和类上。表明这三者的作用

无参有返回值的方法

求一个长宽都是整数的长方形面积。

  1. public class Rectangle {
  2. /**
  3. *一个求长方形面积的方法area()
  4. *长宽都是整数,所以返回类型为int
  5. */
  6. public int area() {
  7. int length=10;
  8. int width=5;
  9. int area=length*width;
  10. return area;//返回语句,变量名和方法名可以一致,同时注意方法返回值需要和规定的返回值一致。
  11. }
  12. public static void main(String[] args) {
  13. Rectangle rc=new Rectangle();
  14. int a = rc.area();//只要返回值不是void,可以在调用方法时,设置变量来承接该方法的返回值
  15. System.out.println("长方形的面积为:"+rc.area());
  16. }
  17. }

带参无返回值的方法

定义一个求两个float类型的数据最大值的方法,在方法中将最大值打印输出。

  1. public class MaxDemo {
  2. public void max(float a, float b) {//形式参数(形参)
  3. float max;
  4. if(a > b) {
  5. max = a;
  6. } else {
  7. max = b;
  8. }
  9. System.out.println("最大值为:" + max);
  10. }
  11. public static void main(String[] args) {
  12. MaxDemo md = new MaxDemo();
  13. //在Java中,当定义方法规定参数的参数类型和参数个数时,必须在调用该方法时完全满足
  14. //传递数值时主方法中可以是变量,也可以是一个字面值,不同类型传递会出现类型转换
  15. //float f1 = 1.2;
  16. //float f2 = 2.2;
  17. //md.max(f1,f2);
  18. //在调用该方法时,对于基本数据类型,方法的参数类型一般不会兼容(是指高级变量转为低级变量不兼容)
  19. md.max(1.1, 1.3);//实际参数(实参)
  20. }
  21. }

带参有返回值的方法

定义一个求n!的方法,然后再求1!+ 2!+3!+4!+5!

  1. public class Four {
  2. //方法不能嵌套定义
  3. //求阶乘的方法
  4. public int fac(int n) {
  5. int s=1;
  6. for(int i=1;i<=n;i++) {
  7. s*=i;//s=s*i;
  8. }
  9. return s;
  10. }
  11. //阶乘和
  12. public int facSum(int n){
  13. int sum = 0;
  14. for(int i=0;i<n;i++){
  15. //可以在无static的方法中直接调用另一个无static修饰的方法
  16. sum = sum + fac(i);
  17. }
  18. return sum;
  19. }
  20. public static void main(String[] args) {
  21. Four four=new Four();
  22. int fac=four.fac(3);
  23. System.out.println("3!="+fac);
  24. int sum=0;
  25. //求1!+2!+3!+4!+5!
  26. for(int i=1;i<=5;i++){
  27. fac=four.fac(i);
  28. sum+=fac;
  29. }
  30. System.out.println("1!+2!+3!+4!+5!="+sum);
  31. }
  32. }

方法的定义必须定义在类的里面,但是不能定义在另外一个方法的里面。方法不能嵌套,带有返回值的方法是为了参与进一步的运算。

数组作为方法参数

定义方法,打印输出数组元素的值。

  1. public class Five {
  2. //打印输出数组元素的值
  3. public void printArry(int[] arr) {
  4. for(int i=0;i<arr.length;i++) {
  5. System.out.print(arr[i]+" ");
  6. }
  7. System.out.println();
  8. }
  9. public static void main(String[] args) {
  10. int[] arr= {10,20,30,40,50};
  11. Five am=new Five();
  12. am.printArry(arr);
  13. //也可以是am.printArry(new int[]{10,20,30,40,50});
  14. }
  15. }

合并数组

  1. public class Demo {
  2. public int[] getArray(int[] a,int[] b){
  3. int[] c = new int[a.length+b.length];
  4. //将a数组元素填充到c数组中
  5. for(int i = 0;i<a.length;i++) {
  6. c[i] = a[i];
  7. }
  8. for(int i = 0;i<b.length;i++) {
  9. int j = i + a.length;//填充a数组后,索引应该是a.length开始
  10. c[j] = b[i];
  11. }
  12. return c;
  13. }
  14. public static void main(String[] args) {
  15. Demo demo = new Demo();
  16. int[] arr1 = {1,2,3};
  17. int[] arr2 = {4,5,6};
  18. demo.getArray(arr1,arr2);
  19. }
  20. }

方法重载

方法重载简单概括就是方法名相同,参数列表不同。

  1. //如果方法名相同,参数列表也相同,这属于方法的重复定义,不属于方法重载
  2. public void hello(){}
  3. public int hello(){}
  1. //参数列表和参数的个数,参数的类型,参数的排序有关,和参数名无关
  2. public void hello(String str){}
  3. public void hello(String s){}//这两个不属于方法重载
  4. public void hello(int a,String str){}
  5. public void hello(String str,int a){}//这两个属于方法重载

通过方法重载可以定义很多相似的方法,这些方法共用一个方法名,根据参数的不同决定调用哪个方法。

定义三个同名方法,实现int、double和数组类型的求和。

  1. public class MathDemo {
  2. //求两个int类型数的和
  3. public int plus(int m,int n){
  4. return m+n;
  5. }
  6. //求两个double类型数的和
  7. public double plus(double m,double n){
  8. return m+n;
  9. }
  10. //求数组元素的累加和
  11. public int plus(int[] arr){
  12. int sum=0;
  13. for(int i=0;i<arr.length;i++){
  14. sum=sum+arr[i];
  15. }
  16. return sum;
  17. }
  18. public static void main(String[] args) {
  19. int m=5,n=10;
  20. int[] arr={1,2,3,4,5,6};
  21. MathDemo mathDemo=new MathDemo();
  22. System.out.println("int类型的和:"+mathDemo.plus(m,n));
  23. System.out.println("double类型的和:"+mathDemo.plus(5.6,7.8));
  24. System.out.println("数组元素的和:"+mathDemo.plus(arr));
  25. }
  26. }

方法的传值

基本数据类型的传值

对两个变量的值进行交换并打印输出(传值问题)

  1. public class ExchangeDemo {
  2. //交换方法
  3. public void swap(int a,int b){
  4. int temp;
  5. System.out.println("交换前:a="+a+","+"b="+b);
  6. temp=a;
  7. a=b;
  8. b=temp;
  9. System.out.println("交换后:a="+a+","+"b="+b);
  10. }
  11. public void swapTest(){
  12. //ExchangeDemo ex=new ExchangeDemo();
  13. //普通方法调用方法不需要定义对象,直接调用即可 方法名(实参);
  14. int m=4,n=5;
  15. System.out.println("交换前:m="+m+","+"n="+n);
  16. swap(m,n);
  17. System.out.println("交换后:m="+m+","+"n="+n);
  18. }
  19. public static void main(String[] args) {
  20. ExchangeDemo ex=new ExchangeDemo();
  21. ex.swapTest();
  22. /*int m=4,n=5;
  23. System.out.println("交换前:m="+m+","+"n="+n);
  24. ex.swap(m,n);
  25. System.out.println("交换后:m="+m+","+"n="+n);*/
  26. }
  27. }

在方法运行之后,我们会发现,m与n的值并没有发生改变。这是因为首先创建m,n变量,会在内存中开辟空间存储对应的值,然后在方法调用的时候把m和n的值传给变量a,b,这时候只是把4和5这两个值传过去了。并不是把m和n的内存地址传递过去了。
总结:如果方法的参数是基本数据类型,那么在方法内对参数进行修改,不会影响到传递的实际参数。

数组的传值(通过数组来看引用数据类型的传值)

  1. public class Ten {
  2. //定义一个用于修改某个数组元素值的方法
  3. public void updateArry(int[] a) {
  4. a[3]=15;
  5. System.out.println("数组a的元素为:");
  6. for(int n:a) {
  7. System.out.print(n+" ");
  8. }
  9. System.out.println();
  10. }
  11. public static void main(String[] args) {
  12. Ten b=new Ten();
  13. int[] a1= {1,2,3,4,5};
  14. System.out.println("方法调用前数组a1元素为:");
  15. for(int n:a1) {
  16. System.out.print(n+" ");
  17. }
  18. System.out.println();
  19. b.updateArry(a1);
  20. System.out.println("方法调用后数组a1元素为:");
  21. for(int n:a1) {
  22. System.out.print(n+" ");
  23. }
  24. }
  25. }

如果主方法中声明的是数组(引用数据类型),则传值是把变量地址传过去了(传过去的是数组的第一个元素的地址),在普通方法中修改变量会影响主方法的变量。传值都是传的的变量里的值,基本数据类型的是值本身,引用类型的是对象的地址。
总结:当方法的参数为引用数据类型时,在方法中对参数进行修改,会影响到方法外的参数。
特殊:String虽然时引用数据类型,但是它经过方法后不会被修改。

可变参数列表

可变参数列表指的是参数的数量不固定,但是参数的类型是固定的,参数列表规定了是哪一种类型,随后的参数就只能是哪一种类型。

  1. public void sum(int...n) {
  2. }
  3. public class Demo {
  4. //求和
  5. public void sum(int...n) {
  6. int sum = 0;
  7. for(int i:n) {//其实我们可以将可变参数列表看作为一个数组
  8. sum = sum + i;
  9. }
  10. System.out.println("sum="+sum);
  11. }
  12. public static void main(String[] args) {
  13. Demo de = new Demo();
  14. de.sum(1);
  15. de.sum(1,2);
  16. de.sum(1,2,3);
  17. //de.sum(1,1.2);传入的必须是int类型
  18. //de.sum(new int[]{1,2,3});也可以用数组代替
  19. }
  20. }

可变参数列表可以看作是数组

  1. public void sum(int...n){}
  2. public void sum(int[] n){}//这两个属于重复定义

参数列表中如果有两个或两个以上的参数,可变参数一定是在最后的。

  1. public class ArgsDemo1 {
  2. //查找
  3. public void search(int n,int...a){//参数列表中如果有两个或两个以上的参数,可变参数一定是在最后的。
  4. boolean flag=false;
  5. for(int a1:a){
  6. if(a1==n){
  7. flag=true;
  8. break;
  9. }
  10. }
  11. if(flag){
  12. System.out.println("找到了"+n);
  13. } else{
  14. System.out.println("没找到"+n);
  15. }
  16. }
  17. /*public void search(int n, int[] a) {
  18. //可变参数方法换成数组是不算重载的,算重复定义
  19. }*/
  20. /*public void search(int n, int... a, int...b) {
  21. //一个方法中只能有一个可变参数。
  22. }*/
  23. public static void main(String[] args) {
  24. ArgsDemo1 ad1=new ArgsDemo1();
  25. ad1.search(3,1,2,3,4,5);
  26. int[] a={1,2,3,4,5};
  27. ad1.search(3,a);//可变参数列表可以和数组进行兼容,可以将数组传递给可变参数列表
  28. }
  29. }

总结:

  1. 可变参数列表指的是参数数量是不确定的,可以随时变化,有时候也称可变原参数。
  2. 参数列表中如果有两个或两个以上的参数,可变参数一定是在最后的。例如:public void a(int a,int… b){ }是正确的,但是如果把int… b写前面则是错误的。
  3. 可以将数组传递给可变参数。
  4. 一个方法中只能有一个可变参数。
  5. 可变参数方法换成数组是不算重载的,算重复定义。

可变参数列表作为方法参数的重载问题

  1. public class Demo {
  2. public int sum(int a, int b) {
  3. System.out.println("不带可变参数列表的方法被调用");
  4. return a + b;
  5. }
  6. //求和
  7. public int sum(int...n) {
  8. int sum = 0;
  9. for(int i:n) {//其实我们可以将可变参数列表看作为一个数组
  10. sum = sum + i;
  11. }
  12. System.out.println("带可变参数列表的方法被调用");
  13. return sum;
  14. }
  15. public static void main(String[] args) {
  16. Demo de = new Demo();
  17. System.out.println("和为:" + de.sum(1,2));
  18. System.out.println("和为:" + de.sum(3,4));
  19. System.out.println("和为:" + de.sum(3,4,5));
  20. }
  21. }

总结:
若有多个重载方法,则可变参数列表所在的方法是最后被访问的(如果主方法所传参数其他重载方法可以满足,则调用其他方法,只有其他方法都不满足,才会调用可变参数列表所在的方法)。