1.什么是NPE,什么情况下会发生NPE
什么是NPE
NPE(java.lang.NullPointerException): 空指针异常。
NPE容易发生的场景
1.返回类型为基本数据类型,return 包装数据类型的对象时,自动拆箱有可能产生 NPE。
2.数据库的查询结果可能为 null。
3.集合里的元素即使 isNotEmpty,取出的数据元素也可能为 null。
4.远程调用返回对象时,一律要求进行空指针判断,防止 NPE。
5.对于Session中获取的数据,建议进行 NPE检查,避免空指针。
6.级联调用 obj.getA().getB().getC();一连串调用,易产生 NPE
如何减少NPE的发生呢?
1.遵守代码规范
一个好的代码规范可以在一定程度上减少错误的发生。这里推荐看阿里巴巴的Java开发手册,现已经更新到泰山版了,可以直接去官网下载来看。
2.使用Optional类
使用JDK8引入的新特性Optional 类来防止NPE 问题,因为Optional类最主要解决的问题就是NPE。
3.空值检测
使用if(obj == null)来检测我们需要检测的对象,当检测到Null时,则可以抛出针对性的异常类型。
如何防止NPE?当你使用指针进行操作的时候,如果不确定指针是否为null应该对指针做非空判断,判断指针为nu11时,使用new关键字开辟内存空间if(指针==null){指针=new.
2. new关键字的作用
1. 充当运算符的作用, 实例化对象和调用构造函数
2. 充当修饰符的作用,隐藏基类成员
3. 充当约束
New关键字:
- 用于在堆区造数组
new数据类型[长度]
数组的构造器是系统默认就有的,
任何一种数据类型都可以使用数组构造器来构造数组
例如new int[]
2.用于在堆区造对象
new构造方法()
对象的构造器是类里面提供的
例如:new student();
这个new后面的student()是一种构造方法,
是编译器给你自动生成的,在字节码文件中可以看到它
对象的构造方法可以自定义
1构造方法使用public修饰
2构造方法没有返回值类型(连void都没有)
3构造方法的名字必须与当前类名相同
4构造方法的内部有一个特殊的this指针,指向当前对象
5如果一个类没有手动指定构造方法,编译器会提供一个默认的无参的构造方法,
如果手动指定构造方法,则编译器不在提供默认的无参的构造方法
3.数组和对象的区别
数组的构造器是系统默认就有的,
对象的构造器是类里面提供的
数组表示有序数据的集合,而对象表示无序数据的集合。如果数据的顺序很重要,就用数组,否则就用对象。
数组和对象的另一个区别是,数组的数据没有”名称”(name),对象的数据有”名称”(name)。
4.基本数据类型对应的引用数据类型
5.正序遍历数组,倒序遍历数组
public static void iterator(){
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
System.out.println(",");
}
}
public static void reverse(){
for (int i = arr.length-1; i > 0; i--) {
System.out.println(arr[i]);
System.out.println(",");
}
}
6.数组求和
public static void sum(){
int sum=0;
for (int i = 0; i < arr.length; i++) {
if(arr[i]==null){
break;
}
sum +=arr[i];
}
System.out.println("arr元素累加之和:"+sum);
}
7.数组求最大值和最小值
public static void max(){
int max=arr[0];
for (int i = 0; i < arr.length; i++) {
if(arr[i]==null){
break;
}
if(arr[i]>max){
max=arr[i];
}
}
System.out.println("arr中数组最大数是:"+max);
}
public static void min(){
int min=arr[0];
for(int i=1;i
8.数组求平均数
public static void avg(){
int sum=0;
for(int i=0;i
9.数组扩容的策略
(1)创建新数组
(2)把原数组的元素转移到新数组中
(3)把新数组的地址赋给原数组的指针
public static void dilatation(){
System.out.println("原数组长度:"+arr.length);
Integer[] newarr=new Integer[arr.length+arr.length/2];
for (int i = 0; i < arr.length; i++) {
newarr[i]=arr[i];
}
arr=newarr;
System.out.println("扩容后的长度:"+arr.length);
}
10.数组中插入元素
1.在数组中指定位置插入元素,要把指定位置之后的元素全部向后移一位(包括指定位置)
2.这样的话数组原来的长度就不够了,因此我们要先对数组进行扩容
3.创建一个新的数组,创建新数组,把原数组的元素转移到新数组中,把新数组的地址赋给原数组的指针
4.找到数组中第一个空的位置
5.从第一个空的位置开始向后移
6.对数组进行遍历打印结果
public static void insert(int insert,int e){
//1.找到数组中第一个空的位置
int empty=-1;
for (int i = 0; i < arr.length; i++) {
if(arr[i]==null){
empty=i;
break;
}
}
//2从第一个空的位置往后移
for (int i = empty; i >insert; i--) {
arr[i]=arr[i-1];
}
arr[insert]=e;
iterator();
}
}
11.数组中删除元素
1.删除指定的元素之后要把删除元素后面的所有元素数据向前移一位
2.做了一个for循环,把从指定的索引开始往后的数据的值赋给前一位
3.把最后一位的数据的值变成0(因为创建的数组是int类型)
4.对数组进行遍历打印结果
删除的方法。大致的分类可以分为如下几类:
1、length
2、delete
3、栈方法
4、队列方法
5、操作方法
6、迭代方法
7、原型方法
12.反转数组
1.把最后一个元素的数据赋值给第一个元素,把倒数第二个元素的数据赋值给第二个元素,依次类推
2.创建一个新的数组接受新的数据
3.把新的数组地址给旧的数组的指针
4.遍历旧的数组把结果打印出来
- 2
1. 使用 slice 和 reverse
2. 使用 ...扩展运算符 和 reverse
3. 使用 reduce 和 ...扩展运算符
4. 使用 reduceRight 和 ...扩展运算符
5. 或者使用push
13.使用冒泡排序算法排序数组
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
针对所有的元素重复以上的步骤,除了最后一个。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
所谓冒泡排序,即是对于一个给定长度为n的无序数组,由初始位置开始,比较数组相邻两个元素,如果是逆序排列的,就交换它们的位置,重复多次之后,最大数就“沉”到了最下面的位置。
14.官方的Arrays工具类
Arrays 类是一个工具类,其中包含了数组操作的很多方法。 这个 Arrays 类里均为 static 修饰的方法(static 修饰的方法可以直接通过类名调用),可以直接通过 Arrays.xxx (xxx) 的形式调用方法。
没有构造,方法全是静态
15.二维数组
二维数组定义的一般形式为:
类型说明符 数组名[ 常量表达式][ 常量表达式];
二维表由行和列组成
行和列由单元格组成
16.类和对象
类(class)和对象(object)是两种以计算机为载体的计算机语言的合称。对象是对客观事物的抽象,类是对对象的抽象。类是一种抽象的数据类型。
它们的关系是,对象是类的实例,类是对象的模板。对象是通过new classname产生的,用来调用类的方法;类的构造方法 。
17.成员变量
成员变量:
这类变量在类的里面,函数的外面
这些变量没有使用static修饰
成员变量不能使用类名
静态变量可以使用类名操作
18.构造方法
构造方法有以下特点:
- 方法名必须与类名相同
- 可以有 0 个、1 个或多个参数
- 没有任何返回值,包括 void
- 默认返回类型就是对象类型本身
- 只能与 new 运算符结合使用
19.成员方法
成员方法就是对象所具有的动态功能。 基本格式如下: 访问修饰符:public(公共的);protected(受保护的);无修饰符和private(私有的)。 修饰符:对属性特征的描述:如static,final,abstract 等等。 返回值类型:方法返回数据的类型。 方法名称:任何合法标识符。 参数:可以有多个,使用逗号分隔。 方法体:该方法具体实现功能的地方。 构造函数:是特殊的成员方法,他的作用是创建对象并初始化成员变量。 构造函数定义规则:构造方法的方法名,必须和类名一致。 每个类都有一个隐藏的无参构造函数。
20. this 关键字
this关键字的作用有两个:
1.当成员变量与局部变量同名时,用来区分成员变量和局部变量;
2.在构造函数中调用构造函数。
哪一个指针调用成员方法入栈执行,那么栈帧中的this就指向哪个对象
、
21.什么是零值
零值是指当你声明变量(分配内存)并未显式初始化时,始终为你的变量自动设置一个默认初始值的策略。



