在前面几个章节中我们经常使用到 System.out.println(),那么它是什么呢?
-
println() 是一个方法。
-
System 是系统类。
-
out 是标准输出对象。
这句话的用法是调用系统类 System 中的标准输出对象 out 中的方法 println()。
目录
什么是方法
Java方法是语句的集合,它们在一起执行一个功能。
-
方法是解决一类问题的步骤的有序组合
-
方法包含于类或对象中
-
方法在程序中被创建,在其他地方被引用
方法的优点
-
使程序变得更简短而清晰。
-
有利于程序维护。
-
可以提高程序开发的效率。
-
提高了代码的重用性。
方法的命名规则
方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符。例如:addPerson。
方法的定义
一般情况下,定义一个方法包含以下语法:
修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值;
}
方法包含一个方法头和一个方法体。下面是一个方法的所有部分:
-
修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
-
返回值类型 :方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void。
-
方法名:是方法的实际名称。方法名和参数表共同构成方法签名。
-
参数类型:参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
-
方法体:方法体包含具体的语句,定义该方法的功能。
如:
public static int age(int birthday){...}
参数可以有多个:
static float interest(float principal, int year){...}
注意: 在一些其它语言中方法指过程和函数。一个返回非void类型返回值的方法称为函数;一个返回void类型返回值的方法叫做过程。
实例
下面的方法包含 2 个参数 num1 和 num2,它返回这两个参数的最大值。
/** 返回两个整型变量数据的较大值 */
public static int max(int num1, int num2) {
int result;
if (num1 > num2)
result = num1;
else
result = num2;
return result;
}
更简略的写法(三元运算符):
public static int max(int num1, int num2) {
return num1 > num2 ? num1 : num2;
}
方法调用
Java 支持两种调用方法的方式,根据方法是否返回值来选择。
当程序调用一个方法时,程序的控制权交给了被调用的方法。当被调用方法的返回语句执行或者到达方法体闭括号时候交还控制权给程序。
当方法返回一个值的时候,方法调用通常被当做一个值。例如:
int larger = max(30, 40);
如果方法返回值是void,方法调用一定是一条语句。例如,方法println返回void。下面的调用是个语句:
System.out.println("欢迎访问菜鸟教程!");
实例
下面的例子演示了如何定义一个方法,以及如何调用它:
public class TestMax {
/** 主方法 */
public static void main(String[] args) {
int i = 5;
int j = 2;
int k = max(i, j);
System.out.println( i + " 和 " + j + " 比较,最大值是:" + k);
}
/** 返回两个整数变量较大的值 */
public static int max(int num1, int num2) {
int result;
if (num1 > num2)
result = num1;
else
result = num2;
return result;
}
}
以上实例编译运行结果如下:
5 和 2 比较,最大值是:5
void 关键字
本节说明如何声明和调用一个 void 方法。
下面的例子声明了一个名为 printGrade 的方法,并且调用它来打印给定的分数。
public class TestVoidMethod {
public static void main(String[] args) {
printGrade(78.5);
}
public static void printGrade(double score) {
if (score >= 90.0) {
System.out.println('A');
}
else if (score >= 80.0) {
System.out.println('B');
}
else if (score >= 70.0) {
System.out.println('C');
}
else if (score >= 60.0) {
System.out.println('D');
}
else {
System.out.println('F');
}
}
}
以上实例编译运行结果如下:
C
这里printGrade方法是一个void类型方法,它不返回值。
一个void方法的调用一定是一个语句。 所以,它被在main方法第三行以语句形式调用。就像任何以分号结束的语句一样。
值传递和引用传递
1、按值传递是什么
指的是在方法调用时,传递的参数是按值的拷贝传递。示例如下:
public class TempTest {
private void test1(int a){
//做点事情
}
public static void main(String[] args) {
TempTest t = new TempTest();
int a = 3;
t.test1(a);//这里传递的参数a就是按值传递
}
}
按值传递重要特点:传递的是值的拷贝,也就是说传递后就互不相关了。
示例如下:
public class TempTest {
private void test1(int a){
a = 5;
System.out.println("test1方法中的a="+a);
}
public static void main(String[] args) {
TempTest t = new TempTest();
int a = 3;
t.test1(a);//传递后,test1方法对变量值的改变不影响这里的a
System.out.println(”main方法中的a=”+a);
}
}
运行结果是:
test1方法中的a=5 main方法中的a=3
2:按引用传递是什么
指的是在方法调用时,传递的参数是按引用进行传递,其实传递的引用的地址,也就是变量所对应的内存空间的地址。
示例如下:
public class TempTest {
private void test1(A a){
}
public static void main(String[] args) {
TempTest t = new TempTest();
A a = new A();
t.test1(a); //这里传递的参数a就是按引用传递
}
}
class A{
public int age = 0;
}
3:按引用传递的重要特点
传递的是值的引用,也就是说传递前和传递后都指向同一个引用(也就是同一个内存空间。
示例如下:
public class TempTest {
private void test1(A a){
a.age = 20;
System.out.println("test1方法中的age="+a.age);
}
public static void main(String[] args) {
TempTest t = new TempTest();
A a = new A();
a.age = 10;
t.test1(a);
System.out.println(”main方法中的age=”+a.age);
}
}
class A{
public int age = 0;
}
运行结果如下:
test1方法中的age=20 main方法中的age=20
4:总结
(1)“在Java里面参数传递都是按值传递”这句话的意思是:按值传递是传递的值的拷贝,按引用传递其实传递的是引用的地址值,所以统称按值传递。
(2)在Java里面只有基本类型和按照下面这种定义方式的String是按值传递,其它的都是按引用传递。就是直接使用双引号定义字符串方式:String str = “Java私塾”;
方法的重载
上面使用的max方法仅仅适用于int型数据。但如果你想得到两个浮点类型数据的最大值呢?
解决方法是创建另一个有相同名字但参数不同的方法,如下面代码所示:
public static double max(double num1, double num2) {
if (num1 > num2)
return num1;
else
return num2;
}
如果你调用max方法时传递的是int型参数,则 int型参数的max方法就会被调用;
如果传递的是double型参数,则double类型的max方法体会被调用,这叫做方法重载;
就是说一个类的两个方法拥有相同的名字,但是有不同的参数列表。
Java编译器根据方法签名判断哪个方法应该被调用。
方法重载可以让程序更清晰易读。执行密切相关任务的方法应该使用相同的名字。
重载的方法必须拥有不同的参数列表。你不能仅仅依据修饰符或者返回类型的不同来重载方法。
变量作用域
变量的范围是程序中该变量可以被引用的部分。
局部变量 :方法内定义的变量被称为局部变量。
局部变量的作用范围从声明开始,直到包含它的块结束;局部变量必须声明才可以使用。方法的参数范围涵盖整个方法。参数实际上是一个局部变量。
for循环的初始化部分声明的变量,其作用范围在整个循环。但循环体内声明的变量其适用范围是从它声明到循环体结束。它包含如下所示的变量声明:
你可以在一个方法里,不同的非嵌套块中多次声明一个具有相同的名称局部变量,但你不能在嵌套块内两次声明局部变量。
命令行参数的使用
有时候你希望运行一个程序时候再传递给它消息。这要靠传递命令行参数给main()函数实现。
命令行参数是在执行程序时候紧跟在程序名字后面的信息
实例
下面的程序打印所有的命令行参数:
public class CommandLine {
public static void main(String args[]){
for(int i=0; i<args.length; i++){
System.out.println("args[" + i + "]: " + args[i]);
}
}
}
如下所示,运行这个程序:
$ javac CommandLine.java $ java CommandLine this is a command line 200 -100 args[0]: this args[1]: is args[2]: a args[3]: command args[4]: line args[5]: 200 args[6]: -100
可变参数
JDK 1.5 开始,Java支持传递同类型的可变参数给一个方法。
方法的可变参数的声明如下所示:
typeName... parameterName
在方法声明中,在指定参数类型后加一个省略号(...) 。
一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
实例
public class VarargsDemo {
public static void main(String args[]) {
// 调用可变参数的方法
printMax(34, 3, 3, 2, 56.5);
printMax(new double[]{1, 2, 3});
}
public static void printMax( double... numbers) {
if (numbers.length == 0) {
System.out.println("No argument passed");
return;
}
double result = numbers[0];
for (int i = 1; i < numbers.length; i++){
if (numbers[i] > result) {
result = numbers[i];
}
}
System.out.println("The max value is " + result);
}
}
以上实例编译运行结果如下:
The max value is 56.5 The max value is 3.0
递归
A方法调用B方法,我们很容易理解! 1、递归就是: A方法调用A方法!就是自己调用自己。递归的能力在于用有限的语句来定义对象的无限集合。
2、利用递归可以用简单的程序来解决一些复杂的问题。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。
3、递归结构包括两个部分: 递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。 递归体:什么时候需要调用自身方法。
实例
public class Demo08 {
public static void main(String[] args) {
System.out.println(f(3));
}
//递归思想的学习!!!尽量不要用,除非基数特别小!!!方法调用次数太多影响机器性能
//阶乘 3=3*2*1
public static int f(int n) {
if (n == 1) {
return 1;
} else {
return n * f(n - 1);
}
}
}