方法的使用与内存操作

左心房为你撑大大i 提交于 2019-12-04 21:55:12

1、方法的使用演示

        对执行流程分割抽取归类,相似相近的归类在一起


只将功能实现在main方法中完成出现的问题:

1、层次结构不鲜明 ---- 虽然可以通过注解进行说明

2、代码的复用性不好 ---- 冗余臃肿

方法格式:

public static void main(String[] args){

code;

}

public ---- 权限修饰符

static ---- 静态修饰符

void   ---- 空 ---------- 需要学习

main   ---- 方法名 ------ 可自定义

(String[] args) 参数 ---- 

{

方法实现

} ----- 方法体

要求:

main方法中不要再添加具体的功能实现,而是直接调用方法

方法的优点:

1、代码结构更清晰明了 ---- 易于代码维护

2、不想让哪个方法运行时不用注释掉整个代码,只需注释掉main方法中的那个方法名即可

3、实现了代码复用

程序中有些是不变的,变的部分应该提供数据输入入口,然后根据输入的数据进行执行

方法:

数据输入 ----> 数据处理 ----> 数据输出

参数          方法体           目前 控制台打印

  现在 返回给调用者 ---- 由调用者处理 

1、是处理数据的 ---- 行为

2、方法内的实现是一些不变的,那么不变的数据通过参数暴漏给调用者

3、数据输出 ----- 返回值类型和return关键字结合


需求:使用方法实现计算两个数的和

方法的继续优化:方法处理完的数据返回给调用者,而不是打印在控制台

class MethodDemo00
{
	//演示算术运算符
	public static void myFirstMethod(){
		int num1 = 10;
		int num2 = 4;
		//-----------------------------------
		int result1 = num1 + num2;
		System.out.println(result1);
		int result2 = num1 - num2;
		System.out.println(result2);
		int result3 = num1 * num2;
		System.out.println(result3);
		int result4 = num1 / num2;//只是取商,即2
		System.out.println(result4);

		int result5 = num1 % num2;//只是取余,即余数2
		System.out.println(result5);
	}
	public static void mySecondrMethod(){
		int num1 = 10;
		int num2 = 4;
		double result6 = (double)(num1 / num2);//结果是2.0 实际它只是将num1/num2的商2强转成浮点型2.0
		System.out.println(result6);
		double result7 = (double)num1 / num2;//正确,即将num1转成double型的再与int型的num2相除结果默认double型的
		System.out.println(result7);
	}
	public static void printStar(){
		for(int i = 0; i < 4; i++){
			for(int j = 0; j < 5; j++){
				System.out.print("*");
			}
			System.out.println();
		}
	}
	public static void printStar2(int rows, int clos){
		for(int i = 0; i < rows; i++){
			for(int j = 0; j < clos; j++){
				System.out.print("*");
			}
			System.out.println();
		}
	}
	//接收num1和num2两个值,计算和,输出在控制台
	public static void sum(int num1,int num2){
		int result = num1 + num2;
		System.out.println(result);
	}
	//接收num1和num2两个值,计算和,返回给控制者
	public static int sum2(int num1,int num2){
		int result = num1 + num2;
		return result;
	}
	public static void main(String[] args){
			//myFirstMethod();
			mySecondrMethod();
			printStar();
			System.out.println("---------------------------");
			printStar();
			System.out.println("----------------------------");
			printStar2(10,10);
			System.out.println("----------------------------");
			printStar2(5,15);
			sum(1,2);// 3
			int sum = sum2(2,3);// 不会在控制台被打印
			System.out.println(sum);// 5
	}
}

2、方法的练习(逐步改进)

数据输入 ---- 参数的方式体现

参数的格式:

1、参数在方法的()中

2、可以没有参数 ---- 无参方法

3、参数可以有多个

4、变量类型1 变量名1,变量类型2 变量名2,


数据处理

具体的功能实现


