Java SE基础知识详解第[3]期—方法

简介: Java SE基础知识详解第[3]期—方法

1.方法是什么

方法是一种语法结构,它可以把一段代码封装成一个功能,以便重复调用。

示例代码如下:

publicstaticvoidmain(String[] args) {
intc1=sum(10, 30);
System.out.println(c1);
    }
publicstaticintsum(inta, intb) {
intc=a+b;
returnc;
    }

2.方法的定义、调用

2.1完整格式的方法定义、调用

方法定义的完整格式

修饰符 返回值类型 方法名(形参列表){

方法体代码(需要执行的功能代码);

return 返回值;

}

示例如下图所示。

Method.png

法必须调用才可以运行,调用格式:方法名(...);

法申明了具体的返回值类型,内部必须使用return返回对应类型的数据。

形参列表可以没有或者有一个或多个,如果有多个形参,形参之间必须用,隔开,且不能初始化值

2.2其他形式的方法定义、调用

方法定义时:返回值类型、形参列表可以按照需求进行填写。

示例代码如下:

publicstaticvoidmain(String[] args) {
print();// HelloWorld// HelloWorld// HelloWorld    }
/*** create by: 全聚德在逃烤鸭、* description: 无参数无返回值的方法* create time: 2022/3/28 0028 10:03** @param* @return void*/publicstaticvoidprint() {
for (inti=0; i<3; i++) {
System.out.println("HelloWorld");
        }
    }

如果方法不需要返回结果,返回值类型必须申明成void(无返回值),此时方法内部不可以使用return返回数据。

方法如果没有参数,或者返回值类型申明为void可以称为无参数、无返回值的方法,依次类推

3.方法使用的常见问题

1.方法的编写顺序无所谓。

方法定义在main方法上面或下面均可,二者没有区别。

示例代码如下:

//定义在main方法上面publicstaticintsum1(inta, intb) {
returna+b;
    }
publicstaticvoidmain(String[] args) {
//        方法的编写顺序无所谓。System.out.println(sum1(10,20)); // 30System.out.println(sum2(100,200)); // 300    }
//定义在main方法下面publicstaticintsum2(inta, intb) {
returna+b;
    }
2.方法与方法之间是平级关系,不能嵌套定义。方法与方法之间不能嵌套,如果把某一方法定义到另一方法内部,会报错。示例代码如下:publicstaticvoidmain(String[] args) {
publicstaticvoidprint() { // 报错,方法定义不能嵌套System.out.println("HelloWorld");
        }
}

3.方法的返回值类型为void(无返回值),方法内则不能使用return返回数据,如果方法的返回值类型写了具体类型,方法内部则必须使用return返回对应类型的数据。

示例代码如下:

