强烈安利韩顺平老师的b站Java教程!
1. Java执行流程
.java文件(源文件) javac编译 .class文件(字节码文件) java运行 结果
//Hello.java
//Hello是一个公有类
public class Hello {
//主方法,程序的入口
public static void main(String[] args) {
System.out.println("hello world!");
}
}
注意:
一个源文件最多一个public类,其他类 不限;
如果源文件包含一个public类,则文件名以该类命名;
可将main方法写在非public类中,然后指定运行非public类,这样入口方法就是非public类的main方法。
2. Java转义符
- \t 一个制表位,实现对齐功能
- \n 换行符
- \r 一个回车
- " ' \ 输出双引号、单引号、反斜杠
3. 文档注释
可被javadoc所解析,生成一套以网页形式体现的说明文档。
/**
* @author Tom
* @version 0.1
*/
javadoc -d /doc -author -version Hello.java
4. Java代码规范
- 类、方法的注释,要以javadoc的方式写
- 运算符和等号两边有空格
- 源文件使用utf-8保存
- 行宽度不要超过80字符
5. 变量
5.1 变量概念
变量必须先声明再使用;
变量在同一个作用域内不能重名;
变量可以在同一类型下更改其他值。
int a = 10
Java变量首字母不能大写。
+号使用:
- 左右两边都是数值型,做加法运算
- 左右两边一方为字符串,做字符串拼接
- 运算顺序从左到右
5.2 数据类型
Java数据类型分两大类,基本数据类型和引用类型。
基本数据类型:
- 数值型
- 整数类型 byte short int long 占字节数:1、2、4、8
- 浮点型 float double 占字节数:4、8
- 字符型 char 占字节数:2
- 布尔型 boolean 占字节数:1
引用类型:
- 类(class)
- 接口(interface)
- 数组
整型
各整型类型有固定的范围和字段长度,不受OS影响。
整型常量(具体值)默认为int,声明long型需在后面加‘l’或‘L’。
long num = 1L
变量一般声明为int,除非长度不足才用long。
浮点型
单精度float 占4字节
双精度double 占8字节
浮点数在机器中存放形式:浮点数=符号位+指数位+尾数位,尾数部分可能丢失,造成精度损失。
浮点型常量(具体值)默认为double,声明float时需在后面加‘f’或‘F’。
float num = 1.1f
浮点型常量两种表示形式:
- 十进制数:9.11 911.0f .0911 (必须有小数点)
- 科学计数法:5.12e2(5.12102) 5.12E-2(5.1210-2)
通常情况应使用double型。
浮点数使用陷阱:2.7与8.1/3,要小心对小数运算结果的相等判断,正确的判断应是对两个数差值的绝对值控制在非常小的精度。
double num1 = 2.7;
double num2 = 8.1 / 3; //计算结果小于但接近2.7
//错误的判断相等
if (num1 == num2) {
System.out.println("equal");
}
//正确的判断相等
if (Math.abs(num1 - num2) < 0.1e-6) {
System.out.println("equal");
}
字符类型
用单引号括起来,存放单个字符,两字节,可存放一个汉字,还允许使用转义字符。
Java中char的本质是一个整数,输出是Unicode码对应的字符。
char型可以进行运算,相当于对应Unicode码整数的运算。
char c1 = 'a';
char c2 = 97;
char c3 = '\t';
char c4 = '啊';
System.out.println('a'+10); //输出107
ASCII一个字节表示字符,
Unicode两个字节表示字符,
UTF-8字母一个字节,汉字三个字节。
布尔型
boolean型占1字节,true和false。Java中不可用0或非零代替false或true。
自动类型转换
当Java程序在赋值或运算时,精度小的类型自动转换为精度大的。
数据类型按精度(容量)大小排序:
char<int<long<float<double
byte<short<int<long<float<double
double a = 80;
,int b = 'a';
注意:
有多种类型的数据混合运算时,系统自动将所有类型转换成精度最大的那种类型。
把精度大的数据类型赋值给精度小的会报错,反之不会。
(byte,short)和char之间不会相互自动转换。
byte,short,char之间可以计算,计算时首先转换成int,即便byte与byte运算也会自动转换为int。
boolean型不参与类型自动转换。
表达式结果的类型自动提升为操作数中最大的类型。
强制类型转换
自动类型转换的逆过程,将容量大的类型转换为容量小的,使用强制转换符,可能造成精度损失或数据溢出。
int i = (int)1.9; //1
int j = 2000;
byte b = (byte)j; //-48
强转符号只针对最近的操作符,对全部操作数需小括号。
char类型可以保存int常量值,不可保存int变量值,需要强转。
基本数据类型与String的转换
基本数据类型转String:后+""
int i = 100;
String s1 = i + "";
boolean b = true;
String s2 = b + "";
String转基本数据类型:使用数据类型对应的parse方法
String s1 = "123";
int i1 = Integer.parseInt(s1);
double d1 = Double.parseDouble(s1);
字符串转char:获取字符串的第一个字符
String s = "123";
System.out.println(s.charAt(0));
注意:
将String转成基本数据类型时,确保String数据的有效性,如果格式不正确会抛出异常。
6. 运算符
6.1 算术运算符
+加,-减,*乘,/除,%取模,++自增,--自减
System.out.println(10 / 4); //输出2,整数除以整数
System.out.println(10.0 / 4); //输出2.5
double d = 10 / 4; //结果2.0
//%本质:a % b = a - a / b * b
System.out.println(-10 % 3); //结果-1
System.out.println(10 % -3); //结果1
System.out.println(-10 % -3); //结果-1
int i = 1;
i = i++; //temp = i; i = i+1; i = temp;
System.out.println(i); //1
6.2 关系运算符
instanceof
检查是否是类的对象,"abc" instanceof String
结果为true。
6.3 逻辑运算符
- 短路与
&&
,短路或||
,取反!
- 逻辑与
&
,逻辑或|
,逻辑异或^
6.4 赋值运算符
- 基本赋值运算符 =
- 复合赋值运算符 +=,-=,*=,/=,%=
复合赋值运算会进行类型强制转换:
byte b = 3;
b += 2; //等价于b=(byte)(b+2),但b=b+2则不行
b++; //等价于b=(byte)(b+1)
6.5 三元运算符
条件表达式?表达式1:表达式2;
若条件表达式为true,则运算结果为表达式1;
若条件表达式为false,则运算结果为表达式2。
表达式1和表达式2要为可以赋给接受变量的类型(或可以自动转换)。
三元运算符可以转换为if-else语句。
6.6 标识符命名规则与规范
Java对各种变量、方法和类等命名使用的字符序列叫做标识符。
命名规则
- 由26各英文字母大小写,0-9,_或$组成;
- 数字不可开头;
- 不可使用关键字和保留字,但能包含关键字和保留字;
- 严格区分大小写,长度无限制;
- 标识符中不能包含空格。
命名规范
- 包名:多单词组成时所有字母小写 aaa.bbb.ccc;
- 类名、接口名:多单词组成时所有单词首字母大写;
- 变量名、方法名:多单词组成时,第一个单词首字母小写,后面单词首字母大写;
- 常量名:所有字母大写,多单词时每个单词间下划线连接。
6.7 进制与位运算
进制
二进制:以0b或0B开头,int n1 = 0b1010
;
八进制:以0开头,int n2 = 01010
;
十六进制:以0x或0X开头,A-F不区分大小写,int n3 = 0x1a
;
位运算
按位与&
,按位或|
,按位异或^
,按位取反~
。
算术右移>>
:低位溢出,符号位不变,并用符号位补溢出的高位。
算术左移<<
:符号位不变,低位补0。
逻辑右移>>>
:无符号右移,低位溢出,高位补0。(没有<<<)
int a = 15 >> 2; //相当于15/2/2=3
int b = 4 << 3; //相当于4*2*2*2=32
7. 控制结构
7.1 顺序控制
7.2 分支控制
单分支
import java.util.Scanner;
public class If01 {
public static void main(String[] args) {
Scanner myScanner = new Scanner(System.in);
System.out.println("input age:");
int age = myScanner.nextInt();
if (age > 18) {
System.out.println(age + "is adult");
}
}
}
双分支
多分支
嵌套分支
switch分支:
switch内的表达式结果数据类型需和case的常量类型一致;
switch表达式中的返回值必须是(byte、short、int、char、enum、String);
case子句中的值必须是常量;
若没有break跳出switch,则顺序执行下一个子句。
7.3 循环控制
for循环
while循环
do_while循环
多重循环
7.4 跳转控制
break
用于终止某个语句块的执行,在switch或循环中。
当某个条件满足时,终止循环。
break出现在多层嵌套的语句中,可通过标签指明要终止到哪里,若没有指定标签,默认退出最近的语句块。
abc1:
for (int j = 0; j < 4; j++) {
abc2:
for (int i = 0; i < 10; i++) {
if (i == 2) {
//break; //输出4次01
break abc1; //输出一次01
}
System.out.println("i=" + i);
}
continue
结束本次循环,继续执行下一次循环。
也可以使用标签。
return
如果return写在main方法,退出程序。
8. 数组
8.1 数组
数组是引用类型,存放多个同类型数据。
动态初始化1:
数组定义:数据类型 数组名[] = new 数据类型[大小];
数组的引用:数组名[下标]
动态初始化2:
先声明:数据类型 数组名[];
创建数组:数组名 = new 数据类型[大小];
静态初始化:
数据类型 数组名[] = {元素值1,元素值2};
注意:
数组中的元素可以是任意类型;
数组创建后,如果没有赋值,有默认值;
使用数组的步骤:1声明数组并开辟空间,2给数组各个元素赋值,3使用数组;
数组属引用类型,数组型数据是对象,赋的值为地址。
数组拷贝
int arr1[] = new int[]{10, 20,30};
int arr2[] = new int[arr1.length];
for (int i=0; i<arr1.length; i++) {
arr2[i] = arr1[i];
}
数组反转
int arr[] = {11,22,33,44,55,66}
int temp = 0;
for (int i=0; i < arr.length/2; i++) {
temp = arr[arr.length-1-i];
arr[arr.length-1-i] = arr[i];
arr[i] = temp;
}
8.2 二维数组
动态初始化1:类型 数组名[][] = new 类型[大小][大小]
动态初始化2:类型 数组名[][];
,数组名 = new 类型[大小][大小];
静态初始化:类型 数组名[][] = {{值1, 值2}, {...}};
int ar[][] = {{...}, {...}};
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < arr[i].length; j++) {
System.out.print(arr[i][j] +" ");
}
System.out.println();
}
可以允许二维数组中的一维数组元素个数不同。
int arr[][] = new int[3][]; //创建三个一维数组的二维数组
for (int i = 0; i < arr.length; i++) {
//给一维数组开辟空间
arr[i] = new int[i+1];
//遍历一维数组并给一维数组元素赋值
for (int j = 0; j < arr[i].length; j++) {
arr[i][j] = i + 1;
}
}