数据输出 ----- 返回值的方式体现 ---- 返回值类型

返回值的使用:

1、方法上声明 ---- 声明的是返回的数据的数据类型

2、方法可以没有返回值 ---- 返回值类型是 void ---- (特殊的返回)

3、方法上的返回值类型结合return使用 ----

return的数据的数据类型必须和声明类型一致

4、调用时

返回值的数据类型  变量名 = 方法名(对应的参数);如(int result = sum2)



需求:计算两个数的和


如何编写方法,从两方面入手:

1、变化的数据是什么

2、需要返回数据吗?如果需要,返回什么?

class MethodDemo01
{
	/*
		改进:1、将数据暴漏,需要参与运算的数据应该有调用者提供
			  2、产生的结果返回给调用者
	*/
	
	public static void sum(){
		int num1 = 1;
		int num2 = 2;
		System.out.println(num1 + " + " + num2 + " = " + (num1 + num2));
	}
	public static int sum2(int num1,int num2){
		int result = num1 + num2;
		return result;
	}
	//在控制台上输出 hello world ! ---- 无参  无返回
	public static void printHelloWrold(){
		System.out.println("Hello Wrold");
	}
	//将两个数的和输出到控制台 ---- 参数  两个数  无返回
	public static void printSum(int num1, int num2){
		System.out.println(num1 + num2);
	}
	//判断两个数是不是一样大 ---- 参数  两个数  返回 boolean
	public static boolean compare(int num1, int num2){
		boolean flag = num1 ==num2;
		return flag;
	}
	public static void main(String[] args){
		sum();//1 + 2= 3
		int result = sum2(1,2);
		System.out.println("result = " + result);//result = 3
		printHelloWrold();// Hello World
		printSum(3,4);// 7
		boolean flag = compare(5,6);
		System.out.println("num1 = num2 " + flag);// 5 = 6 false
	}
}

3、return关键字的使用

1、当方法声明了返回值类型,必须使用return

2、return的数据的数据类型和声明的一致

 (特殊情况:返回的数据的数据类型可以转型为声明数据类型)

3、void方法,隐式的包含一个return

4、return可以作为跳出方法的关键字使用

5、return类似于break,continue不可以后跟逻辑上可以执行到的代码


注意:如果方法有返回值可以直接调用方法,不使用变量接收返回值

class MethodDemo02
{
	public static int returnTest(){
		//return 1;正确
		//return 1.0;//错误  return的类型与声明的类型不一致
		byte b = 10;
		return b;//自动转型
	}
	public static void returnTest2(){
		int num = 1;

		return;
	}
	public static void returnTest3(int num){
		//如果num != 10; 打印num,如果等于10,方法直接退出
		if(num != 10){
			System.out.println(num);
		}else{
			//System.exit(0);//方法A、结束虚拟机 ---- 不建议此方法
			return;//方法B、结束当前方法
		}
		System.out.println("Over!");//num=10时,无论方法A或B都执行不到此语句了
	}
	public static void returnTest4(){
		int num = 1;
		return;
		//System.out.println("returnTest04 Over");//错误:无法访问的语句(return即整个方法已结束,后面的语句逻辑上无法执行)
	}
	public static void main(String[] args){
		returnTest();//只是让方法执行一遍,返回的数据不接收
		returnTest3(10);
		returnTest4();
	}
}

4、方法运行的内存操作与特点

1、在内存产生一块运行时数据区 ---- (栈,堆,方法区),将class文件读取进内存

2、运行main方法时 ---->在栈中为main方法开辟一块空间(main方法的栈桢)

3、main方法执行,输出打印 ---->调用test方法

4、为test在栈中开辟栈桢 ---->

5、初始化数据,打印 -------->执行方法体

6、释放test的栈桢,test执行完

7、main方法继续执行,输出打印

8、main方法执行完,释放main方法栈桢,释放程序的内存

