特殊流程控制语句break,continue
break 语句
break语句用于终止某个语句块的执行,终止循环体
{ ……
break;
……
}
break 语句用法举例
public class TestBreak{
public static void main(String args[]){
for(int i = 0; i<10; i++){
if(i==3)
break;
System.out.println(" i =" + i);
}
System.out.println("Game Over!");
}
}
continue 语句
continue语句用于跳过某个循环语句块的一次执行,结束本次循环执行,进行下一次循环。
continue语句出现在多层嵌套的循环语句体中时,可以通过标签指明要跳过的是哪一层循环
continue语句用法举例
public class ContinueTest {
public static void main(String args[]){
for (int i = 0; i < 100; i++) {
if (i%10==0)
continue;
System.out.println(i);
}
}
}
break只能用于switch语句和循环语句中。
continue 只能用于循环语句中。
二者功能类似,但continue是终止本次循环,break是终止本层循环。
break、continue之后不能有其他的语句,因为程序永远不会执行其后的语句。
方法概述
为什么使用方法?
减少重复性劳动,提高代码重用性。
比如,打印乘法口诀的代码要多次的执行,如果每次都写两个循环来实现这样的功能的话,不但代码变多,使程序的可读性变差,而且重复劳动非常多,解决的办法就是将这些经常重复使用到的代码提出来,放到一个{}中,并给这个{}起一个名字,以后再次使用到这个{}的内容时,只需要调用这个名字就可以了,这个提取重复内容的过程就是方法的定义过程,{}中的内容,就是方法的内容。
方法定义及格式
简单的说:方法就是完成特定功能的代码块{}
在很多语言里面都有函数的定义
函数在Java中被称为方法
格式:
修饰符 返回值类型 方法名(参数类型 参数名1,参数类型 参数名2…) {
方法体;
return [返回值];
}
方法格式的解释说明
- 修饰符
比较多,后面会详细介绍。目前可以这样记忆:被main方法直接调用的方法,定义时固定写成public static
- 返回值类型
用于限定返回值的数据类型(可以是基本数据类型,比如:byte,short,int,long等,也可以是引用数据类型,如String,数组,对象引用等,也可以什么都不返回,特定写成void)
需不需要返回值,需要什么类型的返回值,完全取决于业务逻辑,没有统一规定
- 方法名
一个名称,一般小写,多个单词使用驼峰命名,尽量做到见名知义
- 参数类型 限定调用方法时传入参数的数据类型
- 参数名
是一个变量,接收调用方法时传入的参数
参数类型和形参名合起来称为形参列表
- 方法体
完成功能的代码,每次方法被调用,就执行一次这里面的代码
- return
结束方法以及返回方法指定类型的值,如果方法定义时指定返回值为void,则return后不能接任何东西,此时的return可以省略
- 返回值 程序被return带回的结果,返回给调用者
自定义方法的位置
- 类体内
- 不能在方法中再定义方法,或者说方法不能嵌套定义
目前由于还没有涉及到类和面向对象,所以我们自定义的类都是和main方法在同一个类中,这时要求所定义的方法的修饰符必须是public static,暂时记住即可
示例:
public static void main(String[] args){
add(1,2);//调用方法
}
public static void add(int a ,int b){
System.out.println("hello world");
return ; //void 可以加return么??
}
总结:
- 自定义的方法修饰符目前可以固定写成public static
- 返回值要看具体的方法功能,可以是void,可以是基本数据类型,可以是引用数据类型
- 方法名做到见名知义
- 形参列表里的参数类型可以是基本数据类型和引用数据类型
- return的含义:
用来表示一个方法的结束,并且携带返回值(如果有的话)
一旦携带返回值,一定要和方法定义的返回值类型相同或者是可以自动转换的类型,或者是子类型
自定义方法案例
如何写一个方法呢?考虑两个事情:
- 返回值类型:明确功能结果的数据类型,没有返回值就是void,有的话,就是具体的类型
- 参数列表:明确有几个参数,以及各个参数的类型
按照格式和需要考虑的两个事情自定义方法,来完成如下功能
定义方法求两个数据之和
1.需要返回值么?什么类型的返回值?
2.需要参数么?对什么进行操作?
代码:
class FunctionDemo {
public static void main(String[] args) {
int x = 10;
int y = 20;
//方式1:单独调用
//sum(x,y);
//方式2:输出调用
//System.out.println(sum(x,y));
//相当于System.out.println(30);
//方式3:赋值调用
int result = sum(x,y);
//result在这里可以进行操作
System.out.println(result);
}
/*
需求:求两个数据之和的案例
两个明确:
返回值类型:int
参数列表:2个,都是int类型
*/
public static int sum(int a,int b) {
//如何实现呢?
//int c = a + b;
//return c;
//c就是a+b,所以,我可以直接返回a+b
return a + b;
}
}
验证:
一个有返回值的方法是否可以单独使用?
单独使用就是单独一句调用语句,不打印,不赋值给其他变量
三元运算符不能单独使用,必须有变量接收,或者打印,或者嵌套;
有返回值的方法可以单独使用,没有变量接收编译也不报错。
总结:
可以使用带有返回值的方法的返回值,也可以不理会它的返回值。
案例:求最大值
键盘录入两个数据,返回两个数中的较大值
要求定义方法实现比较两个数的大小,并且使用三元运算符
import java.util.Scanner;
class FunctionTest {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
System.out.println("请输入第一个数据:");
int a = sc.nextInt();
System.out.println("请输入第二个数据:");
int b = sc.nextInt();
int result = getMax(a,b);
System.out.println("较大值是:"+result);
}
/*
需求:两个数中的较大值
两个明确:
返回值类型:int
参数列表:int a,int b
*/
public static int getMax(int a,int b) {
//if语句
/*
if(a > b) {
//System.out.println(a);
return a;
}else {
//System.out.println(b);
return b;
}*/
//用三元改进
//int c = ((a > b)? a: b);
//return c;
//由于c就是后面的式子
return ((a>b)? a : b);
}
}
案例:比较两个数大小
键盘录入两个数据,比较两个数是否相等,定义方法用于比较,返回布尔值
(if语句?三元运算符?能否更精简?)
/*
键盘录入两个数据,比较两个数是否相等
*/
import java.util.Scanner;
class FunctionTest2 {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
System.out.println("请输入第一个数据:");
int a = sc.nextInt();
System.out.println("请输入第二个数据:");
int b = sc.nextInt();
//将方法返回值赋值给一个变量,注意类型
boolean flag = compare(a,b);
System.out.println(flag);
}
/*
需求:比较两个数是否相等
两个明确:
返回值类型:boolean
参数列表:int a,int b
*/
public static boolean compare(int a,int b) {
//if语句的格式2实现
/*
if(a == b) {
return true;
}else {
return false;
}
*/
//三元改进
//boolean flag = ((a==b)? true: false);
//return flag;
//继续改进
//return ((a==b)? true: false);
//最终版
return a == b;
}
}
案例:求三个数中最大值
定义方法接收键盘录入的三个数据,返回三个数中的最大值
要求:使用三元运算符和使用if两种方式实现
/*
键盘录入三个数据,返回三个数中的最大值
*/
import java.util.Scanner;
class FunctionTest3 {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
System.out.println("请输入第一个数据:");
int a = sc.nextInt();
System.out.println("请输入第二个数据:");
int b = sc.nextInt();
System.out.println("请输入第三个数据:");
int c = sc.nextInt();
int max = getMax(a,b,c);//调用方法,将返回值赋值给一个变量
System.out.println("三个数据中的最大值是:"+max);
}
/*
需求;返回三个数中的最大值
两个明确:
返回值类型:int
参数列表:int a,int b,int c
*/
public static int getMax(int a,int b,int c) {
//if嵌套
/*
if(a > b) {
if(a > c) {
return a;
}else {
return c;
}
}else {
if(b > c) {
return b;
}else {
return c;
}
}
*/
//用三元改
/*
if(a > b) {
return (a>c? a: c);
}else {
return (b>c? b: c);
}
*/
//继续改进
//return (a>b)? (a>c? a: c): (b>c? b: c);
//不建议,写代码一定要注意阅读性强,改成如下格式
int temp = ((a>b)? a: b);
int max = ((temp>c)? temp: c);
return max;
}
}
方法定义和使用的注意事项
1.自定义的方法不调用的话,不会自动执行
2.方法与方法是平级关系,不能嵌套定义
3.方法定义的时候参数之间用逗号隔开
4.方法调用的时候不用在传递数据类型,只传值,或者是变量名即可,例如
int res = add(1,2);
//也可以直接传递常量值
int a = 1,b = 2;
int res = add(a,b);
//以下调用是错误的,调用方法时不用再把实参的类型加上
//int res = add(int a,int b);
5.如果方法有明确的返回值,一定要有return带回一个同类型值(或者可以自动向上转型的返回值),比如,有如下方法定义:
public static int test(){
short s = 12;
return s; //s虽然是short型,但是可以自动转型成int型
}
案例:常见错误
方法定义,使用时常见的错误
1.在方法中再次定义方法(嵌套定义方法)
2.返回值类型不匹配,或者不能自动转型
3.调用方法时,在实参前多加了实参的类型
4.方法定义有返回值,但是没有在方法中加return语句
class FunctionDemo2 {
public static void main(String[] args) {
/*//不能在main方法中再定义方法
public static int sum(int a,int b){
return a + b;
}
*/
//sum(10,20);
//int x = 10;
//int y = 20;
//调用方法的时候,不能带实参的数据类型
//sum(int x,int y);
}
public static int sum(int a,int b){
return a + b;
}
}
没有明确返回值的方法的使用
没有返回值,就是返回值为void类型的方法,这样的方法的使用规范是:
不能用于赋值和打印,只能单独调用
案例:返回值为void型方法的使用
/*
需求:在控制台输出如下的形状
*****
*****
*****
*****
void类型返回值的方法调用:
只能是单独调用
不能输出调用
不能赋值调用
*/
class FunctionDemo3 {
public static void main(String[] args) {
//for循环嵌套输出图形
for(int x=0; x<4; x++) {
for(int y=0; y<5; y++) {
System.out.print("*");
}
System.out.println();
}
System.out.println("--------------");
//需求:在控制台输出一个6行7列的星形图形
for(int x=0; x<6; x++) {
for(int y=0; y<7; y++) {
System.out.print("*");
}
System.out.println();
}
System.out.println("--------------");
//如果需要继续改变,我们就应该考虑使用方法改进。
//单独调用
printXing(3,4);
System.out.println("--------------");
printXing(6,7);
System.out.println("--------------");
printXing(8,9);
//输出调用?
//由于方法没有返回值,所以不允许放到打印语句中
//System.out.println(printXing(3,4));
//赋值调用?
//没有void这种类型的变量,不用用于赋值。报错:非法的表达式开始
//void v = printXing(3,4);
}
/*
两个明确:
返回值类型:这个时候没有明确的返回值,这里记住是void
参数列表:int m,int n
*/
public static void printXing(int m,int n) {
for(int x=0; x<m; x++) {
for(int y=0; y<n; y++) {
System.out.print("*");
}
System.out.println();
}
}
}
总结:
- void类型的方法不能放在打印语句中
- void类型的方法不能用于赋值语句中
- void类型的方法只能单独调用
返回值为void类型的方法练习
要求:定义一个方法,接收键盘录入行数和列数,输出由*号组成的矩形
/*
键盘录入行数和列数,输出对应的星形
*/
import java.util.Scanner;
class FunctionTest4 {
public static void main(String[] args) {
//创建键盘录入对象
Scanner sc = new Scanner(System.in);
System.out.println("请输入行数:");
int m = sc.nextInt();
System.out.println("请输入列数:");
int n = sc.nextInt();
//void类型的方法调用
printXing(m,n);
}
/*
两个明确:
返回值类型:void
参数列表:int m,int n
*/
public static void printXing(int m,int n) {
for(int x=0; x<m; x++) {
for(int y=0; y<n; y++) {
System.out.print("*");
}
System.out.println();
}
}
}
案例:n*n乘法表
定义方法,接收键盘录入一个数据n(1<=n<=9),输出对应的n*n乘法表
/*
键盘录入一个数据n(1<=n<=9),输出对应的nn乘法表
*/
import java.util.Scanner;
class FunctionTest5 {
public static void main(String[] args) {
//创建对象
Scanner sc = new Scanner(System.in);
System.out.println("请输入n的值:(1~9)");
int n = sc.nextInt();
//调用自定义方法
printNN(n);
}
/*
功能:输出nn乘法表
两个明确:
返回值类型:void
参数列表:int n
*/
public static void printNN(int n) {
for(int x=1; x<=n; x++) {
for(int y=1; y<=x; y++) {
System.out.print(y+"x"+x+"="+y*x+"\t");
}
System.out.println();
}
}
}
方法重载
在同一个类中,允许存在一个以上的同名方法,只要它们的参数列表(参数个数或者参数类型)不同即可,这就叫方法的重载。
如果一个类中存在两个或者两个以上同名的方法,但是形参列表不同,他们就是方法的重载
方法重载特点
- 与返回值类型无关,只看方法名和参数列表(形参个数,类型)
- 在调用时,虚拟机通过参数列表的不同来区分同名方法
为什么方法的返回值不是区分两个方法重载的标志?
方法重载的例子
public static void test(){
System.out.println("这是不带参数的test方法");
}
public static int test(int id){
System.out.println("这是带一个参数的test方法");
return id;
}
//以下方法只是和上面方法返回值不同,系统无法识别成方法的重载,编译错误
public static String test(int id){
System.out.println("这是带一个参数的test方法");
return id+"";
}
案例:
定义两个同名方法,只有形参的个数不同
在使用方法时,系统会根据传递参数的个数不同而调用不同方法
/*
方法重载:
在同一个类中,方法名相同,参数列表不同。与返回值类型无关。
参数列表不同:
A:参数个数不同
B:参数类型不同
*/
class FunctionDemo4 {
public static void main(String[] args) {
//jvm会根据不同的参数去调用不同的功能
System.out.println(sum(10,20));
System.out.println(sum(10,20,30));
System.out.println(sum(10,20,30,40));
System.out.println(sum(10.5f,20f));
}
//需求1:求两个数的和
public static int sum(int a,int b) {
System.out.println("int");
return a + b;
}
//需求2:求三数的和,无需再定义sum1,含三个形参
/*
public static int sum1(int a,int b,int c) {
return a + b + c;
}
*/
public static int sum(int a,int b,int c) {
return a + b + c;
}
//需求3:求四个数的和,无需再定义sum2,含四个形参
/*
public static int sum2(int a,int b,int c,int d) {
return a + b + c + d;
}
*/
public static int sum(int a,int b,int c,int d) {
return a + b + c + d;
}
public static float sum(float a,float b) {
System.out.println("float");
return a + b;
}
}
方法重载练习:
1.定义两个方法,只有形参类型不同,数量相同
2.定义两个方法,只有形参数量不同,类型相同
3.定义两个方法,形参数量和类型都不相同
思考:一个形参是int型,一个形参是short型,编译器能准确理解我传入的参数的类型么?
有如下两个重载方法的定义:
public static void add(int a,int b){
System.out.println("int");
}
public static void add(short a,short b){
System.out.println("short");
}
使用如下方式调用,JVM将使用哪个方法呢?
public static void main(String[] args){
add(2,3);
}
是不是另一个方法永远得不到调用了?怎么才能调用?
显式调用,可以指定参数的类型:
short a = 2;
short b = 3;
add(a,b);
案例:重载方法比较两个数是否相等
比较两个数据是否相等。参数类型分别为两个byte类型,两个short类型,两个int类型,两个long类型,使用重载方法
class FunctionTest6 {
public static void main(String[] args) {
//测试
byte b1 = 3;
byte b2 = 4;
System.out.println("byte:"+compare(b1,b2));
//测试
short s1 = 5;
short s2 = 5;
System.out.println("short:"+compare(s1,s2));
//后面的两个自己测试
}
//byte类型
public static boolean compare(byte a,byte b) {
System.out.println("byte");
return a == b;
}
//short类型
public static boolean compare(short a,short b) {
System.out.println("short");
return a == b;
}
//int类型
public static boolean compare(int a,int b) {
System.out.println("int");
return a == b;
}
//long类型
public static boolean compare(long a,long b) {
System.out.println("long");
return a == b;
}
}
自定义方法之间的互相调用
之前使用的自定义方法都是被main方法调用,实际上我们自己自定义的方法之间同样可以互相调用
例如,有如下两个方法,其中一个就调用了另一个方法,这两个方法在定义的顺序上没有先后要求
public static void speak(String content) {
sayHi(); //调用另一个自定义方法
System.out.println("我想说的是: "+content);
}
public static void sayHi() {
System.out.println("Hi");
}
public static void main(String[] args) {
speak("天气不错");
}
方法的递归(了解内容)
根据方法的定义和使用规则,方法可以在同一个类中直接调用另一个方法。
但是,能不能调用这个方法自身呢?
验证:
public static void show(){
System.out.println("hello");
show();
return ;
}
一个方法体内调用它自己,就称为方法的递归,方法的递归包含了一种隐式的循环,它会循环执行某段代码,但是这种循环无须控制代码。
递归调用必须有个终止值,否则一直递归调用,直到内存溢出(StackOverflowError)。
方法递归的应用
例如:已知一个数列
f(0)=1,f(1)=4,f(n+2)=2*f(n+1)+f(n),其中n是大于0的整数
求f(10)的值。
变长参数(暂时了解,后面详解)
jdk1.5之后,Java允许在形参中定义个数可变的参数,在调用方法时,可以传递不同个数的参数,定义的方式是:
在最后一个形参的类型后加上...即可,多个参数会被当成一个数组来传入(数组后面会讲)
例如:
public static void add(int i,String... args){
System.out.println(i);//打印第一个参数
//变长参数是一个数组,for循环来遍历
for(int i = 0;i<args.length;i++){
System.out.println(args[i]);
}
}
自定义方法总结:
- 方法定义和格式
固定的public static 返回值 方法名(形参类型1 形参名1,形参类型2 形参名2...)
- 一个没有返回值的方法只能单独调用,不能赋值,不能打印。
- 可以使用带有返回值的方法的返回值(打印/赋值),也可以不理会它的返回值(单独调用)
- 一个类中的同名,但是形参个数或者类型不同的多个方法称为方法的重载
返回值类型不能区别两个方法是否是方法重载