java基础知识的一些细节问题

java基础知识中有一些细节问题其实还是挺重要的,如果平时不注意可能就会犯错(面试中也有可能会问到),针对平时遇到的一些java基础知识中的一些细节做一些总结,以后遇到更多,再继续添加。

目录

1.异常机制中的finally

2,一些数学运算引起的异常的差别

3.数组和集合框架中需要注意的细节:


1.异常机制中的finally

finally代码可以跟在try之后或者catch之后,finally内的代码不管有无异常发生,都会执行:具体来说:

如果没有异常发生,在try代码块内的代码执行结束后执行。

如果发生异常且被catch捕获,在catch内的代码执行结束后执行。

如果异常发生但是没有被捕获,则在异常被抛给上层之前执行。

由于finally的这个特点,它一般被用来释放资源,比如数据库连接,文件IO流等;

try...catch...finally语法中,catch不是必须的,可以只有try...finally,不捕获异常,异常自动向上传递,但finally中的代码在异常发生后也执行。

finally语句的执行细节:

如果在try或者catch代码块语句中有return语句,则return语句在finally语句执行结束后才执行,但是finally并不能改变返回值。看一个例子:

package com.xiaomifeng1010.rbacboot.common.util;

/**
 * @author xiaomifeng1010
 * @version 1.0
 * @date: 2020/5/20 23:46
 */

public class JavaDetailTest {
    public static void main(String[] args) {
        System.out.println("执行finallyTest1方法后返回值:"+finallyTest1());
        System.out.println("执行finallyTest2方法后返回值:"+finallyTest2());

    }

    public static int finallyTest1(){
        int inv=0;
        try {
            return inv;
        }finally {
            inv=2;
        }
    }

    public static int finallyTest2(){
        int nv=0;
        try {
            int iv=5/0;
            return nv;
        }finally{
            return 2;
        }
    }
}

运行后:

执行结果,第一种情况,方法的返回值是0,而不是2,实际执行过程是:在执行到try内的return inv;语句前,会先将返回值inv保存在一个临时变量中,然后才执行finally语句,最后try再返回那个临时变量,finally对inv的修改不会被返回,相当于try语句中的return延迟返回了,等finally语句执行完才返回的。

第二种情况比较好理解,第二种情况返回的是2,也就是直接返回了finally语句中的返回值。如果在finally中也有return语句,则try和catch内的return会丢失,实际会返回finally中的返回值。finally中有return不仅会覆盖try和catch中的返回值,还会掩盖try和catch内的异常,就像异常没有发生一样。代码中的5/0会触发ArithmeticException,但是finally中有return语句,这个方法会返回2,而不再向上传递异常了。finally中如果抛出了异常,则原异常也会被掩盖

改造一下第二个方法:

public static int finallyTest2(){
        int nv=0;
        try {
            int iv=5/0;
            return nv;
        }finally{
            throw new RuntimeException("啊哈出错了!");
        }
    }

2,一些数学运算引起的异常的差别

例如代码中出现1.0/0(注意除数是0,被除数是1.0浮点数)会不会抛出异常?

如果是1/0,又会抛出怎样的异常提示?

如果是0.0/0.0呢?

现在在ide工具中演示一下

public class ArithmeticOPerationTest {
    public static void main(String[] args) {
        System.out.println("1.0/0之后的结果:"+1.0/0);
        System.out.println("1/0之后的结果:"+1/0);
        System.out.println("0.0/0.0之后的结果:"+0.0/0.0);
    }
}

执行之后:

第一个输出语句:输出的是Infinity,无限大的意思(数学中的无穷大∞)

第二个输出语句直接抛出了异常,算数异常 /by zero,原因是分母不能为0,因为分子是整形的

因为第二个语句抛出了异常,所以第三句没有执行,现在注释掉第二句,再执行一下:

 

第三句输出为NaN,是不是在JavaScript中有点熟悉 not  a number,不是数字

(控制台中打印了jvm连接和断开信息,是因为idea中安装了jvisualvm的插件,并且配置了路径,刚才启动main方法时点成jvisualvm插件方式启动了,所以就有那两条语句。

3.数组和集合框架中需要注意的细节:

3.1 foreach可以循环遍历数组和集合,但是仅限于遍历集合用于查询,如果要对集合元素进行修改,例如插入和删除,则需要使用原生的迭代器模式来操作。

package com.xiaomifeng1010.rbacboot.common.util;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author xiaomifeng1010
 * @version 1.0
 * @date: 2020/5/21 0:37
 */

public class CollectionDetailTest {
    public static void main(String[] args) {
        List<String> list= new ArrayList<>();
        list.add("xiaomifeng1010");
        list.add("好好学习");
//        做查找(循环遍历时可以用foreach)
        for (String str : list) {
            System.out.println(str);
        }
//        现在再添加一个元素,会报错(这里会抛出ConcurrentModificationException并发修改异常)
        for (String modify :
                list) {
            if ("好好学习".equals(modify)){

                list.add("才能找到好工作");
            }
        }
//        使用迭代器(这里也会抛出ConcurrentModificationException并发修改异常)
        Iterator<String> it=list.iterator();
        while (it.hasNext()){
            if ("好好学习".equals(it.next())){
                list.add("才能找到好工作!");
            }
        }
        System.out.println(list.toString());
    }
}

运行之后:

 将foreach修改list注释掉,使用迭代器修改,第一种迭代器修改也会抛出异常

如果想在遍历的过程中添加元素,可以用ListIterator中的add方法

所以修改一下迭代器

package com.xiaomifeng1010.rbacboot.common.util;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/**
 * @author xiaomifeng1010
 * @version 1.0
 * @date: 2020/5/21 0:37
 */

public class CollectionDetailTest {
    public static void main(String[] args) {
        List<String> list= new ArrayList<>();
        list.add("xiaomifeng1010");
        list.add("好好学习");
//        做查找(循环遍历时可以用foreach)
//        for (String str : list) {
//            System.out.println(str);
//        }
//        现在再添加一个元素,会报错(这里会抛出ConcurrentModificationException并发修改异常)
//        for (String modify :
//                list) {
//            if ("好好学习".equals(modify)){
//                list.add("才能找到好工作");
//            }
//        }
//        使用迭代器(这里也会抛出ConcurrentModificationException并发修改异常)
//        Iterator<String> it=list.iterator();
//        while (it.hasNext()){
//            String str=it.next();
//            if ("好好学习".equals(str)){
//                list.add("才能找到好工作!");
//            }
//        }
//        使用ListIterator
        ListIterator<String> listIterator = list.listIterator();
        while (listIterator.hasNext()){
            String str=listIterator.next();
            if ("好好学习".equals(str)){
//                使用ListIterator中的add方法添加元素
                listIterator.add("才能找到好工作");
            }
        }
        System.out.println(list.toString());
    }
}

3.2 注意Arrays这个工具类中的asList()方法,会返回一个List类型,但是注意,这个返回的List和集合框架中的各种List实现类是不同的,不能对返回的list做add等修改操作:

会抛出异常:不支持的操作

为什么会抛出异常呢?:asList的返回对象是一个Arrays内部类,并没有实现集合的修改方法。Arrays.asList体现的是适配器模式,只是转换接口,后台的数据仍是数组。

修改一下:

可以看到数组元素修改后,list元素也修改了;

再看一下源码:

返回的是一个ArrayList,但是这个ArrayList是Arrays类的内部类,并不是Collection接口下的那个实现类ArrayList

在看一下这个内部类ArrayList相关源码

是没有相关的修改操作的。今天挺晚了,先总结到这里,以后再添加内容吧!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值