class MethodDemo03
{
	public static void Test(){
		int num = 10;
		System.out.println("num = " + num);
	}
	public static void main(String[] args){
		Test();
	}
}

分析内存:

栈的特点:

1、按照执行顺序,依次压入相应的栈桢

2先执行完的(后压入的),先释放


类似于弹夹 ---->先入后出


对应的结构:

队列 ---------->先进先出


注意:方法的顺序和编写顺序无关

为什么?

因为运行时,class文件已经加载完成 ---- 方法的所有信息在class文件区已经存储了

那么调用时,只要能够查找到即可 ----> 和编写顺序无关

class MethodDemo04
{
	public static void method1(){
		System.out.println("m1 start");
		method2();
		System.out.println("m1 end");
	}
	public static void method2(){
		System.out.println("m2 start");
		System.out.println("m2 end");
	}
	public static void main(String[] args){
		System.out.println("main start");
		method1();
		System.out.println("main end");
	}
}

当变量作为参数传递给另一个方法时,

另一个方法会为它开辟新的空间,与原变量无关

两个变量分别属于不同的栈桢

class MethodDemo05
{
	public static void test(int num1){
		num1++;
		System.out.println("test num1 = " + num1);//test num1 = 11
	}
	public static void main(String[] args){
		int num1 = 10;
		test(num1);
		System.out.println("main num1 = " + num1);//main num1 = 10
	}
}

5、方法间功能的复用

场景:有两个方法

 其中一个方法实现细节,包含了另一个方法B的所有实现细节

解决方案1:

B方法实现所有细节

A方法实现所有细节

解决方案2:

A方法调用B方法

A方法再完成特有的功能

class MethodDemo06
{
	//求两个数的和
	public static int sum1(int num1,int num2){
		num1 += 10;
		num2 += 5;
		int sum = num1 + num2;
		return sum;
	}
	//求三个数的和
	public static int sum2(int num1,int num2,int num3){
		/*num1 += 10;
		num2 += 5;
		int sum = num1 + num2 */
		int sum = sum1 (num1,num2);
		sum += num3;
		return sum;
	}
	public static int getMax1(int num1,int num2){
		int max = num1 > num2 ? num1 : num2;
		return max;
	}
	public static int getMax2(int num1,int num2,int num3){
		//int max = num1 > num2 ? num1 : num2;
		int max = getMax1(num1,num2);
		max = max > num3 ? max : num3;
		return max;
	}
	public static void main(String[] args){
		
	}
}

6、方法调用与区分

方法调用:判断哪一个方法:参考方法名和参数类型

当方法名和参数列表组成的方法标志独一无二时,即认为是合法的

方法的重载:

方法名一致,参数列表不同,就是方法的重载


注意:

当传入的数据类型 <= 参数类型时,会自动进行数据提升

方法调用:1、首先进行严格类型匹配,如果没有,那么会进行数据提升的匹配

 2、提升数据类型匹配时,运行数据类型最接近的方法


如何进行方法区分:

1、通过方法名,方法名不同,方法不同

2、通过参数,方法名相同,参数列表不同也视为不同方法

A、参数个数不同

B、数据类型不同

注意:和参数无关

重载:

1、可以识别不同的方法

2、方法名相同,参数列表不同

注意:和权限修饰符、静态修饰符、返回值类型无关

class MethodDemo07
{
	public static int getMax(int num4,int num5){
		int max = num4 > num5 ? num4 : num5;
		return max;
	}
	public static int getMax(int num1,int num2,int num3){
		//int max = num1 > num2 ? num1 : num2;
		int max = getMax(num1,num2);
		max = max > num3 ? max : num3;
		return max;
	}
	public static void main(String[] args){
		byte b = 10;
		int max1 = getMax(1,b);//合法,当传入的数据类型 <= 参数类型时,会自动进行数据提升
		System.out.println("max1 = " + max1);
		int max2 = getMax(1,2,3);
		System.out.println("max2 = " + max2);
	}
}



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!