前言
这篇文章是自学 Java 时的笔记,有不少地方比较粗糙,正处于边学边完善的阶段。
第一节 八大基本数据类型
一、 数据类型
Java的数据类型整体上来说分为两大类: 基本数据类型、引用数据类型。
二、基本数据类型
1.整型
byte,short,int(默认),long
2.浮点型
flout,double(默认)
3.字符型
char
4.布尔型
boolean(true,false)
三、类型转换
1.自动类型转换
自动类型转换指的是,数据范围小的变量可以直接赋值给数据范围大的变量
byte a = 12;
int b = a; //这里就发生了自动类型转换(把byte类型转换int类型)
自动类型转换其本质就是在较小数据类型数据前面,补了若干个字节
byte-->short-->int-->Long-->flout-->double
char-->int
表达式的自动类型转换
1.多种数据类型参与运算,其结果以大的数据类型为准
2.byte,short,char 三种类型数据在和其他类型数据运算时,都会转换为int类型再运算
2.强制类型转换
强制类型转换指的是:强行将范围大的数据,赋值给范围小的变量
int i = 1500;
byte j = (byte) i;
强制类型转换的原理,强行把前面几个字节去掉,有数据丢失的风险。
四、运算符
1.基本算术运算符
+ - * / %
+符号与字符串运算的时候是用作连接符的,其结果依然是一个字符串。
2.自增自减运算符
++读作自增,--读作自减
++在后:先做其他事情,再做自增
++在前:先自增,再做其他运输
3.赋值运算符
+= -= *= /= %=符号含义:将右边的数据和左边的变量相加、相减、相乘、相除、取余数后,将结果重新赋值给左边的变量。
4.关系运算符
关系运算符(也叫比较运算符)
5.逻辑运算符
逻辑运算符是用来将多个条件放在一起运算,最终结果是true或者false
6.三元运算符
关系表达式? 值1 : 值2;
首先计算关系表达式的值,如果关系表达式的值为true,则返回值1;如果关系表达式的值为false, 则返回值2;
第二节 流程控制
一、分支
1.if 分支
if
if(条件1){
语句体1;
}
if 执行流程如下:
如果 条件表达式 为true,就执行下面的语句体
如果 条件表达式 为false,就不执行
if…else
if(条件1){
语句体1;
}else {
语句体2;
}
if...else执行流程如下:
如果 条件表达式 为true,就执行下面的语句体1
如果 条件表达式 为false,就执行else下面的语句体2
if…else if
if(条件1){
语句体1;
}else if(条件2){
语句体2;
}
...
else{
语句体;
}
if...else if执行流程如下:
如果 条件表达式1 为true,就执行下面的代码1;
如果 条件表达式1 为false,就继续判断条件表达式2;
如果 条件表达式2 为true,就执行下面的语句体;
如果 条件表达式2 为false
....
如果前面所有条件表达式判断都为false,就执行最后的else语句中的代码
2.switch分支
switch (表达式){
case 值1:
执行代码...;
break;
case 值2:
执行代码...;
break;
...
default:
执行代码...;
}
注意:
1.表达式类型只能是byte、short、int、char,JDK5开始支持枚举,
JDK7开始支持String,不支持double、float、double
2.case给出的值不允许重复,且只能是字面量,不能是变量。
3.正常使用switch的时候,不要忘记写break,否则会出现穿透现象。
(当switch语句中没有遇到break,就会直接穿透到下一个case语句执行,直到遇到break为止。)
3. if 、switch如何选择
如果是对一个范围进行判断,建议使用if分支结构
如果是与一个一个的值比较的时候,建议使用switch分支结构
二、循环
1.for循环
//for循环格式:
for (初始化语句; 循环条件; 迭代语句) {
循环体语句(重复执行的代码);
}
初始化语句:一般是定义一个变量,并给初始值
循环条件:一般是一个关系表达式,结果必须是true或者false
迭代语句:用于对条件进行控制,一般是自增或者自减
循环语句体:需要重复执行的代码
2.while
初始化语句;
while(循环条件){
循环体语句(被重复执行的代码);
迭代语句;
}
知道循环几次,建议使用for;不知道循环几次建议使用while
3.do…while
初始化语句;
do {
循环体语句;
迭代语句;
}while(循环条件);
4.三种循环的区别
1. for循环 和 while循环(先判断后执行);
do...while (先执行后判断)
2.for循环和while循环的执行流程是一模一样的,
功能上无区别,for能做的while也能做,反之亦然。
如果已知循环次数建议使用for循环,如果不清楚要循环多少次建议使用while循环。
3 for循环中控制循环的变量只在循环中使用
while循环中,控制循环的变量在循环后还可以继续使用
5.死循环
//for死循环
for ( ; ; ){
System.out.println("Hello World1");
}
//while死循环
while (true) {
System.out.println("Hello World2");
}
//do-while死循环
do {
System.out.println("Hello World3");
}while (true);
三、跳转关键字
break
作用:跳出并结束当前所在循环的执行。只能用于结束所在循环,或者结束所在switch分支的执行
continue
作用:结束本次循环,进入下一次循环。只能在循环中进行使用。
第三节
一、静态初始化数组
标准格式:
数据类型[] 变量名 = new 数据类型[]{元素1,元素2,元素3};
简化格式:
数据类型[] 变量名 = {元素1,元素2,元素3};
数据类型[] 数组名` 也可写成 `数据类型 数组名[]
int[] ages = {12, 24, 36};
int ages[] = {12, 24, 36}
数组的元素访问
//索引: 0 1 2
int[] arr = {12, 24, 36};
// 1、访问数组的全部数据
System.out.println(arr[0]); //12
System.out.println(arr[1]); //24
System.out.println(arr[2]); //36
//下面代码没有3索引,会出现ArrayIndexOutOfBoundsException 索引越界异常
//System.out.println(arr[3]);
// 2、修改数组中的数据
arr[0] = 66;
arr[2] = 100;
System.out.println(arr[0]); //66
System.out.println(arr[1]); 0
System.out.println(arr[2]); //100
// 3、访问数组的元素个数:数组名.length
System.out.println(arr.length);
// 获取数组的最大索引: arr.length - 1(前提是数组中存在数据)
System.out.println(arr.length - 1);
数组的遍历
int[] ages = {12, 24, 36};
for (int i = 0; i < ages.length; i++) {
// i的取值 = 0,1,2
System.out.println(ages[i]);
}
二、动态初始化数组
动态初始化不需要写出具体的元素,先指定元素类型和长度就行
//数据类型[] 数组名 = new 数据类型[长度];
int[] arr = new int[3];
int[] arr 其实就是一个变量,它记录了数组对象的地址值,而且数组中的元素默认值是0。
三、数组的执行原理
数组的执行原理
- Java为了便于虚拟机执行Java程序,将虚拟机的内存划分为 方法区、栈、堆、本地方法栈、寄存器 这5块区域。
- 方法区:字节码文件先加载到这里
- 栈:方法运行时所进入的内存区域,由于变量在方法中,所以变量也在这一块区域中
- 堆:存储new出来的东西,并分配地址。由于数组是new 出来的,所以数组也在这块区域。
int a = 10与 int[] arr = new int[]{11,22,33}的区别
a是一个变量,在栈内存中,a变量中存储的数据就是10这个值。
arr也是一个变量,在栈中,存储的是数组对象在堆内存中的地址值
多个变量指向同一个数组的问题
1、多个数组变量,指向同一个数组对象的原因是什么?需要注意什么?
多个数组变量中存储的是同一个数组对象的地址
多个变量修改的都是同一个数组对象中的数据。
2、如果某个数组变量中存储的nul,代表什么意思?需要注意什么?
代表这个数组变量没有指向数组对象,
可以输出这个变量,但是不能用这个数组变量去访问数据或者访问数组长度
会报空指针异常:NullPointerException。
第四节 方法Method
一、定义
方法是一种语法结构,它可以把一段代码封装成一个功能,以便重复调用。
方法的完整格式
修饰符 返回值类型 方法名( 形参列表 ){
方法体代码(需要执行的功能代码)
return 返回值;
}
方法的执行
必须调用才执行;
//调用格式:
方法名(...);
- 如果方法不需要返回数据,返回值类型必须申明成void(无返回值申明), 此时方法内部不可以使用return返回数据。
- 方法如果不需要接收外部传递进来的数据,则不需要定义形参,且调用方法时也不可以传数据给方法。
- 没有参数,且没有返回值类型(void)的方法,称为值无参数、无返回值方法。此时调用方法时不能传递数据给方法。
方法使用的常见问题
方法使用时的常见问题
- 方法在类中的位置放前放后无所谓,但一个方法不能定义在另一个方法里面。
- 方法的返回值类型写void(无返回申明)时,方法内不能使用return返回数据,
如果方法的返回值类型写了具体类型,方法内部则必须使用return返回对应类型的数据
- return语句的下面,不能编写代码,属于无效的代码,执行不到这儿。
- 方法不调用就不会执行,调用方法时,传给方法的数据,必须严格匹配方法的参数情况。
- 调用有返回值的方法,有3种方式:1、可以定义变量接收结果 2、或者直接输出调用,3、甚至直接调用;
- 调用无返回值的-方法,只有1种方式:1、只能直接调用。
二、方法在计算机中的执行原理
-
方法的运行区域在栈内存。
-
栈有什么特点?方法为什么要在栈中运行自己?
栈先进后出。保证一个方法调用完另一个方法后,可以回来继续执行。
三、方法参数的传递机制
- 参数传递的基本类型数据
Java的参数传递机制都是:值传递,传递的是实参存储的值的副本。 - 参数传递的是引用数据类型
实际上也是值传递,只不过参数传递存储的地址值 - 基本类型和引用类型的参数在传递的时候有什么不同?
= 都是值传递- 基本类型的参数传递存储的数据值。
- 引用类型的参数传递存储的地址值。
四、方法重载
一个类中,出现多个相同的方法名,但是它们的形参列表是不同的,那么这些方法就称为方法重载了。
方法重载需要注意什么?
-
一个类中,只要一些方法的名称相同、形参列表不同,那么它们就是方法重载了,
其它的都不管(如:修饰符,返回值类型是否一样都无所谓)。 -
形参列表不同指的是:形参的个数、类型、顺序不同,不关心形参的名称。
方法重载有啥应用场景?
- 开发中需要为处理一类业务,提供多种解决方案