JavaSE学习笔记——Java中的方法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaSE学习笔记——Java中的方法相关的知识,希望对你有一定的参考价值。
一、 Java中的方法
需求:求整数10和整数3的乘积,然后在求整数2000和整数300的乘积。
public class MethodTest01 {
public static void main(String[] args){
int i = 10; int j = 3; int k = i * j; System.out.println("i * j = " + k);
int l = 2000; int m = 300; int n = l * m; System.out.println("l * m =" + n); } } |
功能已经实现,但是存在的问题是,两段代码完成的功能相同,数据的类型也相同。只是具体的数据不同。并且代码重复使用了两次,虽然实现了功能,但缺点是相同功能的代码不能实现重用。所以在Java中可以使用方法来实现相同功能的代码块重复利用。
1.1 方法的定义
方法就是一段代码片段,可以完成特定的功能,并且可以重复利用。定义方法的语法格式如下。
[方法修饰列表] 返回值类型 方法名(方法形式参数列表){ 方法体; } |
方法修饰符:可以是public、protected、private、abstract、static、final和synchronized。注意:其中public、protected和private不能同时存在,只能是其中之一。
方法的返回值类型:可以是Java语言中的任何一种数据类型(基本数据类型和引用数据类型)。如果该方法执行结束之后,没有任何返回值,那么定义方法的时返回值类型为void。如果存在返回值,使用 return语句。Return语句后面不能再执行语句,因为不可能会执行到,编译不能通过。
方法名:合法的标识符。
方法参数列表:定义方法时可以有参数,也可以没有参数,如果有多个参数,参数之间要使用逗号进行分隔。
定义一个方法实现上面的需求。
public class MethodTest02 {
public static void main(String[] args){ // 调用static修饰的静态方法需要使用类名.的方式 // 直接调用方法并传入需要乘积的参数 MethodTest02.method(10, 3); MethodTest02.method(2000, 300); } // static修饰的方法是静态方法 public static void method(int i,int j){ int product = i * j; System.out.println("i * j = " + product); } } |
定义方法。
public class MethodTest03 {
public static void main(String[] args){ // 调用方法,静态方法直接使用类名.的方式进行调用 MethodTest03.method01(); // 调用方法时同时传递参数给方法 MethodTest03.method02("张三"); // 调用有返回值的方法 int product = MethodTest03.method03(20, 30); System.out.println("product = " + product); } // 定义方法 // public 公共的,外面的类可以调用 // static 方法是静态的 // void 没有返回值 // method01 方法名 // 方法没有参数 public static void method01(){ System.out.println("Hello Java"); } // 方法带有一个String类型的参数 // 参数name是局部变量,作用域在方法体内 public static void method02(String name){ System.out.println(name); } // 方法有两个int类型的参数 // 方法有返回值,返回值类型为int类型 public static int method03(int i,int j){ int product = i * j; // 方法有返回值,必须有return语句,并且返回值的类型与方法定义的类型 // 相同,否则编译不能通过 return product; // return 语句后面不能存在其他语句,否则编译不能通过 // System.out.println("product = " + product); } } |
1.2 方法的调用
静态方法的调用原则。在同一个类中,调用静态方法可以使用类名.的方式进行调用,也可以直接使用方法名进行调用。
public class MethodTest04 {
public static void main(String[] args){ // 在同一个类中,可以直接使用方法名调用静态方法 method02(); // 也可以使用类名的方式调用静态方法 MethodTest04.method02(); // 不在同一个类中的静态方法必须使用类名.的方式进价调用 A.method03(); }
public void method01(){ method02(); MethodTest04.method02(); }
public static void method02(){ System.out.println("Hello Java"); } }
class A{ // 在A类中定义的静态方法 public static void method03(){ System.out.println("A method03()"); } } |
调用带参数的静态方法,需要传递相应类型的参数。通常情况下调用有返回值的方法就是要取得返回值,返回值变量的类型必须与方法返回值的类型相同。在方法中,return语句执行则方法结束,执行流程放回到方法调用处。
public class MethodTest05 {
public static void main(String[] args){ // 调用有返回值的静态方法 int success = method01(true); // 返回值类型是方法的返回值类型 // 参数的类型必须是方法定义的参数类型,并且顺序相同 int product = method02(10,3); System.out.println("product: " + product); // 不在同一个类中,必须采用类名.的方式调用静态方法 A.method03("张三"); } // 静态方法 public static int method01(boolean b){ /* if(b){ return 1; }else{ return 0; } */
if(b){ return 1; }
return 0; } // 静态方法,返回值类型是int型,两个参数。形式参数类型是int public static int method02(int i,int j){ // 返回值的类型必须是方法定义的返回值类型 return i / j; // return语句执行,方法结束,所以不能有语句在return后面,编译不能通过 // System.out.println(i / j); } }
class A{ // 定义的静态方法 public static void method03(String name){ System.out.println("name: " + name); } } |
如何终止方法的执行,采用的方式是如果符合某种条件,使用return语句终止方法的执行。
public class MethodTest06 {
public static void main(String[] args){
method01(11); method01(8); } // 静态方法,没有返回值,一个形式参数,类型是int public static void method01(int i){ // 如果参数值大于10终止方法执行 if(i > 10){ // return语句执行,方法结束 return; }
for(;i <= 10;i++){ if(i == 5){ // break只是结束终止循环 break; } System.out.println("i = " + i); }
System.out.println("break后要执行的语句"); } } |
return语句的使用方式。
public class MethodTest07 {
public static void main(String[] args){ // 静态方法调用 method01(); String info = method02(); System.out.println(info); }
public static void method01(){ // 方法没有返回值,如果使用return,return后面不能存在语句 //return; // 编译可以通过,虽然最后的语句不会输出 if(true){ return; }
System.out.println("HelloWord"); }
public static String method02(){ // 如果方法有返回值,必须存在return语句,后面的值类型必须和返回类型 // 相同,并且return语句后面不能跟其他语句 //return "HelloWord"; // 这种方式可以, /* if(true){ return "HelloWord"; }else{ return "OK"; } */ // 这种方式可以 if(true){ return "HelloWord"; }
return "OK"; // 方法有返回值,return语句一定是最后一条语句,否则编译不能通过 //System.out.println("HelloWord"); } } |
1.3 方法的重载
需求:定义三个方法,分别是int类型、double类型和long类型实现乘积的方法,方法有返回值。
public class MethodTest08 {
public static void main(String[] args){
int product1 = productInt(10,20); System.out.println(product1); double product2 = productDouble(10.11,93.23); System.out.println(product2); long product3 = productLong(10L,20L); System.out.println(product3); // 注意:类型从小容量到大容量,自动类型转换 productInt(10,20); productDouble(10,20); productLong(10,20); }
public static int productInt(int i1,int i2){
return i1 * i2; }
public static double productDouble(double d1,double d2){
return d1 * d2; }
public static long productLong(long l1,long l2){
return l1 * l2; } } |
上面的代码实现了功能,但是存在的问题是每个方法的方法名称不同,相同的是求两个数值类型的值的乘积。另外,还需要记忆多个方法名,并且代码不是特别易读。如果方法实现的功能相同,只是参数类型或者参数的数量不同,可以采用方法重载的方式,如下例子。
public class MethodTest09 {
public static void main(String[] args){
int product1 = product(10,20); System.out.println(product1); double product2 = product(10.11,93.23); System.out.println(product2); long product3 = product(10L,20L); System.out.println(product3); }
public static int product(int i1,int i2){
return i1 * i2; }
public static double product(double d1,double d2){
return d1 * d2; }
public static long product(long l1,long l2){
return l1 * l2; } } |
修改后,三个方法的方法名称相同,参数类型不同,返回值类型不同,但是调用时只需要传入不同类型的参数,不需要指定调用哪个方法,系统会根据参数的类型自动调用相应的方法并将结果返回。并且不需要记忆更多的方法名称。
方法重载的条件。
1.方法重载只出现在同一个类中
2.方法名相同
3.方法的参数类型,个数,顺序至少有一个不同
4.方法的返回类型可以不同(不依靠返回类型来区分重载)
5.方法的修饰符可以不同,因为方法重载和修饰符没有任何关系
public class MethodTest10 {
public static void main(String[] args){
} // 方法重载必须在同一个类中 // 参数类型不同,是方法重载 public static void m1(int i1,int i2){} public static void m1(double d1,double d2){} // 参数数量不同,是方法重载 public static void m2(int i1){} public static void m2(double d1,double d2){} // 参数顺序不同,是方法重载 public static void m3(int i1,double d1){} public static void m3(double d1,int i1){} // 参数类型相同,参数个数相同,不是方法重载,是方法重复 //public static void m4(int a){} //public static void m4(int b){} // 参数类型和个数相同,返回值类型不同,不是方法重载, // 方法重载和返回值类型无关 //public static int m5(int i){} //public static void m5(int i){} // 参数相同,访问修饰符不同,不是方法重载,方法重载和访问修饰符无关 //private static void m6(){} //public static void m6(){} } |
方法重载举例。
public class MethodTest11 {
public static void main(String[] args){ // sun提供的方法重载例子 System.out.println(10); System.out.println(23.2); System.out.println(true); System.out.println(‘A‘); } } |
1.4 类、方法、属性(静态变量)的关系
在一个类中,从类和成员的角度可分为静态的和成员的部分。静态的部分可分为静态变量、静态方法和静态内部类等等。成员的部分可以分为成员变量、成员方法和成员内部类等等。注意:也就是说,在类体中只存在两部分内容,一是属性(成员的或静态的),二是方法(成员方法或静态方法)或内部类。那么可以执行的代码只能存在与方法中,包括成员方法或静态方法,所以,存在与方法中的代码是为了实现一个特定的功能,就像一个工厂生产特定的产品,方法的参数类似于工厂需要的生成原料,而方法的返回值相当于工厂生产出的产品。
public class MethodTest12 {
// 类体
// 成员属性 int i = 10;
// 静态变量 static String country = "中国";
// 成员方法 public void method01(int i){ // 方法体 // 可以执行的代码 // 将参数做一些特殊的处理 System.out.println(i); }
// 静态方法 public static int method02(int i1,int i2){ // 方法体 // 可以执行的代码 // 实现特定功能,并返回特定的结果 return i1 + i2; }
public static void main(String[] args){ // 方法体 // 可以执行的代码 // 程序的执行入口方法 } } |
1.5 调用方法的执行流程
1.5.1 栈的概念
当通过Java命令执行一个程序时,会启动一个JVM,Java虚拟机进程,并创建程序运行环境,会创建程序运行的栈内存,下面的图做了简单的说明。
1.1.1 程序的执行过程
下面通过一个程序说明程序的执行过程。
public class MethodTest13 {
public static void main(String[] args){ // 调用method01()方法 method01(10); } // method01()方法调用method02()方法 public static void method01(int i){ method02(i); } // method02()方法调用method03()方法 public static void method02(int i){ method03(i); }
public static void method03(int i){ System.out.println("i: " + i); } // method04()方法没有被调用 public static void method04(int i){ System.out.println(i); } } |
main()方法调用method01()方法,method01()方法调用method02()方法,method02()方法调用method03()方法,在method03()方法中将参数输出。下面通过一个图说明程序的执行流程。
注意:当方法被调用时,才会在内存中为方法分配空间。如果只是定义了方法,但是没有被调用,不会为方法在内存中分配空间。方法被调用时,Java虚拟机会为方法在栈内存中为方法分配空间。方法被调用时会发生压栈操作,当方法执行结束后会发生弹栈操作。
一、 递归
方法的递归调用就是方法自身调用自身。通常在树形结构访问时用到,如:目录的递归检索,又如权限管理中权限目录数的访问等等。下面的例子是递归的简单演示。
public class RecursionTest01 {
public static void main(String[] args){ // 调用method01()方法 method01(10); } // 方法method01() public static void method01(int i){ // 方法自己调用自己,无限调用下去没有返回 method01(i); } } |
在上面的例子中,因为递归没有结束的条件,所以每调用一次method01()方法,就会在内存中开辟空间,产生压栈操作,但没有出栈操作,不会释放内存,会导致栈内存溢出错误!所以递归程序必须要有结束条件。
不使用递归计算1~n整数的和。
public class RecursionTest02 {
public static void main(String[] args){
int sum = method01(10); System.out.println(sum); }
public static int method01(int n){ int sum = 0;
for(int i = 1;i <= n;i++){ sum += i; }
return sum; } } |
使用递归实现1~n的求和。
public class RecursionTest03 {
public static void main(String[] args){
int sum = sum(5); System.out.println(sum); }
public static int sum(int n){ // 如果参数n等于1,直接返回 if(n == 1){ return 1; }else{ // 否则,将参数n减一作为参数调用自身,返回的值与参数n的和就是 // 最终的结果。 return n + sum(n - 1); } } } |
上面程序的执行流程:
练习:
1. 采用递归的方式求1~n的偶数的和。
public class RecursionTest04 {
public static void main(String[] args){
int sum = sum(5); System.out.println(sum); }
public static int sum(int n){ if(n % 2 != 0){ n -= 1; } if(n == 2){ return 2; }else{ return n + sum(n - 2); } } } |
2. 采用递归的方式求n!。
public class RecursionTest05 {
public static void main(String[] args){
int sum = product(5); System.out.println(sum); }
public static int product(int n){ if(n == 1){ return 1; }else{ return n * product(n - 1); } } } |
3. 不采用递归的方式实现n!。
public class RecursionTest06 {
public static void main(String[] args){
int sum = product(5); System.out.println(sum); }
public static int product(int n){ int product = 1; for(int i = 1;i <= n;i++){ product *= i; }
return product; } } |
本文出自 “kevin.blog” 博客,请务必保留此出处http://dongkevin.blog.51cto.com/12103298/1859921
以上是关于JavaSE学习笔记——Java中的方法的主要内容,如果未能解决你的问题,请参考以下文章