final 和 finally{ },以及“常量池“的特点及区别

final 和 finally{ },以及"常量池"的特点及区别

final

  1. final: Final用于修饰类、成员变量和成员方法

  2. final修饰的类,不能被继承(String、StringBuilder、StringBuffer、Math,不可变类),所以不能同时用abstract和final修饰类(abstract修饰的类是抽象类,抽象类是用于被子类继承的(抽象类被子类继承必须重写父类的抽象方法),和final起相反的作用;

  3. final修饰的方法不能被重写(这里需要注意的是不能被重写,但是可以被重载,这里很多人会弄混),但是子类可以用父类中final修饰的方法;

final修饰的成员变量是不可变的,如果成员变量是基本数据类型,初始化之后成员变量的值不能被改变,如果成员变量是引用类型,那么它只能指向初始化时指向的那个对象,不能再指向别的对象,但是对象当中的内容是允许改变的。
public static void main(String[] args) {
        String a = "shuaige2";
        final String b = "shuaige";
        String d = "shuaige2";
        String c = b + 2;
        String e = d + 2;
        System.out.println((a == c));
        System.out.println((a == e));
    }
}
因上面代码阅读会用到常量池,所以在此补充.
常量池知识点:
常量池分类
常量池大体可以分为:静态常量池,运行时常量池。

静态常量池 存在于class文件中,比如经常使用的javap -verbose中,常量池总是在最前面把?

运行时常量池呢,就是在class文件被加载进了内存之后,常量池保存在了方法区中,通常说的常量池指的是运行时常量池。所以呢,讨论的都是运行时常量池

public class Demo5 {
    public static void main(String[] args) {
        String s1 = "Hello";
        String s2 = "Hello";
        String s3 = "Hel" + "lo";
        String s4 = "Hel" + new String("lo");
        String s5 = new String("Hello");
        String s6 = s5.intern();
        String s7 = "H";
        String s8 = "ello";
        String s9 = s7 + s8;

        System.out.println(s1 == s2);  // true,s1 = = s2 很容易可以判断出来。s1 和 s2 都指向了方法区常量池中的Hello。
        System.out.println(s1 == s3);  // true,s1 = = s3 这里要注意一下,因为做+号的时候,会进行优化,自动生成Hello赋值给s3,所以也是true
        System.out.println(s1 == s4);  // false,s1 = = s4 s4是分别用了常量池中的字符串和存放对象的堆中的字符串,做+的时候会进行动态调用,最后生成的仍然是一个String对象存放在堆中。
        System.out.println(s1 == s9);  // false,s1 = = s9 在JAVA9中,因为用的是动态调用,所以返回的是一个新的String对象。所以s9和s4,s5这三者都不是指向同一块内存
        System.out.println(s4 == s5);  // false,s4和s5是在堆中创建了两个对象,对象的地址不同("=="比较的是地址)
        System.out.println(s1 == s6);  // trues1 = = s6 为啥s1 和 s6地址相等呢? 归功于intern方法,这个方法首先在常量池中查找是否存在一份equal相等的字符串如果有的话就返回该字符串的引用,没有的话就将它加入到字符串常量池中,所以存在于class中的常量池并非固定不变的,可以用intern方法加入新的
    }
}

finally{ }

Java 中的 finally 关键一般与try{},catch{}起使用,无论程序是因为异常而中止或其它方式返回终止的,finally块的内容一定会被执行

在finally代码块中,可以运行清理类型等收尾善后性质的语句
Finally代码块出现在catch代码块最后
当try和catch中有return时,finally仍然会执行;
finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,管finally中的代码怎么样,返回的值都不会改变,任然是之前保存的值),所以函数返回值是在finally执行前确定的;

public class Demo2 {
    public static void main(String[] args) {
        Demo2 t=new Demo2();
        try {
            t.score(103);
        } catch (Demo3 demo3) {//自定义类异常
            //demo3.getMessage();
            demo3.printStackTrace();

        }finally {
            System.out.println("---------------");//这句代码一定会执行
        }


    }
    public void score(int s) throws Demo3 {

        if(s<0||s>100)
        {
            throw  new Demo3("成绩不合法");
        }
        System.out.println("123456789");

        if (s>90){
            System.out.println("优秀");
        }
        if(s<90) {
            System.out.println("不优秀");
        }

    }
}

**注意:**当try语句块捕捉异常时,语句块中如果有显式的thow抛出异常则不能有return.因为编译器认为try块中是又可能产生异常操作的,也就是说在return语句之前如果出现异常的话,那么return语句根本没有机会得到执行,所以编译器会认为缺少return语句.但如果把return写在thow抛出异常前面,那依旧会报错,因为你已经返回了怎么还会有代码继续执行呢.
在这里插入图片描述

解决办法:解决办法:

​ a、在catch块中加入return语句,因为一旦出现异常,catch中的语句可以保证函数会有一个返回值

​ b、在finally块中加入return语句或者在函数末尾加入return语句,我认为此种方法不可行,因为无论哪种,只要系统不退出,finally语句块或函数结尾的return会始终得到执行,这样就会覆盖try块中的return,程序在逻辑上会出现错误!


public class Demo6 {

    static void methodA() {
        try {
            System.out.println("进入方法A");//1
            throw new RuntimeException("制造异常");
        } finally {
            System.out.println("用A方法的finally");
        }
    }

    static int methodB() {
        try {
            System.out.println("进入方法B");
            throw new Exception();
        } catch (Exception e) {
            return 3;
        } finally {
            System.out.println("调用B方法的finally");
            return 2;
        }
    }

    public static void main(String[] args) {
        try {
            methodA();
        } catch (Exception e) {
            //System.out.println(e.getMessage());
        }
        int i = methodB();//2
        System.out.println(i);//6
    } }

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值