首页 > 技术文章 > Java方法02--方法的定义和调用,方法的重载,命令行传参,可变参数

studyhao1999 2021-12-03 21:52 原文

Java方法02--方法的定义和调用,方法的重载,命令行传参,可变参数

方法的定义

  • Java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段,一般情况下,定义一个方法包含以下语法:

  • 方法包含一个方法头和一个方法体。下面是一个方法的所有部分:

    • 修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。public static

    • 返回值类型:方法可能会返回值,returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType是关键字void

    • 方法名:是方法的实际名称。方法名和参数表共同构成方法签名。(驼峰命名)

    • 参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数

      • 形式参数:在方法被调用时用于接受外界输入的数据。
      image-20211203202007132
      • 实参:调用方法时实际传给方法的数据。

      image-20211203201956393

    • 方法体:方法体包含具体的语句,定义该方法的功能。

修饰符 返回值类型 方法名(参数类型 参数名){
    ...
    方法体
    ···
    return 返回值;
}
package com.studyhao1999.method;

public class Demo02 {
    public static void main(String[] args) {
        int max=max(10,10);
        System.out.println(max);

    }
    //比大小
    public static int max(int num1,int num2){
        int result=-1;//此处需要给result初始化,要不会报错
        if (num1==num2){
            System.out.println("num1==num2");
            return 0;//终止方法
        }
        if(num1>num2){
            result=num1;//不能直接写return num1,用result来接受;
        }else{
            result=num2;
        }
        return result;
    }
}

方法的调用

  • 调用方法:对象名.方法名(实参列表)

  • Java支持两种调用方法的方式,根据方法是否返回值来选择

  • 当方法返回一个值得时候,方法调用通常被当做一个值。例如:

    int larger =max(30,40);
    
  • 如果方法返回值是void,方法调用一定是一条语句。

    System.out.println("Hello,xiaohao!")
    

值传递(Java)和引用传递

参考引用:https://www.cnblogs.com/wenbiquan/p/11081173.html

  • 值传递:传递真实值
  • 引用传递:传递内存地址
  1. 基本类型
public class ValueTest{
    public static void main(String[] args){
        int a=10;
        changVal(a);
        System.out.println(a);
    }
    public static void changVal(int a){
        a+=10;
    }
}

上面得demo输出的是10,而不是20,为什么?

  • 程序运行时,main方法先入栈,然后给变量a分配内存。

  • 当运行到changeVal(a);时,changeVal()方法入栈。当方法入栈时,会给局部变量和形参变量(a)分配内存.

即在changeVal方法栈里面,也有一个名为a,值为10的变量。

  • 由于a+=10;是在changeVal方法栈里面运行的,所以只会改变changeVal方法栈里面的a值,而不会改变main方法栈里面的a值。如下图

image-20211203204622605

  1. String测试
public class ValueTest{
    public static void main(String[] args){
        StringBuilder builder = new StringBuilder("hello");
        changVal(builder);
        System.out.println(builder);
    }
    public static void changVal(StringBuilder builder){
        builder.append(" world");
    }
}
  • 输出是hello world,可见builder的值是改变了.
  • 与基本类型不一样,主要是StringBuilder是引用类型。因此new StringBuilder("hello")的内存是分配在堆区。而在栈区的变量(builder)只保存一个地址(假设为0x345),如下图:

image-20211203205134932

因此,main和changeVal两个方法栈的builder变量都指向了同一块内存。故当changVal方法中改变builder的值,main中的builder也会变化。

  1. Str测试
public class ValueTest{
    public static void main(String[] args){
        String str = "hello";
        changVal(str);
        System.out.println(str);
    }
    public static void changVal(String str){
       str+=" world";
    }
}
  • 上面的demo输出的是:hello,而不是hello world。str记录了对象的地址,那么str的值应该也被改变了才对?

  • 这跟String的"特性"有关,String会被存放在字符串常量池,而且String是不可被改变的(final).

①.在第10行设个断点,当执行到这行的时候,由上面的分析可知,main()和changeVal()方法中的str都指向了常量池中的"hello"字符串。

image-20211203205759795

②.执行str+=" world"时,由于String是不可变的,所以不可能直接在"hello"上做修改。这时会在常量池中新增一个"hello world"的字符串,并将地址传给changeVal()方法栈中的str.

image-20211203210021680

③.因此changeVal()方法中的str指向了新增的"hello world"字符串,而main方法中的str还是指向原来的"hello"。所以输出"hello".

方法的重载

  • 重载就是在一个类中,有相同的函数名称,但形参不同的函数
  • 方法的重载规则:
    • 方法名称必须相同;
    • 参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等);
    • 方法的返回类型可以相同也可以不同;
    • 仅仅返回类型不同不足以成为方法的重载。
  • 实现理论;
    • 方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错。

image-20211203210856797

命令行传参

  • 有时候你希望运行一个程序时候在传递给它消息。这要靠传递命令行参数给main()函数实现。
public class CommandLine{
    public ststic void main(String args[]){
        for(int i=0;i<arg.length;i++){
            System.out.println("args["+i+"]:"+args)
        }
    }
}
  • 如果直接在目录文件夹里进行编译后运行文件会报错:

    image-20211203212937766

  • 解决方法:利用cd../进行目录回退,回退到src目录下,然后再通过Package进行运行

image-20211203213037816 image-20211203213053958

可变参数

  • JDK1.5开始,Java支持传递同类型的可变参数给一个方法。

    image-20211203214047673
  • 在方法声明中,在指定参数类型后加一个省略号(...)。

  • 一个方法中只能指定一个可变参数,它必须是方法最后一个参数,任何普通的参数必须在它之前声明。

    image-20211203214023583
package com.studyhao1999.method;

public class Demo04 {
    public static void main(String[] args) {
        //调用可变参数的方法
        Demo04 demo04 = new Demo04();
        demo04.test(1,2,3,4,5);
    }
    public void test(int...i){
        System.out.println(i[0]);
    }
}

举例:排序

package com.studyhao1999.method;

public class Demo04 {
    public static void main(String[] args) {
        //调用可变参数的方法
        printMax(34,4,43,435,545,44,44.6);
        printMax(new double[]{1,2,3});
    }
    public static void printMax(double...numbles){
        if (numbles.length==0){
            System.out.println("No argument passed");
            return;
        }
        double result = numbles[0];

        //排序!
        for (int i = 1; i <numbles.length ; i++) {
            if (numbles[i]>result){
                result =numbles[i];
            }
        }
        System.out.println("The max value is "+result);
    }
}

推荐阅读