publicstaticvoidprint() {
System.out.println("HelloWorld");
//        return 2; // 报错,无返回值方法中不能用return返回数据    }
publicstaticintadd() {
Stringa="A123";
intb=0;
//        没有return,报错,必须有int型返回值//        return "a"; // 报错,返回值类型必须与方法定义中的返回值类型一致,为int型returnb;
    }

4.return语句下面,不能编写代码,因为永远执行不到,属于无效的代码。

示例代码如下

publicstaticintsum(inta, intb) {
returna+b;
//            System.out.println("HelloWorld"); // 报错,上方有return语句,此行代码不会执行        }

5.方法不调用就不执行, 调用时必须严格匹配方法的参数情况。

方法定义后,在使用时必须调用,否则不会执行,且在调用过程中,传入参数的数量和类型必须与方法定义中的数据类型相同,否则报错。

示例代码如下:

publicstaticvoidmain(String[] args) {
//        方法不调用不会执行inta=sum1(10); // 报错,传入参数数量不符,需要传入2个参数intc=sum1(10,2.5); // 报错,传入参数数据类型不符,需要int型intb=sum1(20, 10);
    }
publicstaticintsum1(inta, intb) {
returna+b;
    }

6.有返回值的方法调用时可以选择定义变量接收结果,或者直接输出调用,甚至直接调用;无返回值方法的调用只能直接调用。

示例代码如下:

publicstaticvoidmain(String[] args) {
//        6.有返回值的方法调用时可以选择定义变量接收结果,或者直接输出调用,甚至直接调用;无返回值方法的调用只能直接调用。// 定义变量接收inta=sum2(100, 200); // 300// 输出调用System.out.println(sum2(1000,2000)); // 3000// 直接调用(调用方法,让程序跑一下,不接收返回结果)sum2(150,150); // 300// 无返回值的方法只能直接调用,否则报错print1(); //打印HelloWorld//      int c = print1(); // 报错,需要返回数据类型为int的数据,print1()方法无返回值    }
publicstaticintsum2(inta, intb) {
returna+b;
    }
publicstaticvoidprint1() {
System.out.println("HelloWorld");
    }

4.方法案例

方法定义技巧说明

MethodDefinition.png

如上图所示,修饰符:public static (暂时固定的)

方法名称:自己取名,有意义,英文小写,驼峰模式。(有意义的名字即可)

方法体代码:完成自己需要写的功能代码即可。(具体需求具体实现)

真正需要关注的就两点:

1、分析方法是否需要声明返回值类型;2、分析方法是否需要接收参数。

4.1计算1-n的和并返回

需求:定义一个方法,方法中计算出1-n的和并返回。

分析:

1.根据格式编写方法-->因n不固定,因此需要声明形参接收,且需要返回结果,还需要声明返回值类型。

2.方法内部使用for循环计算出1-n的和并返回。

示例代码如下:

publicstaticvoidmain(String[] args) {
System.out.println("1-100的和是"+add(100)); // 5050    }
publicstaticintadd(intn) {
intnumber=0;
for (inti=1; i<=n; i++) {
number+=i;
        }
returnnumber;
    }

4.2判断整数是奇数还是偶数

需求:拿一个整数,然后调用方法,把整数交给方法,在方法中输出该数为奇数还是偶数

分析:

1.根据格式编写方法--> 因要传入数据给方法,方法需要声明形参接收

2.方法内部使用if语句判断,并输出对应的结论。

示例代码如下:

publicstaticvoidmain(String[] args) {
intdata=99;
intdata2=100;
check(data);
System.out.println("----------");
check(data2);
    }
publicstaticvoidcheck(inta) {
if (a%2==0) {
System.out.println(a+"为偶数");
        } else {
System.out.println(a+"为奇数");
        }
    }

4.3数组求最值案例改方法形式

需求:把找出数组的最大值案例,改造成方法,可以支持返回任意整型数组

的最大值数据。

分析:

1.根据格式编写方法

要返回最大值,需要声明返回值类型。

需要接收数组需要声明形参列表。

2.方法内部找出数组的最大值并返回。

示例代码如下:

publicstaticvoidmain(String[] args) {
int[] ages= {12, 20, 33, 18, 15};
intmax=gerArrayMax(ages);
System.out.println("数组中的最大值为"+max);
    }
publicstaticintgerArrayMax(int[] arr) { // 形参传入的是堆内存中new出来的数组对象的地址// 找出数组中的最大值,并返回intmax=arr[0];
for (inti=1; i<arr.length; i++) { // 遍历数组中的每个索引的元素值// 若某个索引的元素值大于当前最大值,则将该元素值设为最大值if (arr[i] >max) {
max=arr[i];
            }
        }
returnmax;
    }

5.方法调用的内存图

方法调用流程-内存图解

方法没有被调用的时候,在方法区中的字节码文件中存放

方法被调用的时候,需要进入到栈内存中运行。

具体执行流程示例如下图所示:

MethodRAM.png

上图中程序的一般执行步骤为:

Step1:在方法区加载.class文件,里面包含程序中的四个方法main(),study(),sleep(),和eat()。

Step2:main()方法是程序运行的入口。首先会把main()方法添加到栈内存中,执行main()方法。

Step3:在main()方法执行过程中,调用study()方法,将study()方法添加到栈内存中,执行study()方法。

Step4:在study()方法执行过程中,调用eat()方法,将eat()方法添加到栈内存中,执行eat()方法,打印出“吃饭”,eat()方法执行完毕,执行完毕后将eat()方法从栈内存中移除。

Step5:调用完毕eat()方法后,study()方法继续向下执行,打印出“学习”

Step6:打印完毕后,再继续向下执行,调用sleep()方法,将sleep()方法添加到栈内存中,执行sleep()方法,打印出“睡觉”,sleep()方法执行完毕,执行完毕后将sleep()方法从栈内存中移除。

Step7:调用完毕sleep()方法后,study()方法执行完毕,study()方法从栈内存中移除

Step8:调用完毕study()方法后,main()方法执行完毕,main()方法从栈内存中移除,程序结束。

6.方法的参数传递机制

6.1基本类型的参数传递

Java的参数传递机制:值传递

在传输实参给方法的形参的时候,并不是传输实参变量本身,而是传输实参变量中存储的值方法内部中对于形参的任何改变不影响原实参,因为只传输的值,而不是传输的实参变量,这就是值传递。

实参:如在方法内部定义的变量。

形参:如在定义方法时,“()”中所声明的参数。

示例代码如下:

 

publicstaticvoidmain(String[] args) {
inta=10; // 实参a,与方法中传入的形参a仅仅是名字一样,没有任何关系change(a);
System.out.println(a); // 10,在进行参数传递时,仅仅将实参a的值10传入change()方法中,对于实参a没有任何改变,其自身值仍为10    }
publicstaticvoidchange(inta) { // 形参aSystem.out.println(a); // 10a=20;
System.out.println(a); // 20    }

6.2引用类型的参数传递

引用类型的参数传递与基本类型的参数传递原理相同,都是把存放在实参内的具体值赋给形参,然而二者的不同点是,引用类型的实参内的具体值,存放的是引用对象的地址,因此在进行引用类型的参数传递时,也是将具体值(地址)传给形参后续方法内是对形参中存放的引用对象的地址进行访问或操作的。

示例代码如下:

publicstaticvoidmain(String[] args) {
int[] arr= {10, 20, 30};
change(arr);
System.out.println(arr[1]); // 100 获取打印堆内存中new出来的这个数组对象第2个索引位置的值,在change()方法中已经被改变    }
privatestaticvoidchange(int[] arr) { // 将实参arr中存放的new出来的数组的地址的具体值传给形参arr,后续通过该地址访问System.out.println(arr[1]); // 20arr[1] =100;
System.out.println(arr[1]); // 100 通过传递的地址值,改变了堆内存中new出来的这个数组对象第2个索引位置的值    }

基本类型与引用类型的参数传递的区别?

二者进行参数传递时都是通过值传递的方法,区别就是基本类型的参数传递,传的是参数的具体值,引用类型的参数传递,传递的也是具体值,只不过这个值是一个地址,再通过这个地址访问数据。

就像文件的分享一样,基本类型的参数传递是把我的文件复制、粘贴,通过拷贝的方式给你一份,我给你的是文件,无论你怎么改你自己这份文件,都和我没关系,影响不到我。而引用类型的参数传递,就像我把这份文件上传共享文档,我给你的是这份文档的网址,你通过打开网址的方式,来读取或者编辑这份文件,如果对文件有了改动,那我打开这个网址的时候就文件也会相应变化,变的是网址中文件的内容,但是打开该文件的网址没有任何变化。

7.方法的参数传递案例

7.1打印数组内容

需求:

设计一个方法用于输出任意整型数组的内容,要求输出成如下格式:

“该数组内容为:[11, 22, 33, 44, 55]”

分析:

1、定义一个方法,要求该方法能够接收数组,并输出数组内容。-->需要参数需要声明返回值类型

2、定义一个静态初始化的数组,调用该方法,并传入该数组。

示例代码如下:

publicstaticvoidmain(String[] args) {
int[] array= {10, 25, 33, 14, 88};
printArray(array); // 调用printArray方法,打印整型数组内容 该数组内容为:[10,25,33,14,88]int[] array2=null; // 该数组内容为:[]printArray(array2);
int[] array3= {};
printArray(array3); // 该数组内容为:[]    }
// 打印整型数组内容的方法publicstaticvoidprintArray(int[] arr) {
System.out.print("该数组内容为:[");
// 遍历并打印出数组中每一个元素值//        for (int i = 0; i < arr.length; i++) {//            if (i != arr.length - 1) {//                System.out.print(arr[i] + ",");//            } else {//                System.out.print(arr[i]);//            }//        }if (arr!=null&&arr.length>0) { // 判断数组不为空或长度大于0时,打印数组内容,否则跳过// 遍历并打印出数组中每一个元素值(优化写法)for (inti=0; i<arr.length; i++) {
System.out.print(i==arr.length-1?arr[i] : arr[i] +",");
            }
        }
System.out.println("]");
    }

7.2从数组中查询元素的索引返回

需求:设计一个方法可以接收整型数组,和要查询的元素值;最终要返回元素在该数组中的索引,如果数组中不存在该元素则返回-1。

分析:

1、定义方法,接收整型数组,查询的元素值,在方法体中完成元素查询的功能。--->需要参数、返回值

2、定义数组,调用该方法,并指定要搜索的元素值,得到返回的结果输出。

示例代码如下:

publicstaticvoidmain(String[] args) {
intdata=25;
int[] ages= {25, 20, 22, 12, 28};
intdataIndex=getDataIndex(data, ages); // 调用查找数组中数据索引位置的方法,获取返回值if (dataIndex!=-1) {
System.out.println(data+"在数组中的索引为:"+dataIndex);
        } else {
System.out.println(dataIndex);
        }
    }
/*** create by: 全聚德在逃烤鸭、* description: 定义一个方法,从数组中查询元素的索引返回,若不存在,返回-1。参数:数组、要查询的数据    返回值:整型* create time: 2022/3/29 0029 9:56** @param data* @param arr* @return int*/publicstaticintgetDataIndex(intdata, int[] arr) {
for (inti=0; i<arr.length; i++) {
if (data==arr[i]) {
returni;
//                break; // return返回调用该方法的语句,该方法直接结束,循环也就相应结束,不用再添加beak;            }
        }
return-1; // 如果循环遍历后,没有符合条件的索引,则返回-1    }

7.3比较两个数组内容是否一样

需求:如果两个数组的类型,元素个数,元素顺序和内容是一样的我们就认为这2个数组是一模一样的。

请使用方法完成:能够判断任意两个整型数组是否一样,并返回true或者false。

分析:

1、定义方法,接收2个整型数组,-->需要参数、返回值

2、在方法内部完成判断的逻辑,并返回布尔结果。

示例代码如下:

publicstaticvoidmain(String[] args) {
int[] ages1= {10, 20, 320, 40};
int[] ages2= {10, 20, 30, 40};
booleanisSame=checkArraySame(ages1, ages2);
if (isSame) {
System.out.println("两个数组内容一样");
        } else {
System.out.println("两个数组内容不一样");
        }
    }
/*** create by: 全聚德在逃烤鸭、* description: 定义一个方法,比较两个整型数组内容是否一样,一样返回true,否则返回false    参数:两个整型类型   返回值:布尔型* create time: 2022/3/29 0029 10:15** @param arr1* @param arr2* @return boolean*/publicstaticbooleancheckArraySame(int[] arr1, int[] arr2) {
// 判断两个数组长度是否一致,若不一致则返回falseif (arr1.length!=arr2.length) {
returnfalse;
        }
// 判断两个数组中各个元素值大小及顺序是否一致,若不一致则返回falsefor (inti=0; i<arr1.length; i++) {
if (arr1[i] !=arr2[i]) {
returnfalse;
            }
        }
returntrue; // 两个数组长度、各个元素值大小及顺序均一致,返回true    }

8.方法重载

8.1方法重载的形式、作用

方法重载的定义

同一个类中,出现多个方法名称相同,但是形参列表是不同的方法,那么这些方法就是重载方法

调用方法的时候,会通过参数的不同来区分调用的是哪个方法

示例代码如下:

publicstaticvoidmain(String[] args) {
fire(); // 默认向x地发射1枚武器fire("A地"); // 默认向A地发射1枚武器fire("A地", 100); // 默认向A地发射100枚武器    }
publicstaticvoidfire() {
System.out.println("默认向x地发射1枚武器");
    }
publicstaticvoidfire(Stringlocation) {
System.out.println("默认向"+location+"发射1枚武器");
    }
publicstaticvoidfire(Stringlocation, intnumbers) {
System.out.println("默认向"+location+"发射"+numbers+"枚武器");
    }

方法重载的作用

可读性好,方法名称相同提示是同一类型的功能,通过形参不同实现功能差异化的选择,这是一种专业的代码设计。

重载的方法还可以调用其他的方法,来减少代码的开发工作量,使代码更加简洁。

如在上例中可以在调用fire()方法时,在方法内部调用fire(String location)方法,在调用fire(String location)方法时,在方法内部调用fire(String location, int numbers)方法

示例代码如下:

publicstaticvoidmain(String[] args) {
fire(); // 默认向x地发射1枚武器fire("A地"); // 默认向A地发射1枚武器fire("A地", 100); // 默认向A地发射100枚武器    }
publicstaticvoidfire() {
fire("x地"); // 调用fire(String location)方法    }
publicstaticvoidfire(Stringlocation) {
fire(location, 1); // 调用fire(String location, int numbers)方法    }
publicstaticvoidfire(Stringlocation, intnumbers) {
System.out.println("默认向"+location+"发射"+numbers+"枚武器");
    }

8.2方法重载的识别技巧

1.只要是同一个类中,方法名称相同、形参列表不同,那么他们就是重载的方法,其他都不管

修饰符,返回值类型都无所谓

2.形参列表不同指的是:形参的个数、类型、顺序不同,不关心形参的名称

示例代码如下:

 

// 新方法publicstaticvoidopen() {
    }
// 重载方法publicstaticvoidopen(inta) { // 形参的个数不同    }
// 重载方法publicstaticvoidopen(inta, intb) { // 形参的个数不同    }
// 重载方法publicstaticvoidopen(doublea, intb) { // 形参的类型不同    }
// 重载方法publicstaticvoidopen(inta, doubleb) { // 形参的顺序不同    }
// 重复方法//    public static void open(int i, double d) { // 形参的个数、类型、顺序均相同,形参的名称无所谓////    }// 新方法publicstaticvoidOPEN() { // 方法名称不同    }

9.补充知识:单独使用return关键字

return;-->可以立即跳出并结束当前方法的执行;

return关键字单独使用可以放在任何方法中。

return只会结束当前所在方法,不会结束上级调用方法

示例代码如下:

 

publicstaticvoidmain(String[] args) {
System.out.println("main()方法开始");
division(10, 0);
System.out.println("main()方法结束"); // return只会结束当前所在方法,不会结束上级调用方法    }
publicstaticvoiddivision(inta, intb) {
if (b==0) {
System.out.println("输入数据有误,除数不能为0!");
return; // 立即跳出并结束当前方法的执行,返回上级调用该方法的语句        }
intc=a/b;
System.out.println("结果是"+c);
    }

易混淆知识点—return、break、continue的执行特点:

return;跳出并立即结束所在方法的执行。

break;跳出并结束当前所在循环的执行。

continue;结束当前所在循环的当次继续,进入下一次执行。

相关文章
|
15天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
55 4
|
26天前
|
Java API
Java 对象释放与 finalize 方法
关于 Java 对象释放的疑惑解答,以及 finalize 方法的相关知识。
45 17
|
19天前
|
Java 测试技术 Maven
Java一分钟之-PowerMock:静态方法与私有方法测试
通过本文的详细介绍,您可以使用PowerMock轻松地测试Java代码中的静态方法和私有方法。PowerMock通过扩展Mockito,提供了强大的功能,帮助开发者在复杂的测试场景中保持高效和准确的单元测试。希望本文对您的Java单元测试有所帮助。
44 2
|
27天前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
19 3
|
27天前
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
17 2
|
27天前
|
安全 Java
Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧
【10月更文挑战第20天】Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧,包括避免在循环外调用wait()、优先使用notifyAll()、确保线程安全及处理InterruptedException等,帮助读者更好地掌握这些方法的应用。
17 1
|
27天前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
33 1
|
27天前
|
Java
在Java多线程编程中,`wait()`和`notify()`方法的相遇如同一场奇妙的邂逅
在Java多线程编程中,`wait()`和`notify()`方法的相遇如同一场奇妙的邂逅。它们用于线程间通信,使线程能够协作完成任务。通过这些方法,生产者和消费者线程可以高效地管理共享资源,确保程序的有序运行。正确使用这些方法需要遵循同步规则,避免虚假唤醒等问题。示例代码展示了如何在生产者-消费者模型中使用`wait()`和`notify()`。
25 1
|
27天前
|
安全 Java 开发者
Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用
本文深入解析了Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用。通过示例代码展示了如何正确使用这些方法,并分享了最佳实践,帮助开发者避免常见陷阱,提高多线程程序的稳定性和效率。
34 1
|
21天前
|
Java Spring
JAVA获取重定向地址URL的两种方法
【10月更文挑战第17天】本文介绍了两种在Java中获取HTTP响应头中的Location字段的方法:一种是使用HttpURLConnection,另一种是使用Spring的RestTemplate。通过设置连接超时和禁用自动重定向,确保请求按预期执行。此外,还提供了一个自定义的`NoRedirectSimpleClientHttpRequestFactory`类,用于禁用RestTemplate的自动重定向功能。
下一篇
无影云桌面