目录
- 2.1 Java 基础语法
- 2.2 基本数据类型
- 2.21 整数类型
- 2. 22浮点数类型
- 2.23 字符类型
- 2.24 布尔类型
- 2.25 基本数据类型的类型转换
- 2.26 自动类型转换/隐式类型转换
- 2.27强制类型转换
- 2.28表达式类型的自动提升
- 2.29 最常用的引用类型 String
- 2.3 运算符和表达式
- 2.31 算术运算符
- 2.32 自增和自减
- 2.33 赋值运算符
- 2.34 比较运算符
- 2.35 逻辑运算符
- 2.36 按位运算符,移位运算符
- 2.37 三元运算符 / 三目运算符
- 2.4 Java中的关键字
- 2.5 Java中的修饰符
- 2.6 常量和变量
- 2.6.1常量
- 2.4.2 变量
- 2.7 注释
- 2.8 数据输出和输入
- 2.81 数据输出
- 2.82 数据输入
2.1 Java 基础语法
- 在配置完 Java 开发环境,并下载 Java 开发⼯具(Eclipse、 IDEA 等)后,就可以写 Java 代码了,因为本篇⽂章是从头梳理 Java 体系,所以有必要从基础的概念开始谈起。
- Java语言严格区分大小写,⼤⼩写敏感: Java 是对⼤⼩写敏感的语⾔,例如 Hello 与 hello 是不同的,这其实就是 Java 的字符串表示⽅式
- 一个java源文件(.java)里可以定义多个 Java 类,但其中最多只能有一个类可以被定义为public类;若源文件中包含public类定义,则该源文件的文件名必须与该public类的类名一致
- 一个源文件包含N个Java类时,成功编译后会生成N份字节码文件(.class),即每个类都会生成一份单独的class文件,且字节码文件名和其对应的类名相同
- 若一个类必须运行,则需要有mian方法或j使用JUnit 测试类,mian方法是程序的入口
- 标识符: 标识符就是给常量、变量、类、方法起名字
注意:
标识符由字母、数字、下划线"_"、美元符号"$"组成
标识符不能以数字开头
标识符严格区分大小写
标识符不能是关键字
例如 :
1.小驼峰命名法:变量名,方法名
1.1.规则:首字母小写,从第二个单词开始,每个单词首写字母大写
1.2.举例:myFirstMethod,myFirstMethod()
2.类名:
2.1:对于所有的类来说,⾸字⺟应该⼤写
2.2:举例:MyFirstClass
3.包名:
3.1:包名应该尽量保证⼩写
3.2:举例: my.first.package
4.常量的命名规范:
4.1 :规则:每个单词都大写,单词之间用_(下划线)分割
4.2:举例:MOMENT_LEARN
2.2 基本数据类型
●对于每一种数据都定义了明确的具体数据类型,在内存中分配了不同大小的内存空间。
- 在 Java 中,数据类型只有 四类⼋种
2.21 整数类型
1.byte,short,int,long
2. byte 也就是字节, 1 byte = 8 bits, byte 的默认值是 0
3. short 占⽤两个字节,也就是 16 位, 1 short = 16 bits,它的默认值也是 0
4. int 占⽤四个字节,也就是 32 位, 1 int = 32 bits,默认值是 0
5. long 占⽤⼋个字节,也就是 64 位, 1 long = 64 bits,默认值是 0L
6. 所以整数型的占⽤字节⼤⼩空间为 long > int > short > byte
int i = 11;//整数常量默认是int 类型
long l = 11L; //long 类型常量需在整数后添加l 或L 后缀
long l = 110; //可以把一个比较小的整数值(int类型的表数范围内)直接赋给一个long 类型的变量(自动类型转换)
1MB= 1024KB 1KB= 1024B B= byte ? bit?
bit:计算机中的最小存储单位。byte:计算机中 基本存储单元。
2. 22浮点数类型
浮点型有两种数据类型: float 和 double
- float 是单精度浮点型,占⽤ 4 位, 1 float = 32 bits,默认值是 0.0f
- double 是双精度浮点型,占⽤ 8 位, 1 double = 64 bits,默认值是 0.0d;
double pi = 3.14; // 浮点数常量默认是 double 类型
float pi = 3.14F; // float 类型常量需在浮点数后添加 f 或 F 后缀
float pi = 3.14; // 错误: 不兼容的类型: 从 double 转换到 float 可能会有损失
3.14 == 3.14F; // false
3.14 == 3.14D; // true
float a = 1.0f - 0.9f;
float b = 0.9f - 0.8f;
a == b; // false
注意:浮点数采用“尾数+阶码”的编码方式,所以 float, double 都不能表示精确的浮点数,需用 BigDecimal 类型
2.23 字符类型
字符型就是 char, char 类型是⼀个单⼀的 16 位 Unicode 字符,最⼩值是 \u0000 (也就是 0 ) ,
最⼤值是 \uffff (即为 65535) , char 数据类型可以存储任何字符,例如 char a = ‘A’。
- char 16 位 Unicode 字符集,编码方式为 UTF-16BE
- UTF-16 使用 2 或者 4 字节表示一个字符,在 65536 以内的占两个字节,而基本上所有汉字的 Unicode 编码在 19968 到 40869 之间,所以一个 char 类型可以存储一个汉字
- 使用’‘引号括起来
49’1’; 65 ‘A’; 97 ‘a’
// 表示形式
char c1 = 'A'; // 使用单个字符
char c2 = 65; // 使用十进制的整数(Unicode 值),[0, 65535]
char c3 = '\u0061'; // 使用十六进制的整数,格式'\uXXXX',('\u0000'~'\u00FF')
2.24 布尔类型
布尔型指的就是 boolean, boolean 只有两种值, true 或者是 false,只表示 1 位,默认值是 false。
boolean isMan = true;
2.25 基本数据类型的类型转换
boolean不属于数值类型.不参与转换
2.26 自动类型转换/隐式类型转换
如果直接将一个较小的整数常量(在 byte 或 short 类型的表数范围内)赋给一个 byte 或 short 变量,系统会自动把这个整型常量当成 byte 或 short 类型来处理
2.27强制类型转换
语法格式: (targetType)value
byte b2 = 65; // 系统会自动把 65 当成 byte 类型处理
int a = 12;
byte b = (byte) a;// 强制类型转换
float a = (float) 5.6; // 强制类型转换
int i = (int) -12.32; // 强制类型转换(小数部分被截掉),i = -12
(char) 65; // 表示 'A' 字符
2.28表达式类型的自动提升
- 所有的byte , short , char 类型被自动提升到int 类型
- 整个算术表达式最终结果的数据类型被提升到表达式中操作数类型最高的类型
short s = 5 ; //自动类型转换 (隐式类型转换)
s = s -2; //错误: 不兼容的类型: 从int 转换到short 可能会造成精度损失
2.29 最常用的引用类型 String
- 字符串常量使用""引起来的,连接字符串使用 “+” 符号
- 字符串拼接:字符串可以和任何基本类型的值或 Java 对象进行连接运算,结果都是字符串类型(基本类型的值将自动类型转换为字符串类型,系统自动调用 Java 对象 toString() 方法)
2.3 运算符和表达式
运算符: 对常量或变量进行操作的符号
表达式:用运算符把常量或变量连接起来符合Java语法的式子被称为表达式
表达式不是完整的语句!
2.31 算术运算符
符号 | 作用 | 举例 | 说明 |
+ | 加 | 3+6 | 6+3=10 |
- | 减 | 9-3 | 9-3=6 |
* | 乘 | 3*3 | 3*3=9 |
/ | 除 | 9/3 | 9/3=3 |
& | 取模(取余) | 7%3 | 7%3=1 |
说明:
- 加号
1.1 加号在操作数值、字符、字符串时,其结果是不同的
1.2 当两个字符相加得到的是 ASCII 码表值
1.3 作为字符串连接运算符 - 除号
2.1 如果除法运算符的两个操作数都是整数类型,则计算结果也是整数(截断小数部分取整),此时除数不能是 0,否则将引发除以零异常 ArithmeticException: / by zero
2.2 如果除法运算符的两个操作数有 1 个是浮点数,或者 2 个都是浮点数,则计算结果也是浮点数,此时允许除数是 0,或者 0.0,得到结果是正无穷大或负无穷大 - 算数运算
3.1 算数运算符需要注意的就是 优先级问题 ,当⼀个表达式中存在多个操作符时,操作符的优先级顺序就决定了 计算顺序,最简单的规则就是先乘除后加减, () 的优先级最⾼,没必要记住所有的优先级顺
序,不确定的直接⽤ () 就可以了。 - 取模(取余)
4.1 被模数 % 模数
4.2模数的符号忽略不计,结果的正负取决于被模数
4.3 如果求余运算的两个操作数都是整数类型,则求余运算的第二个运算数不能是 0,否则将引发除以零异常
'A' + 'B' // 131
"A" + "B" // AB
10 / 3 // 3
System.out.println(10 / 0) // ArithmeticException: / by zero
System.out.println(10.0 / 0) // 输出正无穷大:Infinity
System.out.println(-10.0 / 0) // 输出负无穷大:-Infinity
System.out.println(0 / 0.0) // 输出非数(Not a Number):NaN
/*
注意:
无穷大和 NaN 都属于 double 浮点类型
但是所有正无穷大数值都是相等的,所有负无穷大数值也是相等的
NaN 不与任何数值相等,也不等于自己
*/
2.32 自增和自减
符号 | 作用 | 举例 | 说明 |
++ | 自增 | int i =10; i++; | i=11 |
– | 自减 | 3*3 | 3*3=9 |
- 自增、自减操作都是直接修改变量的值(读、改、写),不经过操作数栈
- 前置 ( ++i ):局部变量表中的 i 先自增,再把 i 的值压入操作数栈
- 后置 ( i++ ):先把局部变量表中的 i 压入操作数栈,再自增
int i = 1;
i = ++i;
System.out.println(i); // 2
int j = 1;
j = j++;
System.out.println(j); // 1
int a = 5;
b = ++a;
c = a++;
2.33 赋值运算符
符号 | 作用 | 举例 | 说明 |
= | 赋值 | int i =9 | 将9 赋值给i |
+= | 加后赋值 | i+=x | 将i+x的值赋值给i |
– = | 减后赋值 | i-=x | 将i-x的值赋值给i |
*= | 乘后赋值 | i*=x | 将i*x的值赋值给i |
/ = | 除后赋值 | i/=x | 将i/x的值赋值给i |
%= | 取余后赋值 | i%=x | 将i%x的值赋值给i |
+= 隐式的将加操作的结果类型强制转换为持有结果的类型
byte a = 127;
byte b = 127;
b = a + b; // error : cannot convert from int to byte
b += a; // ok
short s = 5;
s += 5; // s = (short)(s + 5)
2.34 比较运算符
⽐较运算符⽤于程序中的变量之间,变量和⾃变量之间以及其他类型的信息之间的⽐较。
⽐较运算符的运算结果是 boolean 型。当运算符对应的关系成⽴时,运算的结果为 true,否则为false。⽐较运算符共有 6 个,通常作为判断的依据⽤于条件语句中。
符号 | 作用 | 举例 | 说明 |
== | 判断是否相等 | x==z | 判断x和z的值是否相等,成立为true,不成立为false |
!= | 判断是否不等 | x!=z | 判断x和z的值是否不相等,成立为true,不成立为false |
> | 大于 | x>z | 判断x的值是否大于z的值,成立为true,不成立为false |
>= | 大于等于 | x>=z | 判断x的值是否大于等于z的值,成立为true,不成立为false |
< | 小于 | x<z | 判断x的值是否小于z的值,成立为true,不成立为false |
<= | 小于等于 | x<=z | 判断x的值是否小于于等于z的值,成立为true,不成立为falsei |
- 比较运算符的结果是 boolean 类型
- 使用 == 判断两个两个变量是否相等
基本类型变量:只要两个变量的值相等( 不一定要求数据类型严格相同),就返回 true
引用类型变量:只有两个变量指向同一个对象时,返回 true(不可用于比较类型上没有继承关系的两个对象,否则编译报错)
97 == 'a'; // true
5.0 == 5; // true
"hello" == new Animal(); // 编译报错
2.35 逻辑运算符
逻辑运算符主要有三种,与、或、⾮
符号 | 作用 | 说明 |
& | 逻辑与 | 与,都为 true,结果才为 true,否则结果是 false |
| | 逻辑或 | 或,都为 false,结果才为 false,只要有一个是 true,结果就是 true |
! | 逻辑非 | 取反,!true 结果是 false,!fasle 结果是 true |
^ | 逻辑异或 | 异或,判断两个操作数是否不同,不同则为 true,相同则为 false |
&& | 短路与 | 短路与,如果左边的操作数是 false,结果一定为 false,且不再计算右边的操作数 |
|| | 短路或 | 短路或,如果左边的操作数是 true,结果一定为 true,且不再计算右边的操作数 |
- “& " 和”&&" 的异同
1.1 “&” 和"&&":左边为真,右边都运行
1.2 左边为假 "&"运行 "&&"不运行
下⾯是逻辑运算符对应的 true/false 符号表
用于操作两个 boolean 类型的变量或常量,结果也是 boolean 类型
2.36 按位运算符,移位运算符
- 按位运算符⽤来操作整数基本类型中的每个 ⽐特 位,也就是⼆进制位。按位操作符会对两个参数中对应的位执⾏布尔代数运算,并最终⽣成⼀个结果。
- 移位运算符⽤来将操作数向某个⽅向(向左或者右)移动指定的⼆进制位数。
符号 | 作用 | 说明 |
& | 按位与 | 当两位同时为 1 时才返回 1 |
| | 按位或 | 只要有一位为 1 即可返回 1 |
~ | 按位非 | 单目运算符,将操作数的每个位(包括符号位)全部取反 |
^ | 按位异或 | 当两位相同时返回 0,不同时返回 1 |
<< | 左移运算符 | eg:9<<2=36 |
>> | 右移运算符 | eg:8>>1=4 |
>>> | 无符号右移运算符 | 不管此整数是整数还是负数,高位都拿0补 |
- 操作的是数的补码的二进制位
- 位运算符只能操作整数类型的变量或值
- << : 在一定范围内,每左移一位,相当于*2
- >>: 在一定范围内,每右移一位,相当于/2
- 经典面试题:你能否写出最高效的2 * 8 的实现方式 ?
2 << 3 或 8 >> 1
// 左移 n 位相当于乘以 2 的 n 次方
// 右移 n 位相当于除以 2 的 n 次方
4 >> 1; // 效率高的除以 2,等价于 4 / 2
1 << 10; // 等于 2 的 10 次方
// 交换两个变量的值
int a = 10;
int b = 12;
// 第一种方法,使用临时变量
int temp = a;
a = b;
b = temp;
// 第二种方法
// 把 a、b 看做数轴上的点,围绕两点间的距离来进行计算(可能会越界)
a = b - a;
b = b - a;
a = b + a;
// 第三种方法
// 任意一个数与任意一个给定的值连续异或两次,值不变
a = a ^ b;
b = a ^ b;
a = a ^ b;
2.37 三元运算符 / 三目运算符
三元运算符是类似 if…else… 这种的操作符,语法为: 条件表达式?表达式 1:表达式 2。问号
前⾯的位置是判断的条件,判断结果为布尔型,为 true 时调⽤表达式 1,为 false 时调⽤表达式 2。
格式:boolean 表达式 ? 表达式 1 : 表达式 2
// 判断奇数偶数
String ret = number % 2 == 0 ? "偶数" : "奇数";
2.4 Java中的关键字
定义:在Java语言中事先被定义赋予特性含义的小写单词
2.5 Java中的修饰符
- 修饰符的适用范围
- 访问权限修饰符
定义:用于控制一个类的成员是否可以在其他类中访问,不能修饰局部变量 - private(当前类访问权限): 在同一类内可见,只能被所属类方法
无(包访问权限):不使用任何修饰符时,在同一包内可见
protected(子类访问权限) : 对同一包内的任何其他类和不同包中的子类可见,不能修饰接口中的成员变量和成员方法(注意:在不同包中的子类只能通过该子类访问父类中protected成员,通过其他子类或父类都无法访问)
public(公共访问权限):对所有类可见 - 非访问修饰符
static : 用于创建类方法和类变量,类方法不能访问的实例变量
final : 用于修饰符,方法和变量,final修饰的类不能被继承,修饰的方法不能被继承类重新定义,修饰的变量为常量,不可修改
abstract : 用来创建抽象类,抽象方法
synchronized : 修饰的方法,代码块中在同一时间只能被一个线程访问,不能修饰构造器,成员变量等
volatile : 修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值;并且,当成员变量发生变化时,强迫线程将变化值回写到共享内存(保证了线程操作时变量的可见性.即一个线程修改了某个变量的值.这个新值对其他线程来说是立即可见的) (只保证内存可见性,无法保证操作的原子性)
transient : 序列化的对象包含被transient 修饰变量时,JVM 跳过该特定的变量
native : 修饰的方法通常采用C/C++ 语言实现
- volatile 的实现原理
- 如果对声明了volatile 变量进行写操作 .JVM 就会对处理器发送一条lLock前缀的指令,将这个变量所在的缓存行的数据写回到内存,这个回写内存的操作会引起在其他CPU里缓存了该内存地址的数据无效
- 缓存一致行协议(如Intel 的MESI协议): 每个处理器通过嗅探在总线上传播的数据来检查自己缓存的值是不是过期了,当处理器发现自己缓存行对应的内存地址被修改,就会将当前处理器的缓存行设置为无效状态,当处理器要对这个数据进行修改操作时,会强制重新从系统内存里把数据读取到处理器缓存里
- final 修饰符
- final修饰的类:
- 表示最终的类,不可被继承的类
- Java里 final 修饰的类有很多,比如八大基本数据类型包装类和String类,也是不可变类(当创建它们的实例后,其实例的实例变量不可改变)
final修饰的方法:
- 表示最终的方法,该方法子类可以调用,但不允许被子类覆盖
- 构造方法不能使用 final 修饰
final修饰的变量
- 表示最终的变量,常量,该变量只能被赋值一次
- final 修饰的成员变量必须显示指定初始值(定义时,初始化块或构造器中指定),系统不会为final 字段初始化; 静态常量的单词全部大写,单词间使用下划线隔开 final int MAX_VALUE=…;
- final 是唯一可以修饰局部变量的修饰符
- final 修饰基本数据类型的变量,表示该变量不能重新赋值
- final 修饰引用数据类型的变量 ,表示该变量所引用的地址不能变,而引用对象的内容可以改变
- 可执行"宏替换" 的final 变量: 当定义final 变量时就为该变量指定了初始值,编译器会把程序中所有用到该变量的地方直接替换成该变量的值**(在编译阶段能确定内容只能来自于常量池中)**
2.6 常量和变量
2.6.1常量
- 字面量常量/直接量
- final 定义的变量
直接量的类型
1.int类型的直接量二进制(以0B或0b开头),八进制(以0开头),十进制和十六进制(以0x或0X开头) 如123,012(对应的十进制的10),0x12 (对应十进制的18)
4. long类型的直接量: 在整数数值后添加l 或L ,如3L,0x12L
5. float类型的直接量: 在一个浮点数后添加f或F ,如5.34f,3.14E5F
6. double类型的直接量: 标准小数形式或科学计数法形式的浮点数,如: 5.34,3.14E5
7. boolean类型的直接量: 只有true 和false
8. char类型的直接量:单引号括起来的字符,转义字符和Unicode值表示的字符 如: ‘a’,’\n’和’u0061’
9. String类型的直接量: 用双引号括起来的字符序列
10. null类型的直接量: 只有一个值,即null,可以赋给任何引用类型的变量,用于表示这个引用类型变量中保持的地址为空,即还未指向任何有效对象
2.4.2 变量
定义格式:
1.//数据类型 变量名 = 初始化值; (声明,赋值)
2. int num =123;
使用注意:
变量的分类按声明的位置的不同
●在方法体外,类体内声明的变量称为成员变量。
●在方法体内部声明的变量称为局部变量。
- 同一作用域内同一变量不可重复声明
- 变量必须初始化后才能使用(即必须有值才能使用),否则编译报错
- 变量的值可在同一类型不断变化
- 变量命名符合标识符规范,使用驼峰命名法,首字母小写
- 就近原则
变量的分类及作用域
不同数据类型的成员变量的初始值
成员变量/全局变量/字段 : 直接定义在类中, 方法外的变量
- 类变量使用static 修饰的字段 方法区
2.实例变量没有使用static修饰字段 堆
3.默认是有初始值的,可以先在方法中定义 - 作用域是整个类
局部变量
1.方法的形参,方法中的变量,代码块中的变量
2.没有初始值,必须显示初始化后才能使用
3.定义局部变量后,系统并未分配内存空间,直到这个程序为变量赋值时 ,系统才会字所在方法中的栈内存中为局部变量分配内存,并将初始化(基本数据类型的值或者对象的引用),保存在该内存中
4.从定义的位置 开始到所在结束的花括号
二进制整数
- 原码,计算机中对数字的二进制定点表示方法,在数值前增加了一位符号位(即最高位为符号位) : 正数该位为0,负数该位为1(0有两种表示: +0 和-0) , 其余位表示数值的大小
- 正数的补码和原码完全相同
- 负数的补码是其反码加1;反码是原码按位取反,但最高位(符号位) 保持不变
2.7 注释
●用于说明解释程序的文字就是注释。
●提高了代码的阅读性;调试程序的重要方法。
●Java中的注释类型:
单行注释 使用 //注释内容
多行注释 使用 /*注释内容*/
文档注释 使用 /**注释内容*/:
➢格式: /**
* @author
指定java序的作者
*@version指定源文件的版本
*/
●注释内容可以被JDK提供的工具javadoc所解析,生成一套以
网页文件形式体现的该程序的说明文档。
●注释是一个程序员必须要具有的良好编程习惯。
●将自己的思想通过注释先整理出来,再用代码去体现
●注:
➢对于单行和多行注释,被注释的文字,不会被JVM( java虚拟机)解释执行。
➢多行注释里面不允许有多行注释嵌套。
2.8 数据输出和输入
2.81 数据输出
System.out.println(常量/变量/方法返回值/对象/表达式); //输出后换行
System.out.print(常量/变量/方法返回值/对象/表达式); //输出后不换行
2.82 数据输入
import java.util.Scanner
public class Text {
public static void main(String[] args) {
Scanner sc= new Scanner(System.in);
int i = sc.nextInt();
system.out.println(i);
}
}