第2章 - Java语言基础
作者:vwFisher
时间:2019-09-02
GitHub代码:https://github.com/vwFisher/JavaBasicGuide
目录
- 1.Java语言基础
- 1.1 标识符
- 1.2 关键字
- 1.3 注释
- 1.3.1 文档注释
- 1.4 基础数据类型
- 1.4.1 Java的8中基本数据类型
- 1.4.2 转义字符表
- 1.4.3 基本数据类型对象包装类
- 1.4.4 使用标准方法测试字符
- 1.4.5 BigDecimal
- 1.4.5.1 BigDecimal 的大小比较
- 1.4.5.2 BigDecimal 保留几位小数
- 1.5 常量和变量
- 1.5.1 常量
- 1.5.2 变量
- 1.5.3 变量的有效范围
- 1.6 运算符
- 1.6.1 运算符(6个)说明
- 1.6.2 运算符的优先级
- 1.6.3 原码, 补码, 反码
- 1.6.4
>>
和>>>
的区别
- 1.7 类型转换
- 1.7.1 自动类型转换(隐式类型转换)
- 1.7.2 强制类型转换(显式类型转换)
- 1.8 题目
- 2 流程控制
- 2.1 条件语句
- 2.2 switch多分支语句
- 2.3 循环语句
- 2.4 foreach语句
- 2.5 流程控制语句
- 2.6 题目
- 3 函数
- 3.1 什么是函数
- 3.2 函数的格式
- 3.3 函数的特点
- 3.4 函数的重载
- 3.5 基本数据类型参数传递 和 引用数据类型参数传递
- 3.6 递归的使用
- 4 获取用键盘输入常用的两种方法
- 方法1:通过 Scanner
- 方法2:通过 BufferedReader
1.Java语言基础
标识符, 关键字, 注释, 常亮和变量, 运算符, 语句, 函数, 数组
1.1 标识符
概念: 用来标识类名、变量名、方法名、数组名、文件名的有效字符序列
命名规则:
- 由26个英文字母大小写, 数字: 0-9, 符号:_$组成
- 合法标识符规则: {1}.数字不可以开头, 如7word。{2}.不可以使用关键字, 如this, goto
- Java中严格区分大小写, 例如good和Good就是两个不同的标识符
- Java语言使用Unicode标准字符集, 最多可以识别65535个字符. 因此Java语言中的字母可以是Unicode字符集中的任何字符, 包括拉丁字母、汉子、日文和其他许多语言中的字符
- 在定义标识符时, 为了提高阅读性, 要尽量有意义
1.2 关键字
定义: 被Java语言赋予了特殊含义的单词。
特点: 关键字中所有字母都为小写
- 定义数据类型:boolean,byte,char,short,int,long,float,double
- 定义数据类型值:true,false,null
- 定义流程控制:if,else,switch,case,default,do,while,for,brak,continue,return
- 定义访问权限修饰符:public,private,properted
- 定义类,函数,变量修饰符的关键字:abstract,final,static,class,interface
- 定义类与类关系:extends,implements
- 建立实例和引用实例:new,this。super,instanceof
- 异常:try,catch,finally,throw,throws
- 包:package,import
- 其他修饰关键字:synchronized,native,strictfp,transient,volatile,assert
- 保留关键字(未被使用):goto,const
1.3 注释
单行注释: // 注释文字
多行注释: /* 注释文字 */
文档注释: /** 注释文字*/
1.3.1 文档注释
文档注释(documentation comment)
是为程序生成单独的文档。javadoc的程序在为程序处理源代码中的文档注释,从而为代码生成HTML网页形式的单独文档。从SDK中得到的所有文档都是这样产生的。代码中用于在标准表格中记录方法和类的以@开头的特殊标签。@字符会跟有一个关键字,从而定义标签的目的。如下表展示一些可以使用且常用的关键字。
@author:用于定义代码的作者。例如, 可以通过添加如下标签来指定作者:
/**
* @author vwFisher
*/
@deprecated:标识类库中废弃/过时的方法, 指示已经替换它们并且不应该在新的应用程序中使用。
@exception:用来记录代码可能抛出的异常以及可能导致这种情况发生的条件。例如, 可以将如下文档注释添加到一个方法的定义之前, 从而指示该方法可能抛出的异常类型
/**
* @exception IOException When an I/O error occurs.
*/
{@link}:生成到所生成文档中另一部分文档的链接。可以使用这个标签在代码的描述文本中插入到另一个类或方法的链接。花括号用来分离链接和其他的文本
@param:用来描述一个方法的参数
@return:用来记录从一个方法返回的值
@see:用来设定到另一个类或方法的其他部分代码的交叉引用。还可以引用一个URL。也可以只设定一个代表外部引用的字符串, 不识别为URL,例如:
/**
* @see Object#clone()
* @see "Beginning Java 7"
*/
@throws:@exception的同义词
@version:用来描述代码的当前版本
@since:从什么版本开始
除之之外, 可以使用任何HTML标签. 在浏览文档时, 会用插入的HTML标签来对文档进行构建和格式化, 而且javadoc会添加HTML标签, 对包含表中提到的特殊@标签的注释进行格式化.
1.4 基础数据类型
1.4.1 Java的8个基本数据类型
(basic.javabasic.basictype.BasicDataType)
在Java中有8种基本数据类型, 其中6种是数值类型, 另外2种分别是字符类型和布尔类型
Java语言是强类型语言,对于每一种数据都定义了明确的具体数据类型,在内存中分配了不同大小的内存空间
注意:
1.注意数据溢出产生的错误问题
2.long: 在赋值结尾需要加上'L'或'l', 否则将不认为是long类型
3.float: 赋值结尾必须添加'F'或'f', 否则, 系统将其定义为double型变量
4.double: 赋值建议结尾添加'D'或'd', 但没有硬性规定
5.所有的浮点运算以及类型float和double的定义都遵循IEEE 754标准
6.char
用于存储单个字符,系统分配两个字节的内存空间(汉字会赋予2字节,而字母和数字赋予1字节)。在定义字符型变量,要用单引号括起来(例如:'a'表示一个字符,并且只有有一个字符), 还可以char x = 97
在Unicode表中97对应的就是'a',即'a': 97,'A': 65,小写=大写+32
char c1 = '无'; // 汉子占2byte
char c2 = 'a'; // 字母占1byte
System.out.println(Integer.toBinaryString(c1));
// 110010111100000
System.out.println(Integer.toBinaryString(c2));
// 1100001
7.特殊字符
字符类型中有一种特殊的字符, 以反斜线''开头, 后跟一个或多个字符, 具有特定含义, 不同于字符原有的意义, 叫做转义字符
8.对于整数: 有四种表达形式
- 二进制: 0,1, 满2进1
- 八进制: 0-7, 满8进1, 用0开头表示
- 十进制: 0-9, 满10进1
- 十六进制: 0-9、A-F, 满16进1, 用0x开头表示
System.out.println(Integer.toBinaryString(12)); // 2进制, 1100
System.out.println(Integer.toOctalString(12)); // 8进制, 14
System.out.println(Integer.toHexString(12)); // 16进制, c
9.1byte(字节) = 8个二进制位(8bit)(比特)
计算机内容全部以二进制位保存:1KB=1024Byte, 1MB=1024KB, 1GB = 1024MB
10.关于TCP通讯常用16进制的byte传输数据时的转换方式
byte b1 = (byte) 0xAA;
System.out.println("Int型=" + (b1 & 0xff));
System.out.println("-----倒序-----");
int i2 = 0x01020304;
byte[] b3 = new byte[] {
(byte) (i2 & 0xFF),
(byte) ((i2 >> 8) & 0xFF),
(byte) ((i2 >> 16) & 0xFF),
(byte) ((i2 >> 24) & 0xFF)
};
for (byte b : b3) {
System.out.print(b + ",");
}
对应整型数据在计算机内部都是作为二进制数存储的。最左边是符号位,用一个s标记。当符号位为0时该数为正数,为1时该数为负。负的二进制数用所谓的补码形式来表示。
- byte:10000000 ~ 01111111 (-128 ~ 127)
- short:1000000000000000 ~ 0111111111111111 (-65536 ~ 65535)
- int,long同理
数据类型 | 内存空间(8位等于1字节) | 取值范围 |
---|---|---|
byte | 8位(1字节) | -128 ~ 127(2^8) |
short | 16位(2字节) | -32768 ~ 32767(2^16) |
int | 32位(4字节) | -2147483648 ~ 2147483647(2^32) |
long | 64位(8字节) | -9223372036854775808 ~ 9223372036854775807(2^64) |
float | 32位(4字节), 有效小数位6~7位 [1bit(符号位), 8bits(指数位), 23bits(尾数位)] |
-3.4E38(-3.4 * 1038) ~ +3.4E38(+3.4 * 1038) |
double | 64位(8字节) , 有效小数位15位 [1bit(符号位), 11bits(指数位), 52bits(尾数位)] |
-1.7E308(-1.7 * 10308) ~ +1.7E308(+1.7 * 10308) |
char | 16位(2字节), 字节占1字节,汉字2字节 | 0 ~ 65536 之间的Unicode表对应字节 |
boolean | 2位(1字节), 只有1位有效 | true, false(通常用于判断条件) |
1.4.2 转义字符表
转义字符 含义
\ddd 1~3位八进制数所表示的字符, 如\456
\' 单引号字符
\r 回车
\uxxxx 4位十六进制所标的字符, 如\0052
\" 双引号字符
\b 退格
\t 垂直制表符, 将光标移动下一个制表符的位置
\\ 反斜杠字符
\f 换页
\n 换行。回车符:windows系统由两个符号组成的 \r\n;linux中回车符是 \n
1.4.3 基本数据类型对象包装类
(basic.javabasic.basictype.PackageDataType)
为了方便操作基本数据类型值, 将其封装成对象(基本数据类型对象包装类), 在对象中定义了属性和行为丰富了该数据的操作。包装对象主要用基本类型和字符串之间的转换,基本类型与包装类之间的转换。
- 基础类型默认值:整数: 0, 小数: 0.0或0.0f, boolean: false, char '\u0000'
- 对象包装类型默认为null
基本数据类型 | byte | short | int | long | float | double | char | boolean |
---|---|---|---|---|---|---|---|---|
对象包装类型 | Byte | Short | Integer | Long | Float | Double | Character | Boolean |
1.基本类型 ==> 字符串
- 基本类型数值+""
- 用String类中的静态方法valueOf(基本类型数值);
- 用Integer的静态方法valueOf(基本类型数值);
- String.format("%s", 基本类型数值);
2.字符串 ==> 基本类型
使用包装类中的静态方法,如xxx.parseXxx("xxx类型的字符串");
1.整型: 若str不是整型数据, 带有小数点或字母, 会报错。
public static byte parseByte(String s)
public static short parseShort(String s)
public static int parseInt(String s)
public static long parseLong(String s)
2.浮点型: 如果str带有字母, 会报错
3.字节型: Character没有parse方法
4.布尔型: 除了true转换为true, 其他都转为false
public static boolean parseBoolean(String s) {
return ((s != null) && s.equalsIgnoreCase("true"));
}
3.基本类型 <==> 包装类型
Byte byte1 = 127;
Short short1 = 32767;
Integer int1 = 2147483647; // jdk1.5以后, 自动装箱, 如果装箱的是一个字节,那么该数据会被共享不会重新开辟空间
Long long1 = 9223372036854775807L;
Float float1 = 3.4028235E-38F;
Double double1 = 1.7976931348623157E-308;
Character char1 = 'a';
Boolean boolean1 = true;
/** 包装类和类型类的转换,可使用另一个非静态的方法xxxValue(); */
byte byte2 = byte1.byteValue();
Byte byte3 = Byte.valueOf(byte2);
short short2 = short1.shortValue();
Short short3 = Short.valueOf(short2);
int int2 = int1.intValue();
Integer int3 = Integer.valueOf(int2);
long long2 = long1.longValue();
Long long3 = Long.valueOf(long2);
float float2 = float1.floatValue();
Float float3 = Float.valueOf(float2);
double double2 = double1.doubleValue();
Double double3 = Double.valueOf(double2);
boolean boolean2 = boolean1.booleanValue();
Boolean boolean3 = Boolean.valueOf(boolean2);
char char2 = char1.charValue();
Character char3 = Character.valueOf(char2);
4.包装类型的 swap
public void swap(Integer a, Integer b) {
try {
Field field = Integer.class.getDeclaredField("value");
boolean accessibleFlag = field.isAccessible();
field.setAccessible(true);
field.setInt(a, a ^ b);
field.setInt(b, a ^ b);
field.setInt(a, a ^ b);
field.setAccessible(accessibleFlag);
} catch (Exception e) {
e.printStackTrace();
}
}
5.自动装箱与拆箱
- 装箱:将基本类型用它们对应的引用类型包装起来;
- 拆箱:将包装类型转换为基本数据类型;
1.4.4 使用标准方法测试字符
Character提供测试字符的方法, 如下表
方法 | 描述 |
---|---|
isLowerCase | 判断是否小写 |
isUpperCase | 判断是否大写 |
isDigit | 判断是否是数字(0~9) |
isLetter | 判断是否是一个字母(a~z 和 A~Z) |
isLetterOrDigit | 判断是否是一个字母或数字 |
isWhitespace | 如果参数是空自,返回true。空白可以是如下字符之一:空格(' ')、Tab制表符('\t')、换行('\n')回车('\r')、换页('\t') 否则返回 false |
1.4.5 BigDecimal
BigDecimal 主要用来操作(大)浮点数,BigInteger 主要用来操作大整数(超过 long 类型)
BigDecimal 的实现利用到了 BigInteger, 与之不同的是 BigDecimal 加入了小数位的概念
浮点数之间的等值判断,基本数据类型不能用==来比较,包装数据类型不能用 equals 来判断。具体原理和浮点数的编码方式有关
float a = 1.0f - 0.9f;
float b = 0.9f - 0.8f;
System.out.println(a); // 0.100000024
System.out.println(b); // 0.099999964
System.out.println(a == b); // false
具有基本数学知识的,清楚知道输出并不是我们想要的结果(精度丢失),我们如何解决这个问题呢?
一种很常用的方法是:使用使用 BigDecimal 来定义浮点数的值,再进行浮点数的运算操作。
// 可以用valueOf,BigDecimal a = BigDecimal.valueOf(1.0D);
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("0.9");
BigDecimal c = new BigDecimal("0.8");
BigDecimal x = a.subtract(b);// 0.1
BigDecimal y = b.subtract(c);// 0.1
System.out.println(x.equals(y));// true
为了防止精度丢失,推荐使用它的 BigDecimal(String) 构造方法来创建对象。优先用String参数,或者 valueOf,此方法内部 使用了 Double 的 toString。该方法实际能表达的精度对尾数进行了截断。
1.4.5.1 BigDecimal 的大小比较
a.compareTo(b):返回 -1 表示小于,0 表示 等于, 1表示 大于。
BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("0.9");
System.out.println(a.compareTo(b));// 1
1.4.5.2 BigDecimal 保留几位小数
通过 setScale方法设置保留几位小数以及保留规则。保留规则有挺多种,不需要记,IDEA会提示。
BigDecimal m = new BigDecimal("1.255433");
BigDecimal n = m.setScale(3,BigDecimal.ROUND_HALF_DOWN);
System.out.println(n);// 1.255
1.5 常量和变量
1.5.1 常量
(basic.javabasic.basictype.FinalDataDemo)
在程序运行过程中一直不会改变的量称为常量(final定义),常量在整个程序中只能被赋值一次
格式:final 数据类型 常量名称 [ = 值 ]
例子:
final double PI = 3.1415956F; // 声明double型变量PI
Java中常量的分类
- 整数常量: 所有整数(byte, short, int, long)
- 小数常量: 所有小数(float, double)
- 布尔(boolean)型常量: 较为特有, 只有两个数值, true和false
- 字符(char)常量: 将一个数字字母或符号用单引号('')标识
- 字符串(String)常量: 将一个或多个字符用双引号("")标识。不是基础数据类型之一, 是final类
- null常量: 只有一个数值就是: null
写法规范: 常量所有字母都大写, 多个单词, 中间用_连接
1.5.2 变量
(basic.javabasic.basictype.VariableData)
1.概念
- 内存中的一个存储区域(下图中的数据区)
- 该区域有自己的名称(变量名)和类型(数据类型)
- 该区域的数据可以在同一类型范围内不断变化(如同数学中的未知数)
2.为什么要定义变量?
- 用来不断的存放同一类型的常量, 并可以重复使用
- 告诉编译器(compiler)这个变量属于哪一种数据类型, 这样编译器才知道需要配置多少空间, 以及能存放什么样的数据
3.内存状态
系统的内存大略分为3个区域, 即系统区(OS)、程序区(Program)和数据区(Data)。当程序执行时, 程序代码会加到内存中的程序区, 数据暂时存储在数据区中.
4.定义变量的格式
数据类型 变量名 = 初始化值
5.命名规则
- 变量名必须是有效的标识符(变量名必须使用Java语言中合法的标识符, 即以字母、数字和下划线组成, 且首字母不能是数字, 不可以使用Java中的关键字)
- 变量名不能重复(如果两个变量具有同样的变量名, 系统运行时不知道调用哪个变量, 运行结果就是错的)
- 建议选择有意义的单词作为变量名
- Java允许使用语言文字定义变量, 但建议不要使用!
1.5.3 变量的有效范围
变量的有效范围是指程序代码能够访问该变量的区域, 若超出变量所在区域访问变量, 编译时会出现错误.
变量的作用范围
(一对{}之间有效, 程序会根据变量能够访问的区域将变量分为"成员变量"和"局部变量")
- 成员变量: 在类中定义的变量被称为成员变量, 在整个类中都有效, 类的成员变量又可分为静态变量(类变量, 关键字static)和实例变量两种
- 局部变量: 在类的方法体重定义的变量, 称为局部变量,只在方法体中有效
- 局部变量与成员变量名字相同时, 成员变量将被隐蔽, 如果要调用成员变量, 需要使用类名.静态变量
- 初始化值
1.6 运算符
(basic.javabasic.basictype.OperateDemo)
1.6.1 运算符(6个)说明
1.赋值运算符:=、+=、-=、*=、/=、%=、<<=、>>=、&=、^=、|=
2.算术运算符:+、-、*、/、%(取余,模运算)、+(连接符)、++、 --
运算符 说明 实例 结果
+ 加 12.45F + 15 31.45
- 减 4.56 – 0.16 4.4
* 乘 5L * 12.45F 62.25
/ 除 7 / 2 3
% 取余数(摸运算) 1 & 2 1
3.比较运算符:>、<、=、>=、<=、==、!=
, 运算结果为 true
或 false
运算符 作用(比较) 操作数据类型 实例
> 左边是否大于右方 整型,浮点型,字符型 'a'>'b' = false
< 左边是否小于右方 整型,浮点型,字符型 156<456 = false
== 左边是否等于右方 基本数据类型,引用型 'c'=='c' = true
>= 左边是否大于等于右方 整型,浮点型,字符型 479>=426 = true
<= 左边是否小于等于右方 整型,浮点型,字符型 12.45<=45 = false
!= 左边是否不等于右方 基本数据类型,引用型 'y'!='t' = true
4.逻辑运算符:位与: &、逻辑与: &&、位或: |、逻辑或: ||、非: ! 、异或: ^
运算符 含义 用法 结合方向
&&, & 逻辑与 op1 && op2 左到右
||, | 逻辑或 op1 || op2 左到右
! 逻辑非 !op1 右到左
使用逻辑运算符进行逻辑运算
op1 op2 op1 && op2 op1 || op2 !op1
true true true true false
true false false true false
false true false true true
false false false false true
&&和& / ||和| 运算的结果是一样的, 但是运算过程有点小区别
1). & / |: 无论左边的运算结果是什么, 右边都参与运算
2).&& / ||: 当左边为false/true时, 右边不参与运算的, 也称之为短路与/短路或
5.位运算符:<<、>>、>>>、&、|、^、~
运算符 含义 用法 运算分类
~ 按位取反 ~op1 按位运算
& 按位与 op1 & op2 按位运算
| 按位或 op1 | op2 按位运算
^ 按位异或 op1 ^ op2 按位运算
<< 左移 op1 << op2 移位运算符
>> 有符号右移 op1 >> op2 移位运算符
>>> 无符号右移 op1 >>> op2 移位运算符
6.三元运算符:条件 ? 结果1 : 结果2
,需要注意以下情况
1).0不可以做除数, 会报出ArithmeticException异常
2).>> 和 >>>看下面关于原码, 补码, 反码的讲解中有详细例子
3).^ (异或): 当2边结果不同时候为true。eg:true ^ false = true, true ^ true = false
4).不用其他变量来互换2个变量的值
int a = 3, b = 5;
a = a ^ b; // a = 3 ^ 5;
b = a ^ b; // b = (3^5)^5; b = 3;
a = a ^ b; // a = (3^5)^3; a = 5;
1.6.2 运算符的优先级
优先级 | 描述 | 运算符 | 结合性 | ||
---|---|---|---|---|---|
1 | 括号 | [], () |
从左向右 | ||
2 | 正负号(一元运算) | +, - |
从右向左 | ||
3 | 一元运算符 | ++, --, ! |
从左向右 | ||
4 | 乘除 | *, /, % |
从左向右 | ||
5 | 加减 | +, - |
从左向右 | ||
6 | 移位运算 | >>, >>>, << |
从左向右 | ||
7 | 比较 | >, <, >=, <=, instanceof |
从左向右 | ||
8 | 比较是否相等 | ==, != |
从左向右 | ||
9 | 按位与运算 | & |
从左向右 | ||
10 | 按位异或运算 | ^ |
从左向右 | ||
11 | 按位或运算 | ` | ` | 从左向右 | |
12 | 逻辑与运算 | && |
从左向右 | ||
13 | 逻辑或运算 | ` | ` | 从左向右 | |
14 | 三元运算符 | ? : |
从右向左 | ||
15 | 赋值运算符 | = |
从右向左 |
1.6.3 原码, 补码, 反码
1.原码: 符号位 + 数字的二进制表示,对于原码, 绝对值相等的正数和负数只有符号位不同
- 7: 0000 0111
- -7: 1000 0111
2.反码: 正数:反码与原码相同. 负数:符号位不变化, 其余位取反
- 7: 0000 0111
- -7: 1111 1000
3.补码: 正数:补码与原码相同. 负数:取反码+1(反码+1 = 补码)
- 7: 0000 0111
- -7: 1111 1001
总结:
- 正数: 原码, 反码, 补码相同
- 负数: 反码 = 原码取反(符号位不变), 补码 = 反码 + 1
1.6.4 >>
和 >>>
的区别
首先右移, 都是取补码, 然后进行右移, 右移后再去补码得会结果
>>
: 有符号右移, 如果原先符号位是1, 结果取补码
>>>
: 无符号右移, 结果一定是正数
进行右移 >>
操作:
1).33 >> 5: 补码 00000000 00000000 00000000 00100001
右移5位 00000000 00000000 00000000 00000001
因为33为正数, 再取补码为 00000000 00000000 00000000 00000001
转为十进制为1 即33>>5=1
2).-33 >> 5: 补码 11111111 11111111 1111111 11011111
右移5位 11111111 11111111 11111111 11111110
因为-33为负数,再取补码为 00000000 0000000 0000000 00000010
最前一位1为符号位 转为十进制为-2 即-33>>5=-2
进行无符号右移>>>操作
1).33 >>> 5: 补码 00000000 00000000 00000000 00100001
右移5位 00000000 00000000 00000000 00000001
因为无符号位, 代表结果肯定为正数,正数取补码为本身 00000000 00000000 00000000 00000001
转为十进制为1 即33>>>5=1
2).-33 >>> 5: 补码 11111111 11111111 1111111 11011111
右移5位 00000111 11111111 11111111 11111110
因为无符号位, 代表结果肯定为正数,正数取补码为本身 00000111 11111111 11111111 11111110
转为十进制为134217726 即-33>>>5=134217726
1.7 类型转换
(basic.javabasic.basictype.ConverDemo)
1.7.1 自动类型转换(隐式类型转换)
表达式的数据类型自动提升(隐式类型转换规则), 低级到高级转换
- 所有的byte型, short型和char型的值将被提升到int型
- 如果一个操作数是long型, 计算结果就是long型
- 如果一个操作数是float型, 计算结果就是float型
- 如果一个操作数是double型, 计算结果就是double型
操作数1的数据类型 | 操作数2的数据类型 | 转换后的数据类型 |
---|---|---|
byte, short, char | int | int |
byte, short, char, int | long | long |
byte, short, char, int, long | float | float |
byte, short, char, int, long, float | double | double |
1.7.2 强制类型转换(显式类型转换)
把高精度的变量的值赋给低精度的变量时, 必须使用显示类型转换运算(强制类型转换)
如 int a = (int) 45.23; // 45, 将double类型强转int型
[注: 转换类型的取值范围, 可能会导致数据溢出的问题]
1.8 题目
1.经典范例1: 判断某一年是否是闰年
(basic.javabasic.basictype..title.ClassicCase1LeapYear)
为了弥补人类历法年度天数和地球公转实际周期的时间差, 设立了有366议案的闰年, 闰年的二月份有29天.
闰年的判定规则是: 如果该年能被4整数且不能被100整数或者被400整数, 则该年是闰年, 否则不是
2.经典范例2: 求球形的体积
(basic.javabasic.basictype..title.ClassicCase2Volume)
计算球体的半径和体积
2 流程控制
(basic.javabasic.if_for_while_switch.If_SwitchDemo, For_WhileDemo)
2.1 条件语句
一、格式:
1).if (布尔表达式) { 执行语句; }
2).if (布尔表达式) { 执行语句; } else { 执行语句; }
3).if (布尔表达式) { 执行语句; } else if (布尔表达式) { 执行语句; } else { 执行语句; }
4).简写: 三元表达式: 条件 ? 结果1 : 结果2;
二、说明:
- 布尔表达式: 表示单纯的布尔值变量、布尔值常量, 使用关系的表达式或布尔运算符的表达式
- 执行语句: 0条或多条语句, 当为true时候执行
2.2 switch多分支语句
1.概念
switch的表达式, 必须是整型或字符型,在JAVA 7之前不支持String, Long, 在JAVA 7后支持String, 不支持Long
- 若表达式的值与case后面的变量值相同, 则执行该case语句后的若干语句, 直到遇到break语句为止,
- 若当前case没有break语句, 那么会执行后面的case的若干语句
- 若没有对应的case的值, 执行default的语句, default是可选的, 如果不存在, 就不执行
2.说明
在switch(expr)中, expr只能是一个整数表达式或者枚举常量, 整数表达式可以是int基本类型或Integer包装类型, 由于byte,short,char都可以隐含转换为int, 所以这些类型以及这些类型的包装类型也是可以的.
显然, long和String类型都不符合switch的语法规定, 并且不能被隐式转换成int类型, 所以他们不能作用于switch语句中
3.格式
switch(表达式) {
case 取值 1: 执行语句; break;
...
case 取值 n: 执行语句; break;
default: 执行语句; break;
}
2.3 循环语句
一、while (布尔表达式) { 执行语句; }
while循环语句也称为条件判断语句, 它的循环方式为利用一个条件来控制是否要继续反复执行这个语句
二、.do { 执行语句; } while (布尔表达式)
do...while循环语句与while循环语句类似, 他们之间区别是while循环语句先执行判断, 而do...while必须先执行一次循环, 在判断条件是否成立
三、for (初始化表达式; 循环条件表达式, 循环后的操作表达式) { 执行语句; }
- 初始化表达式: 负责完成变量的初始化
- 循环条件表达式: 值为boolean型的表达式, 指定循环条件
- 循环后的操作表达式: 负责修整变量, 改变循环条件
2.4 foreach语句
for的简化版本, 并不是关键字, 习惯将这种特殊的for语句称之为foreach
for (元素变量 x : 遍历对象 obj(Collection集合|数组)) {
引用了x的Java语句
}
1.传统for和高级for的区别?
传统for可以完成对语句执行很多次, 因为可以定义控制循环的增量和条件.
高级for是一种简化形式. 它必须有被遍历的目标. 该目标要是数组, 要么是Collection单列集合.
对数数组的遍历如果仅仅是获取数组中的元素, 可以使用高级for。如果要对数组的角标进行操作建议使用传统for
List list = new ArrayList();
list.add("abc1");
list.add("abc2");
for (String s : list) { //简化书写
System.out.println(s);
}
2.JDK8 Lambda表达式[实测比原生循环效率低]
// JDK 8 Lambda 表达式
System.out.println("\n=====JDK 8的新用法=====");
list.forEach(s -> {
System.out.println(s);
});
2.5 流程控制语句
一、break语句
应用在for, while和do...while, 强行退出循环, 和在switch跳出, 防止执行后面的执行语句
System.out.println("\n=====第一个break=====");
for (int x = 0; x < 3; x++) {
if (x == 2)
break;
System.out.println("x = " + x);
}
System.out.println("\n=====第二个break=====");
A1: for (int x = 0; x < 3; x++) {
A2: for (int y = 0; y < 4; y++) {
System.out.println("x = " + x);
break A1;
}
}
二、continue语句(继续)
只能应用在for, while和do...while循环语句中, 用于跳过后面的语句, 进入下一次循环
三、return语句
return语句可以从一个方法返回, 并把控制权交给调用它的语句
格式: return [表达式];
表达式: 可选参数, 表示要返回的值, 它的数据类型必须与方法生命中的返回值类型一致
2.6 题目
(basic.javabasic.if_for_while_switch.title.*)
1).范例2:验证登录信息的合法性:用户输入登录信息和密码,验证是否正确,正确则允许登录,否则拒绝
2).经典范例1: 使用for循环输出九九乘法表
3).经典范例2: 使用for循环输出杨辉三角:杨辉三角形由数字排列, 可以把它看作一个数字表, 基本特性是两侧数值均为1, 其他位置的数值是其正上方的数值与左上角数值之和
3 函数
(basic.javabasic.func.FunctionDemo)
3.1 什么是函数
函数就是定义在类中具有特定功能的一段独立小程序,函数也称为方法
3.2 函数的格式
格式:
修饰符 返回值类型 函数名 (参数类型 形式参数1, 参数类型 形式参数2, ...) {
执行语句;
return 返回值;
}
- 修饰符:private、public、protected
- 返回值类型: 函数运行后的结果的数据类型
- 参数类型: 是形式参数的数据类型
- 形式参数: 是一个变量, 用于存储调用函数时递给函数的实际参数
- 实际参数: 传递给形式参数的具体数值
- return: 用于结束函数
- 返回值: 该函数运算后的结果, 该结果会返回给调用者
3.3 函数的特点
- 定义函数可以将功能代码进行封装
- 便于对该功能进行复用
- 函数只有被调用才会被执行
- 函数的出现提高了代码的复用性
- 没有具体返回值的情况, 返回值类型用关键字void表示, return语句如果在最后一行可以省略不写
说明: 函数的可变参数, 其实就是一个数组, 但是接收的是数组的元素. 自动将这些元素封装成数组. 简化了调用者的书写. 可变参数类型, 必须定义在参数列表的结尾
public static int addBatch(int... arr) {
int sum = 0;
for (int i = 0; i < arr.length; i++) {
sum+=arr[i];
}
return sum;
}
3.4 函数的重载
概念: 在同一个类种, 允许存在一个以上的同名函数, 只要他们的参数个数或者参数类型不同即可
特点: 与返回值类型无关, 只看参数列表
好处: 方便于阅读, 优化了程序设计
/** 加法运算. 两个整数的和 */
public static int add(int a, int b) {
return a + b;
}
/** 加法运算. 两个小数的和 */
public static double add(double a, double b) {
return a + b;
}
/** 加法运算, 三个整数的和*/
public static int add(int a, int b, int c) {
return add(a, b) + c;
}
3.5 基本数据类型参数传递 和 引用数据类型参数传递
(basic.javabasic.func.ParamTransmit)
一、基本数据类型参数传递,不会真正改变值(因为不在同一个区间)。
流程说明:
- main压栈
- x=3压栈(main里面的局部变量)
- 调用show()方法, show方法压栈
- show里面的x跟着压栈, 主函数的x赋值给show方法的x=3, 但是他们不在一个区间, show方法的x=4, 那么show里面的x=4
- 然后show方法执行完毕, 弹栈
- 但是main中x并没有被改变, 因为不在同一个区间
- 结果输出为3
二、引用数据类型参数传递,因为指向地址的值被改变, 这就是引用数据类型参数传递。
流程说明:
- main方法压栈
- Demo d压栈
- new Demo()压堆, 并开辟地址赋值给d
- show方法压栈, 将d传给show
- show执行d.x=4(因为d指向地址, 所以该地址下的x=4)
- show执行完毕, 弹栈
- 显示d.x, 结果为4, 而不是9,
3.6 递归的使用
(basic.javabasic.func.DiGuiDemo)
函数自身直接或者间接的调用到了自身就称为递归, 经典案例: 汉诺塔
一个功能被重复使用, 并每次使用时, 参与运算的结果和上一次调用有关, 这时可以考虑使用递归来解决问题
使用递归注意的点:
- 递归一定要明确条件, 否则容易导致栈溢出
- 注意递归的次数
4 获取用键盘输入常用的两种方法
方法1:通过 Scanner
Scanner input = new Scanner(System.in);
String s = input.nextLine();
input.close();
方法2:通过 BufferedReader
BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
String s = input.readLine();