JAVA基础
作为一名软件测试工程师,经常会自己做一些测试数据,也为了之后的自动化测试及review项目代码,决定系统的学习JAVA。
本笔记是根据【狂神说Java】Java零基础学习视频通俗易懂按课程进度逐步学习,强烈推荐给大家。
此外狂神说的课程还包含前端、后端、数据库、redis、框架等课程,全部免费,一并推荐给大家,详见遇见狂神说的B站主页。
//输出一个HelloWorld 单行注释
/*
多行注释
*/
/**
* ┏┓ ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* ████━████ ┃+
* ┃ ┃ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━┓ ┏━┛
* ┃ ┃
* ┃ ┃ + + + +
* ┃ ┃ Code is far away from bug with the animal protecting
* ┃ ┃ + 神兽保佑,永无bug
* ┃ ┃
* ┃ ┃ +
* ┃ ┗━━━┓ + +
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +
*/
- 可以使用大小写字母、$和_开头
- 首字母之后可以跟大小写字母、$和_
- 不建议用拼音命名
- 可以使用中文命名,但不建议使用
- 大小写十分敏感
关键字:字母 $ 下划线
int i2 = 0b1;//二进制
int i8 = 010; //八进制0
int i10 = 10;//十进制
int i16 = 0x10; //十六进制0x
float f = 0.1f;
由于浮点数是有限的,会舍入误差,数值过大时无法精确比较,数据量过大系统还是会判断相等,所以银行不会使用浮点数开发程序,银行用BigDecimal。
float f1 = 1212121212121212121f;
float f2 = f1+1;
System.out.println(f1==f2); //true
-
double 双精度浮点数
与float的区别是比float范围大,但系统运算要慢
-
char 字符串
可以表示中英文、数字、符号等所有文本
字符串的本质还是数字
Unicode编码格式,有个对应的编码表,用数字代表文本,如:97 = a ,最多可编65536字节,excel最长也是2^10 = 65536字节
char c3 = '\u0061'; //u代表转义
System.out.println(c3); //a
转义字符是以‘\’为开头的字符,后面跟一个或几个字符,其意思是将反斜杠‘\’后面的复字符转变成为另外的意义
\t 代表制表符Tab
\n 代表换行
\n其实应该叫回车换行。换行只是换一行,不改变光标的横坐标;回车只是回到行首,不改变光标的纵坐标。
容量级别
低------------------------------------------>高
byte,short,char-->int-->long-->float-->double
在把高容量转换到低容量的时候,要强制转换;反之会自动转换
- 强制转换语法:数值前加:(类型)
int i = 128;
byte b = (byte)i; //强制转换 内存溢出了
- 自动转换,直接转换即可
int a = 1;
long b = (long)a;
操作比较大的数值时,注意溢出问题,解决方案是在运算之前进行转换
//操作比较大的数值时,注意溢出问题
//JDK7数字之间可以用下划线分割
int money = 10_0000_0000;
int year = 365;
int year_money = money*year;
System.out.println(year_money);
long long_y_m = money*year;
System.out.println(long_y_m); //默认是int,转换之前已经存在了问题
long long_y_m_exchange = money*(long)year; //运算之前先进行转换即可
System.out.println(long_y_m_exchange);
总结注意点:
- 1.不能对布尔值进行转换
- 2.不能把对象类型转换为不相干的类型
- 3.在把高容量转换到低容量的时候,要强制转换;反之会自动转换
- 4.转换的时候可能存在内存溢出,或者精度问题
变量类型 变量名 = 值;
如:
int a = 1;
String b = "Hello World";
-
变量的作用域
变量的作用域分为:
- 类变量
- 实例变量
- 局部变量
类变量
变量前边加static,方法中的类可以直接用。
局部变量
存在于方法里,必须声明初始化值,否则不能输出,只在当前的方法里起作用,在其他方法里不能被输出。
实例变量
在方法的外面,类的里面。
从属于对象。
如果不进行初始化,值会变成这个类型的默认值(如数字是0、0.00,布尔是false,除了基本类型,其余默认值都是null)
类里边的方法不能直接用(有类A,实例变量a,A类有方法B,方法B里不能直接使用变量a)
public class Demo4 {
double age = 20; //实例变量,类的里面,方法的外面
String sex = "女";
double shoesNumber = 35;
static int a = 99; //类变量,static修饰,方法中可以直接用
static final double PI = 3.14; //静态变量,修饰符static和final先后顺序无要求
public static void main(String[] args) {
int part_a = 99; //局部变量,存在于方法里
System.out.println(Demo4.a); //方法中可以直接用类变量a
Demo4 demo4 = new Demo4(); //实例化Demo4
System.out.println(demo4.sex); //实例化后可使用实例变量
}
}
final 常量名 = 值;
finall PI = 3.14;
1. 算数运算符 + -*/% ++ –
加 减 乘 除 模运算 + - * / %
//二元运算符(需要两个以上的数运算)
int a = 10;
int b = 10;
int c = 10;
int d = 7;
System.out.println(a+b);
System.out.println(a-b);
System.out.println(a*b);
System.out.println(a/b);
System.out.println(a%d); //取余,模运算
自增自减运算符
++在前,先算后赋,++在后,先赋后算
//一元运算符
int a = 10; //a的初始值为10
int a1 = a++; //a++ : a = a +1 执行完这行代码后,先给a1赋值,a再自增
System.out.println(a); //此时a经过自增运算,已经变成了11
int a2 = ++a; //++a : a = a +1 执行完这行代码后,a先自增,再把值给a2
System.out.println(a);
System.out.println(a1);
System.out.println(a2);
幂运算,使用工具类来操作
Math提供了甚多计算方法
//幂运算2^3 2*2*2 = 8
double pow = Math.pow(2,3);
System.out.println(pow);
2. 赋值运算符 =
赋值运算符
运算符 | 说明 | 示例 |
---|---|---|
= | 简单的赋值运算符,将右操作数的值赋给左侧操作数 | C = A + B将把A + B得到的值赋给C |
+= | 加和赋值操作符,它把左操作数和右操作数相加赋值给左操作数 | C + = A等价于C = C + A |
-= | 减和赋值操作符,它把左操作数和右操作数相减赋值给左操作数 | C - = A等价于C = C - A |
*= | 乘和赋值操作符,它把左操作数和右操作数相乘赋值给左操作数 | C * = A等价于C = C * A |
/ = | 除和赋值操作符,它把左操作数和右操作数相除赋值给左操作数 | C / = A等价于C = C / A |
(%)= | 取模和赋值操作符,它把左操作数和右操作数取模后赋值给左操作数 | C%= A等价于C = C%A |
3. **关系运算符 > < >= <= == != **
关系运算符返回的结果:正确或者错误,为布尔值
int e = 10;
int f = 20;
System.out.println(e>f);
System.out.println(e<f);
System.out.println(e==f);
System.out.println(e!=f);
4. 逻辑运算符 && || !
与或非
//与(and) 或(or) 非(取反)
boolean a = true;
boolean b = false;
System.out.println("a && b:"+(a&&b)); //逻辑与运算,两个变量都为真,结果才为真
System.out.println("a || b:"+(a||b)); //逻辑或运算,两个变量有一个为真,则结果才为真
System.out.println("!a || b:"+!(a||b)); //取反 如果是真则为假,如果是假则为真
//短路运算 与运算中,第一个变量为假,后面不再执行
System.out.println("a && b:"+(b&&a)); //不会走到a
int c = 5;
boolean d = (c<4)&&(c++<4);
System.out.println(c); //c还是等于5,并没有执行c++
System.out.println(d);
位运算符
跟二进制有关的,一位一位的进行逻辑运算(不常用)
深入研究需要了解计算机的组成原理
二进制是0和1组成的:
二进制表示 | 对应十进制的数字 |
---|---|
0000 0000 | 0 |
0000 0001 | 1 |
0000 0010 | 2 |
0000 0011 | 3 |
0000 0100 | 4 |
0000 1000 | 8 |
0001 0000 | 16 |
运算符 | 说明 | 示例 |
---|---|---|
& | 与运算 | 按为做对比,都为1则为1,有一个不为1则为0 |
| | 与运算 | 其中有1则为1,都为0则为0 |
^ | 抑或运算 |
条件运算符 ?:
三元运算符,用来偷懒的,必须需要掌握
//三元运算符
// x ? y : z
//如果x==true,则结果为y,否则结果为z
int score =80;
String type = score >=60?"及格":"不及格"; //偷懒写法,必须要掌握
System.out.println(type);
三元运算符
扩展赋值运算符
用来偷懒的,新手不建议用
int a = 10;
int b = 20;
a+=b; //a = a + b;
a-=b; //a = a - b;
System.out.println(a);
本节拓展
字符串连接符 +
字符串连接,只要有字符串连接,字符串后面其他数值也按字符串连接,不做计算
int a = 10;
int b = 20;
System.out.println(""+a+b); // 字符串后面的数值按字符串连接
System.out.println(a+b+""); // 字符串前面的数值正常运算
System.out.println(""+(a+b)); // 如果字符串后面要接数值运算,把数值运算括起来
为了更好的组织类,Java提供了包机制,用于区别类名的命名空间
包的本质就是文件夹
一般利用公司域名倒置作为包名
以百度为例:
如果需要使用别人的包,需要导入包
import java.util.Date;
package必须放在代码的最上面
package XXX
public class XXX{
public static void main(String[] args){
}
}
package必须放在代码的最上面
package引用的class名不能和当前的class名一样
javadoc命令是用来生成自己API文档的
API(Application Programming Interface,应用程序接口)
加在类上面,就是类注释;加在方法上面,就是方法注释
参数信息 | 参数含义 |
---|---|
@author | 作者名 |
@version | 版本号 |
@since | 指明需要最早使用的jdk版本 |
@param | 参数名 |
@return | 返回值情况 |
@throws | 异常抛出情况 |
package com.base;
import com.base.*;
/**
* @author libingchen
* @version 1.0
* @since 1.8
*/
public class Demo10 {
String name;
/**
*
* @param name
* @return
* @throws Exception
*/
public String test(String name) throws Exception{
return name;
}
}
Scanner可以实现基本的人机交互,Scanner类是Java提供的工具类,可以获取用户的输入。
java.util.Scanner是Java5的新特性。
基本语法:
Scanner s = new Scanner(System.in);
通过Scanner类中next()与nextLine()方法获取输入字符串。
在获取用户输入前,使用hasNext()与hasNextLine()判断是否有输入的数据。
public static void main(String[] args) {
//创建一个扫描对象,用于接收键盘数据
Scanner scanner = new Scanner(System.in);
System.out.println("使用next方式接收:");
//判断用户有没有输入字符串,如果输入了字符串,则打印
if (scanner.hasNext()){
String str = scanner.next();
System.out.println("输出的内容为:"+str);
}
//凡是属于IO流的类如果不关闭会一直占用资源,要养成好习惯用完就关掉
scanner.close();
}
以上重点:使用next()输入,前面的空格和回车不算做输入,直到有字符串才算做输入,字符串后面有空格,则空格后面的输入,不算做输入;用nextLine()输入,前面的空格和回车不算做输入,直到有字符串才算做输入,字符串后面有空格也算做输入,直到敲回车,才输入完成。
总结:
- nextxxx()是获取输入的字符。
- hasNextxxx()是判断输入的字符是否符合类型,结果是布尔类型。
public static void main(String[] args) {
//输入多个数字,输出总和与平均数,每输入回车确认,通过非数字结束执行结果
System.out.println("请输入要运算的数字:");
Scanner scanner = new Scanner(System.in);
int no =0;
double sum = 0;
while (scanner.hasNextDouble()){
double x = scanner.nextDouble();
sum = sum + x;
no++;
System.out.println("你输入了第"+no+"个数字,当前的总和为:"+sum);
}
System.out.println("输入的数字之和为:"+sum);
System.out.println("数字的平均值为:"+(sum/no));
scanner.close();
}
Java中最基本的结构
一行一行,从上到下,依次执行
public static void main(String[] args) {
System.out.println("我是第一行");
System.out.println("我是第二行");
System.out.println("我是第三行");
System.out.println("我是第四行");
System.out.println("我是第五行");
}
if单选结构
if(布尔表达式){
//如果布尔表达式为true将执行的语句
}
代码示例:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入内容:");
String userInput = scanner.nextLine();
//equals:判断字符串是否相等
if(userInput.equals("Hello")){
System.out.println(userInput);
}
System.out.println("End");
scanner.close();
}
if(布尔表达式){
//如果布尔表达式为true将执行的语句
}else{
//如果布尔表达式值为false将执行的语句
}
代码示例:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入成绩(0 - 100):");
if(scanner.hasNextInt()) {
int score_input = scanner.nextInt();
if (score_input<60){
System.out.println("成绩不及格!");
}else(score_input>=60){
System.out.println("成绩及格了!");
}
}else{
System.out.println("必须输入整数!");
}
}
if(布尔表达式1){
//如果布尔表达式1为true将执行的语句
}else if(布尔表达式2){
//如果布尔表达式2值为true将执行的语句
}else if(布尔表达式3){
//如果布尔表达式3值为true将执行的语句
}
代码示例:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入成绩(0 - 100):");
if(scanner.hasNextInt()) {
int score_input = scanner.nextInt();
if (score_input<60){
System.out.println("成绩不及格!");
}else if (score_input>=60 && score_input <80){
System.out.println("成绩及格了!但没有优秀");
}else if(score_input>80 && score_input<=100 ){
System.out.println("成绩不仅及格了,还达到了优秀!!!");
}else if (score_input>0 || score_input<100){
System.out.println("成绩输入不符合规范!");
}
}else{
System.out.println("必须输入整数!");
}
}
注意点:
-
if语句至多只能有一个else语句,else语句再所有else if 语句之后
-
if语句中 else if 语句数量不限,它们必须在 else 语句之前
-
一旦其中一个 else if 语句检测为 true ,其他的else if 以及 else 语句都将跳过执行!
-
if嵌套结构
语法:
if(布尔表达式1){
//如果布尔表达式1为true将执行的语句
else(布尔表达式2){
//如果布尔表达式2值为true将执行的语句
}
}
代码示例见if多选结构
-
switch多选结构
- 多选择结构还有另外一个实现方式,就是switch case语句。
- switch case 语句判断一个变量与一系列值中某个值是否相等,每一个值成为一个分支。
- switch 语句中的变量类型可以是:byte、short、int 或者是char,从Java SE 7开始,支持字符串String类型了。
- case标签必须为字符串常量或字面量。
switch(expression){
case value :
//语句
break: //可选
case value :
//语句
break: //可选
//可以有任意数量的case语句
default : //可选
//语句
}
代码示例:
public static void main(String[] args) {
char grade = '0';
switch(grade){
case 'A':
System.out.println("优秀");
break;//如果符合上面的条件并执行完符合条件的语句后,没加break,则后面的语句不会判断全部都执行,这就是case穿透
case 'B':
System.out.println("良好");
break;
case 'C':
System.out.println("一般");
break;
case 'D':
System.out.println("不及格");
break;
default:
System.out.println("未知等级");
}
}
JDK 7 的新特性,表达式结果可以是字符串:
public static void main(String[] args) {
String name = "123";
//JDK 7 的新特性,表达式结果可以是字符串!
//字符的本质还是数字
//反编译:java编译后-->class(字节码文件),将class文件编译回java代码,idea即可反编译
switch(name){
case "秦江":
System.out.println("秦江");
break;
case "李二狗":
System.out.println("李二狗");
break;
default:
System.out.println("弄啥嘞?");
}
}
-
补充知识点:Java反编译
- java编译后—>class(字节码文件),将class文件编译回Java代码,即是 反编译
- IDEA即可简单的对class文件进行反编译,步骤如下:
通过查看反编译后的源码可见,switch在对字符串做对比的时候,实际上是用字符串的哈希值做对比,并且在对比后用if语句又加了一层equals对比保证字符串对比的准确性,实现方式也是先用第一个switch对字符串做对比,对比后对系统定义的变量(var3)赋值,第二个switch语句通过判断系统定义的变量(var3)来执行原switch判断相等后要执行的语句。
平时要养成看源码的习惯,能够更深入的理解Java语言,能够找到更高效的方法解决问题,能够深入的体会到设计模式、数据结构和算法。 一个好的开发一定有优秀的思想,看源码就是核心的思想。
-
For循环
- for循环语句是支持迭代的一种通用结构,是最有效、最灵活的循环结构。
- for循环执行的次数是在执行前就确定的。
- 最先执行的初始化步骤,一般声明一种类型,也可以初始化一个或多个循环控制变量,也可以是空语句。
- 布尔表达式的值,如果为true,循环体被执行,如果为false,循环终止。
- 执行一次循环后,更新循环控制变量,再次检测布尔表达式的值,继续上一步骤。
for(初始化;布尔表达式;更新){
//代码语句
}
循环示例1:
public static void main(String[] args) {
int main_no = 2;
int son_no = 2;
int grandson_no =10;
for (int a=0;a<main_no;a++){
System.out.println("<main></main>");
for(int b=0;b<son_no;b++){
System.out.println("\t<son></son>");
for(int c=0;c<grandson_no;c++){
System.out.println("\t\t<child></child>");
}
}
}
代码示例1:计算0到100之间所有奇数和偶数的和
public static void main(String[] args) {
int sum_single = 0;
int sum_double = 0;
for (int i = 0; i <= 100; i++) {
if(i%2==1){
sum_single = sum_single + i;
}else{
sum_double = sum_double + i;
}
}
System.out.println("基数和:"+sum_single);
System.out.println("偶数和:"+sum_double);
}
代码示例2:循环输出1-1000之间能被5整除的数,每行输出3个
public static void main(String[] args) {
//循环输出1-1000之间能被5整除的数,每行输出3个
for (int i = 1; i <= 1000; i++) {
if (i%5==0){
System.out.print(i+"\t");
}
if (i%(5*3)==0){
System.out.println();
}
//println 输出完会换行
//print 输出完不会换行
}
}
代码示例3:打印九九乘法表
public static void main(String[] args) {
//打印九九乘法表
for (int i = 1; i <= 9; i++) {
for (int i1 = 1; i1 <= i; i1++) {
System.out.print(i1+"*"+i+"="+(i1*i)+"\t");
//这里没必要单加判断,因为i和i1相等之后,里边的循环执行执行到最后一次了,再执行就继续往下执行了(外面循环),此时在外面循环中,里面循环的下面,sout就可以了
//if (i==i1){
// System.out.println();
//}
}
System.out.println();
}
}
-
增强for循环
- Java 5 引入了一种主要用于数组或集合的增强型for循环。
- 声明语句:声明新的局部变量,该变量的类型必须和数组元素的类型匹配。其作用域限定在循环语句块,其值与此事数组元素的值相等。
- 表达式:表达式是要访问的数组名,或者是返回值为数组的方法。
for(声明语句:表达式){
//代码句子
}
代码示例:
public static void main(String[] args) {
int[] number = {10,20,30,40,50};//定义了一个数组
for (int i = 0; i < 5; i++) {
System.out.println(number[i]);
}
for (int x:number){ //等同于上面的写法
System.out.println(x);
}
}
- 其实这是个数组遍历的方法,是一个简化的写法
-
break
- break用在任何循环语句的主体部分,作用是强制退出当前循环,也不会有执行循环中的剩余语句
- break语句也在switch语句中使用
-
continue
- continue只用在循环语句中,用于终止当前的循环,跳过循环体中未执行的语句,接着进行下一次循环
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
if(i>2){
break;
}
System.out.println(i);
}
System.out.println("============================");
for (int i1 = 0; i1 < 5; i1++) {
if(i1==2){
continue;
}
System.out.println(i1);
}
}
-
goto(不需要掌握)
- goto关键字很早就在程序设计语言中出现,尽管是Java中的一个保留字,但并没有在Java中得到正式使用
- 在break和continue两个关键字身上,我们仍然能看出一些沟通的影子—>带标签的break和continue
- 标签是指后面跟一个冒号的标识符,例如:label:
public static void main(String[] args) {
//打印101到150之间所有的质数
//质数:只能被1和自身整除的数
label:for (int i = 101; i < 151; i++) {
for (int i1 = 2; i1 < i; i1++) {
if (i%i1 ==0){ //如果取模为0,则说明这个数不是质数,直接从最开始继续循环
continue label;
}
}
System.out.print(i+"\t");
}
}
-
什么是方法?
- Java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段
- 方法是语句的集合,他们在一起执行一个功能
- 方法是解决一类问题的步骤的有序的组合
- 方法包含于类的对象中
- 方法在程序中被创建,在其他地方被调用
-
设计方法的原则
- 一个方法只做一个功能,有利于后期的扩展(方法的原子性)
- main方法要时刻保持简介干净
-
方法的组成
- 方法包含一个方法头和一个方法体
- 修饰符:可选,告诉编译器如何调用该方法,定义了该方法的访问类型
- 返回值类型:方法可能会返回值,returnValueType是方法返回值数据类型,如果没有返回值,returnValueType是关键字void
- 方法名:方法的实际名称。方法名和参数表共同构成方法签名 (用驼峰命名规范)
- 参数类型:方法被调用时,传递值给参数,这个值被称为实参或变量,参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。
- 形式参数:方法被调用时用户接收外界输入的数据。
形参 顾名思义:就是形式参数,用于定义方法的时候使用的参数,是用来接收调用者传递的参数的。形参只有在方法被调用的时候,虚拟机才会分配内存单元,在方法调用结束之后便会释放所分配的内存单元。因此,形参只在方法内部有效,所以针对引用对象的改动也无法影响到方法外。
- 实参:调用方法实际传给方法的数据。
实参 顾名思义:就是实际参数,用于调用时传递给方法的参数。实参在传递给别的方法之前是要被预先赋值的。
- 方法体:方法体包含具体的语句,定义该方法的功能。
修饰符 返回值类型 方法名(参数类型 参数名){
方法体
return 返回值;
}
public static void main(String[] args) {
int sum = add(1,2); //1 和 2 是调用方法实际传递的参数,叫实参
System.out.println(sum);
}
//a 和 b 是定义方法的占位符,为形参,用来做定义作用的
public static int add(int a,int b){
return a+b;
}
-
方法的调用
- 调用方法:对象名.方法名(实参列表)
- Java支持两种嗲用方法的方式,根据方法是否返回值来选择。
- 当方法返回一个值的时候,方法调用通常被当做一个值。例如:
- 如果方法返回值是void,方法嗲用一定是一条语句
static关键字
在类中,用static声明的成员变量为静态成员变量,也c称为类变量。类变量的生命周期和类相同,在整个应用程序执行期间都有效。
- static修饰的成员变量和方法,从属于类
- 普通变量和方法从属于对象
- 静态方法不能调用非静态成员,编译会报错
- 用static修饰的方法不叫类方法,叫静态方法
static关键字的用途
一句话描述就是:方便在没有创建对象的情况下进行调用(方法/变量)。
显然,被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问。
static可以用来修饰类的成员方法、类的成员变量,另外也可以编写static代码块来优化程序性能
static方法
static方法也成为静态方法,由于静态方法不依赖于任何对象就可以直接访问,因此对于静态方法来说,是没有this的,因为不依附于任何对象,既然都没有对象,就谈不上this了,并且由于此特性,在静态方法中不能访问类的非静态成员变量和非静态方法,因为非静态成员变量和非静态方法都必须依赖于具体的对象才能被调用。
虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法和静态成员变量。
重载就是在一个类中,有相同的函数名称,但形参不同的函数。
方法重载的规则:
- 方法名必须相同
- 参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)
- 方法的返回类型可以相同也可以不相同
- 仅仅返回类型不同不足以成为方法的重载
实现理论: - 方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错。
public static void main(String[] args) {
System.out.println(add(1,2));
System.out.println(add(1.0,3));
System.out.println(add(1,2,3));
}
public static String add(int a,int b){
return String.valueOf(a+b);
}
public static String add(double a,double b){
return String.valueOf(a+b);
}
public static String add(int a,int b,int c){
return String.valueOf(a+b+c);
}
-
可变参数
- JDK1.5开始,java支持传递同类型的可变参数给方法。
- 在方法声明中,在指定参数类型后加一个省略号(…)
- 一个方法只能指定一个可变参数,它必须是方法的最后一个参数。任何非可变参数必须在它之前声明
public static void main(String[] args) {
Demo05 demo05 = new Demo05();
System.out.println(demo05.choseMax(1,2,3,4,5,6,7,8,9));
}
public double choseMax(double... i) {
if (i.length == 0) {
System.out.println("没有指定参数");
}
double result = i[0];
for (int i1 = 0; i1 < i.length; i1++) {
if (result < i[i1]) {
result = i[i1];
}
}
return result;
}
小结:其实方法中形参的可变参数就是数组。
//计算n*n-1...1
public static void main(String[] args) {
System.out.println(f(5));
}
public static int f(int n){
if (n == 1){
return 1;
}else{
return n*f(n-1);
}
}
- 递归包括递归头和递归体
- 递归头:什么时候不调用自身方法f(1)。如果没有头,将陷入死循环。
- 递归体:什么时候需要调用自身方法。
- 递归会占用大量的栈内存,如果调用太多了,会影响性能内存溢出,所以不建议使用
- 递归是一种思想,基数较少的时候可以使用,基数较大是,不要用递归,换其他方法实现
- 在解决问题的时候,可以想办法用递归解决,但要考虑递归是不是最好的思路,如果调用太多了,反而会影响机器的性能