一、方法
一、定义:
1.(多使用,不要代码都在main方法中写,方便别人使用。因为方法是一个独立的功能,可以重复使用。)
2、方法是一段可以完成某个特定功能的并且可以被重复利用 的代码片段。
二、格式:
【修饰符列表】 返回值类型 方法名 (形式参数){
方法体
}
三、分开解释:
3.1、修饰符列表:
此项是可选项,不是必须的,目前统一写成 public static。
3.2、返回值类型
1、定义:非常重要,在你写方法之前你就要只要此方法应该完成什么功能,返回什么类型的数据。
此项可以是 java 语言当中任何一种数据类型,包括基本数据类型,也包 括所有的引用数据类型,当然,如果一个方法执行结束之后不准备返回任何数据,则返回值类 型必须写 void。返回值类型例如:byte,short,int,long,float,double,boolean,char,String,void 等。
2、当有返回值的时候,即返回值类型不是void时必须写return语句。当返回值类型为void时也可以使用return语句。
3、也就是说当一个方法的返回值类型是 void 的时候,方 法体当中允许出现“return;”语句(注意:不允许出现“return 值;”),这个语法的作用主要 是用来终止方法的执行。
例子:public static void method2(){ return; }对的。 public static void method2(){ return 10; }错的。
3.3、方法名
1、定义:
此项需要是合法的标识符,开发规范中要求方法名首字母小写,后面每个单 词首字母大写,遵循驼峰命名方式,见名知意,例如:login、getUsername、findAllUser 等。
3.4、形式参数
1、定义:(数据类型 变量名,数据类型 变量名。。。。。。)
此项又被称为形参,其实每一个形参都是“局部变量”, 形参的个数为 0~N 个,如果是多个参数,则采用半角“,”进行分隔,形参中起决定性作用的 是参数的数据类型,参数名就是变量名,变量名是可以修改的,也就是说(int a , int b)也可以写 成(int x , int y)。
2、
3.5、方法体
1、定义:
由一对儿大括号括起来,在形参的后面,这个大括号当中的是实现功能的核 心代码,方法体由 java 语句构成,方法体当中的代码只能遵循自上而下的顺序依次逐行执行, 不能跳行执行。
3.6、方法的调用
1、前提是方法的修饰符列表中带有 static 关键字): “类名.方法名(实际参数列表)。当方法写在当前类体中的时候可以不加类名,但是方法写在其他类体中的时候就要使用 类名.方法名()调用。
2、调用的格式:类名.方法名(实际参数)
3、实际参数与形式参数的数据类型要一样,数量要一样。
例子:
long x;
//long a=1L;
// long b=2L;
x=sum(10,20);
System.out.println(x);
}
public static int sum(int x, int y) {
if (x > y) {
return x;
}else return 0;
//此程序可以运行,但是会有精度的损失,从int类型到long类型。
2、 public static void main(String[] args) {
sum(true,10);
}
public static void sum(int x, int y) {
if (x > y) {
System.out.println("0");
}else
System.out.println("1");
}//此程序就会显示形参和实参的类型不同的错误。
深入return语句
1、同一作用域下,return语句下面不能编写任何代码:
例子:
public static int sum(int x,int y){
if(x>y){
return x;
}//错误错误原因是因为无法确定这个return是不是一定运行,所以是缺少返回语句。
public static int sum(int x,int y){
if(x>y){
return x;
}else {
return y;
}//对的
在返回类型为void的方法中使用return语句。主要是为了用来结束当前方法。break只能终止某个循环。
1、方法执行结束之后的返回值我们可以接收,也可以不接收,不 是必须的,但大多数情况下方法的返回值还是需要接收的,要不然就没有意义了,另外方法的 返回值在接收的时候采用变量的方式接收,要求这个变量的数据类型和返回值类型一致(当然, 也可以遵守自动类型转换规则)。
例子:
public static void main(String[] args) {
//可以编译也可以正常运行
sumInt(10 , 20);
int retValue = sumInt(100 , 200);
System.out.println("计算结果 = " + retValue);
//编译报错,返回值类型是 int,不能采用 byte 接收
//byte retValue2 = sumInt(1 , 2);
}
public static int sumInt(int a , int b){
return a + b;
}
四、数据结构
1、JVM的内存区:
栈区,方法区,堆区。
2、栈的介绍
栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是:仅允许在表的一端进行插 入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作 进栈、入栈或压栈(push),它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从 一个栈删除元素又称作出栈、退栈或弹栈(pop),它是把栈顶元素删除掉,使其相邻的元素 成为新的栈顶元素。
特性:先入后出。
3、方法的执行与调用
1、类加载器把.class文件加载到方法区(可以重复的代码块)
2、程序开始执行,方法进入栈区。
具体的程序实例:
public class MethodTest {
public static void main(String[] args) {
System.out.println("main begin");
m1();
System.out.println("main over");
}
public static void m1() {
System.out.println("m1 begin");
m2();
System.out.println("m1 over");
}
public static void m2() {
System.out.println("m2 begin");
System.out.println("m2 over");
}
}
运行结果:
文字描述:
① 类加载器将 class 文件加载到方法区。
② 开始调用 main方法,在栈内存中给 main方法分配空间,开始执行 main方法,输出”main begin”。
③ 调用 m1()方法,在栈内存中给 m1()方法分配空间,m1()方法处于栈顶,具备活跃权, 输出”m1 begin”。
④ 调用 m2()方法,在栈内存中给 m2()方法分配空间,m2()方法处于栈顶,具备活跃权, 输出”m2 begin”,继续输出”m2 over”。
⑤ m2()方法执行结束,内存释放,弹栈。
⑥ m1()方法这时处于栈顶,具备活跃权,输出”m1 over”。
⑦ m1()方法执行结束,内存释放,弹栈。
⑧ main()方法这时处于栈顶,具备活跃权,输出”main over”。
⑨ main()方法执行结束,内存释放,弹栈。
⑩ 栈空了,程序结束。
4、栈内存主要存储局部变量。
二、方法重载(OverLoad)
4.1、定义:
1.方法重载(overload)是指在一个类中定义多个同名的方法, 但要求每个方法具有不同的参数的类型或参数的个数。
2.方法重载通常用于创建完成一组任务相 似但参数的类型或参数的个数不同的方法。
3.调用方法时通过传递给它们的不同个数和类型的实 参来决定具体使用哪个方法。
4.2、什么时候考虑方法重载
在同一个类当中,如果多个功能是相似的,可以考 虑将它们的方法名定义的一致,使用方法重载机制,这样便于程序员的调用,以及代码美观, 但相反,如果两个方法所完成的功能完全不同,那么方法名也一定要不一样,这样才是合理的。
4.3、什么条件满足之后构成方法重载
1.在同一个类当中。
2.方法名相同。
3.参数列表不同:
个数不同算不同。
顺序不同算不同。
类型不同也算不同。
例子:
public class DemoOverLoad {
public static void main(String[] args) {
m1(1,2.0);
m1(1.0,2);
m1(1);
m1(1.0F,2.0);
}
//顺序不同
public static void m1(int a,double b){
System.out.println("1");
}
public static void m1(double a,int b){
System.out.println("2");
}
//数量不同
public static void m1(int a){
System.out.println("3");
}
//类型不同
public static void m1(float a,double b){
System.out.println("4");
}
// void m1(int a,double b){
// System.out.println("1");
// }
}
4.4、方法重载和什么有关系,和什么没有关系
1.方法重载之和方法名以及参数的类型有关系。
2.和有无修饰符列表无关系。
错误的例子:
void m1(int a,double b){
System.out.println("1");
}
public static void m1(int a,double b){
System.out.println("2");
}
3.方法重载和返回值类型无关
public static int m1(int a,double b){
System.out.println("1");
}
public static void m1(int a,double b){
System.out.println("2");
}//错误的写法
4.5、方法重载的实际应用
可以自己写一个模块,然后在其它的类中加载这个模块,代码简洁方便。
public static void main(String[] args) {
A.m1(1);
A.m1(2.0F);
A.m1(2.0);
A.m1(2L);
A.m1("陈绪杰");
}
}
class A{
public static void m1(int data){
System.out.println(data);
}
public static void m1(double data){
System.out.println(data);
}
public static void m1(float data){
System.out.println(data);
}
public static void m1(byte data){
System.out.println(data);
}
public static void m1(long data){
System.out.println(data);
}
public static void m1(String data){
System.out.println(data);
}
三、递归
1.定义:
1.方法自己调用自己,就是递归。
2.栈内存使用比较多,能不要用就不用。
3.使用递归须谨慎,因为递归在使用的时 候必须有结束条件,没有结束条件就会导致无终止的压栈,栈内存最终必然会溢出,程序因错 误的发生而终止。
4.一个递归程序有的时候存在合法有效的终止条件,但由于递归的太深,在还没有等到条件 成立的时候,栈内存已经发生了溢出,这种情况也是存在的,所以实际开发中我们尽可能使用 循环来代替递归算法。
5.能不用递归尽量不用,能用循环代替的尽可能使用循环。
6.递归的例子,在面试的过程中也经常使用:
//递归算法
public class DemoDigui {
public static void main(String[] args) {
int n=4;
int retvalue=sum1(n);
System.out.println(retvalue);
}
//利用递归计算1~N的累加和
public static int sum(int a){
if (a==1){
return a;
}
a=a+sum(a-1);
return a;
}
//利用递归计算N的阶乘,面试题经常考
public static int sum1(int n){
int a;
if (n==1)
return 1;
return n*sum1(n-1);
}
}
四、总结
- 方法体当中的代码必须遵循自上而下的顺序依次逐行执行,当前行代码不结束,下一行代码 是绝对不会执行的。
- 一定要理解栈数据结构的原理是遵循先进后出、后进先出 原则,每当方法调用时分配空间,此时“进”栈,每当方法执行结束时释放空间,此时“出” 栈。
- 永远都是最后执行的方法最先结束,最先执行的方法最后结束。