Java基础易忘点
前言:本文章是面对有一点基础的同学。
本人是一名大四在校生,在原来三年浑浑噩噩的过去了,学过Java也了解过一点,但是对于有一些代码总是容易忘记,所以看了狂神说Java的视频,一边学习写了一份博客帮助我和与我有一样感受的同学加深印象。
一、Java8大基本数据类型
类型名称 | 注意点 | 范围 |
---|---|---|
byte(字节型) | \ | -128~127 |
short(短整型) | \ | -32768~32767 |
int (整型) | \ | -2147483648~2147483647 |
long(长整型) | 整型常量若要声明为long类型,需要在数字后加上l或L | -263~263-1 |
float(单精度浮点型) | 定义float类型的变量需要在小数后面追加f或者F | -3.403E38~3.403E38 |
double(双精度浮点型) | \ | -1.798E308~1.798E308 |
boolean(布尔型) | 只有两个取值:true和false,默认值:false | |
char(字符型) | \ | 0~65535 |
1、扩展
1、所有的字符本质还是数字(对应Unicode表里的数字)
char str = '坤';
System.out.println(str+" 这是直接打印");
System.out.println((int)str+" 这是对应的Unicode编码");
结果截图:
2、float类型是: 有限的 离散的 舍入误差 大约 接近但不等于
列如上面的例子,f与d从我们的理解中应该相等,但是由于浮点类型的特性导致不相等 因此 最好避免使用浮点数进行比较
2、类型转换
由于Java是强类型语言,所以要进行有些运算的时候的,需要用到类型转换。
- 运算中,不同类型的数据先转化为同一类型,然后经行运算
- 强制类型转换:强制转换 (类型)变量名 高–>低 容易造成内存溢出
- 自动类型转换:自动转换 低–高
- 不能对布尔值进行转换
- 不能把对象类型转换为不相干的类型
二、运算符
1、逻辑运算符
&&:与 (两个表达式,同真为真)
||:或 (两个表达式,一个为真就为真,同假为假)
!:非 (让表达式从真变成假,或者从假变成了真)
短路:只有 “||” 有短路,当第一个表达式为真时,就为真了,所以不需要在判断其他表达式。
2、三元运算符
用下面列子来解释
(关系表达式) ? 表达式1 : 表达式2;
如果score小于60 则是true,打印不及格;
如果score大于60则是false,打印及格;
三、循环
1、do…while循环
对于while语句而言,如果不满足条件,则不能进入循环。但有时候我们需要即使不满足条件,也至少执行一次。
do…while循环和while循环相似,不同的是,do…while循环至少会执行一次。
2、For循环
格式如下:
for(初始化;布尔表达式;更新){
//代码语句
}
对于For主要是它的执行顺序:
初始化(只执行一次) —–>布尔表达式(判断) —–> 执行代码语句 —–>更新(递增或者递减) —–>布尔表达式 —–> 执行代码语句 —–>更新 … … 一直到不满足 布尔表达式 退出循坏
四、选择结构
1、switch
switch case 语句语法格式如下:
switch(expression){
case value :
//语句
break; //可选
case value :
//语句
break; //可选
//你可以有任意数量的case语句
default : //可选
//语句
}
其中:
switch 也可以用来循环匹配对应的中文,输出对应的结果。
case:具有强穿透性(如果 case 语句块中没有 break 语句时,匹配成功后,从当前 case 开始,后续所有 case 的值都会输出。)
2、break与continue
- break用于跳出一个循环体或者完全结束一个循环,不仅可以结束其所在的循环,还可结束其外层循环。
- 只能在循环体内和switch语句体内使用break
- 不管是哪种循环,一旦在循环体中遇到break,系统将完全结束循环,开始执行循环之后的代码。
- 当break出现在循环体中的switch语句体内时,起作用只是跳出该switch语句体,并不能终止循环体的执行。若想强行终止循环体的执行,可以在循环体中,但并不在switch语句中设置break语句,满足某种条件则跳出本层循环体。
- continue语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。
- continue语句并没有使整个循环终止。
- continue 只能在循环语句中使用,即只能在 for、while 和 do…while 语句中使用。
PS:return用于结束方法的运行
五、方法
1、什么是方法
方法就是是语句的集合,这个集合一起执行能完成某个功能。
方法格式如下:
修饰符 返回值类型 方法名(形式参数类型 形式参数名){
方法体
return 返回值;
}
修饰符:修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。
返回值类型:方法可能会有返回值。returnValueType是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType是关键字void。
方法名: 是方法的实际名称。
参数类型:用于限定调用方法时传入参数的数据类型。
参数名:是一个变量,用于接收调用方法时传入的数据
形式参数: 在方法被调用时用于接收外界输入的数据。
实参: 调用方法时实际传给方法的数据。
方法体: 方法体包含具体的语句,定义该方法的功能。
2、方法的重载
重载就是在一个类中,有相同的函数名称,但形参不同的函数。
方法的重载的规则:
-
方法名称必须相同。
-
参数列表必须不同(个数不同、或类型不同、参数排列顺序不同等)。
-
方法的返回类型可以相同也可以不相同。
-
仅仅返回类型不同不足以成为方法的重载。
实现理论: 方法名称相同时,编译器会根据调用方法的参数个数、参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错
3、可变参数
Jdk1.5开始,Java支持传递同类型的可变参数给一个方法。 在方法声明中,在指定参数类型后加一个省略号 (…)。
一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。
格式如下:
修饰权限 返回类型 方法名(数据类型…变量名){
方法体
return 返回值;
}
eg:
- 形式参数 int… num 可以从实际参数中得到相应的值。这个实际参数有N个。
- 可变参数一般在底层代码中,了解它对于理解底层代码有很大用处。
4、递归
A方法调用B方法,我们很容易理解! 递归就是:A方法调用A方法! 就是自己调用自己
利用递归可以用简单的程序来解决一些复杂的问题。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需少量的程
序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。
递归结构包括两个部分:
-
递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
-
递归体:什么时候需要调用自身方法。
六、数组的定义
1、概念
数组是指相同类型数据的有序集合。
数组元素是通过索引访问的,数组索引从0开始。
数组的四个基本特点:
- 其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
- 其元素必须是相同类型,不允许出现混合类型。
- 数组中的元素可以是任何数据类型,包括基本类型和引用类型。
- 数组变量引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。
2、数组的声明与创建
声明
- dataType[] arrayRefVar; // 首选的方法
- dataType arrayRefVar[]; // 效果相同,但不是首选方法
创建
- arrayRefVar = new dataType[arraySize];
数组变量的声明,和创建数组可以用一条语句完成,如下所示:
dataType[] arrayRefVar = new dataType[arraySize];
int[] num = new int[5]
dataType[] arrayRefVar = {value0, value1, ..., valuek};
int[] num = {1,2,3,4,5}
3、多维数组:
可以看做是数组的数组,如:二维数组的每一个元素都是一个一维数组。
int[][] num={{1,2},{3,4},{5,6},{7,8}};//分别代表num[0],num[1],num[2],num[3]
//其中num.length=4;num[0].length=2。
//num[2][1]=6
内存图:
七、内存分析
JAVA在程序运行时,在内存中划分5片空间进行数据的存储。分别是:1、寄存器。2、本地方法区。3、方法区。4、栈。5、堆。
-
寄存器
-
本地方法区
-
方法区:
- 可以被所有线程共享
- 包含了所有class和static的变量
-
栈(stack):
- 存放基本变量类型(会包含这个类型的具体数值)
- 引用对象的变量(会存放这个引用在堆里面的具体地址)
-
堆(heap):
- 存放new的对象和数组
- 可以被所有的线程共享,不会存放别的对象引用
做图具体分析:
eg1:声明创建数组,并赋值的栈堆图
- 属性引用名(array)存放在栈里面,并指向对应存放地址(new int[]开辟出来的地址)
- 在开辟出来的地址(堆)里面在平均分配地址,用来存放数据
eg2:创建对象内存分析
Application.java
public static void main(String[] args) {
Person student = new Person();
student.name="真新镇小智";
student.age=20;
student.occupation();
System.out.println(student.name);
System.out.println(student.age);
Person teacher = new Person();
}
Person.java
public String name;
public int age;
public void occupation(){
System.out.println("猜猜我是什么职业");
}
栈堆图:
第一步、main()函数是程序入口,JVM先执行,首先将main方法压入栈中。
第二步、在栈内存中开辟一个空间,存放Person类型的引用变量student,在堆中分配一片区域,用来存放和创建Person对象,这片内存区域会有属于自己的内存地址,假设是0x001,然后给成员变量赋值,age=22,name=“真新镇小智” 执行结束后,构造防范弾栈,Person创建完成,将Person的内存地址0x001赋值给person(此处person小写,是引用变量类型)
第三步、在栈内存中开辟一个空间,存放Person类型的引用变量teacher,再在堆中分配一片区域,用来存放和创建Person对象,这片内存区域会有属于自己的内存地址,假设是0x002(这里我就没有在赋值了),这时候变量student与变量teacher同时存在互不影响。