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);
}
}
来源:oschina
链接:https://my.oschina.net/u/2653543/blog/668591