• final、finalize()、finally、static


    一、final

    final的三种情况:

    1.变量

      1)对于基本类型,final使数值恒定不变;而对于对象引用,final使引用恒定不变,即一旦引用被初始化指向一个对象,就无法再把它改为指向另一个对象,然而,对象自身却是可以被修改的。

      2)被final修饰的变量是编译期常量。

    1     public static void main(String[] args) {
    2         String s = "sc";
    3         String a = "s";
    4         final String b = "s";
    5         String d = a + "c";
    6         String e = b + "c";
    7         System.out.println(d == s);//false
    8         System.out.println(e == s);//true
    9     }
    View Code

    分析:

    在被使用final修饰的基本数据类型和String的时候,编译器会把它作为编译期常量使用,也就是在编译的时候b就已经作为常量赋值给e了,所以e的值就是一个常量“sc”。

    而d则是在运行期间进行的赋值操作,将对象a赋值给d,虽然他们的值相同,但是他们的对象指针指向已经不相同了,s是在常量池中,而我们的d已经指向生成对象d的指针去了。

    2.方法

    1)把方法锁定,任何继承类都没法修改,也就是无法重写。

    2)“重写”只在某方法是基类的接口的一部分时才会出现,即,必须能将一个对象向上转型为它的基本类型并调用相同的方法。如果某方法为private,它就不是基类的接口的一部分。它仅是一些隐藏于类中的程序代码,只不过是具有相同的名称而已。而父类中的public、protected或包访问权限的方法是不允许被子类重写的,也就是子类中不能有相同名字的方法。例子如下:

    1 class WithFinals {
    2     private final void f();
    3     public final void g();
    4 }
    5 class Son extends WithFinals {
    6     private final void f();
    7     public final void g();//出错,不允许
    8 }
    View Code

    3.类

    1)不允许该类被继承。

     总结:

    1)对于一个final变量,如果是基本数据类型的变量,则其数值一旦在初始化之后便不能更改;如果是引用类型的变量,则在对其初始化之后便不能再让其指向另一个对象。

    2)final方法不能被重写。

    3)final类不能被继承。

    二、finalize()

    finalize():gc准备释放内存时,会先调用finalize()。

    finalize()的主要用途:回收特殊渠道申请的内存。比如JNI调用non-java程序,finalize()会回收这部分内存。

    注意点:

    1)finalize()不能保证会被及时执行。

    2)垃圾回收只与内存有关。

    3)垃圾回收和finalize()在内存还没耗尽时,是不会进行回收的。

    4)finalize()线程的优先级比普通线程要低。

    如果类的对象中封装的资源确实需要钟执,可以提供一个显式的终止方法,该方法通常与try-finally结合起来使用,以确保及时终止。

    具体可以查看<<effective java>>中的第6条。

    三、finally

    结论:

    1、无论在什么情况下,finally块中代码都会执行。
    2、finally是在return后面的表达式运算完成后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,然后执行finally语句块,如果finally中有return,则返回的值会被改变)。

    举例:

     1 情况1:try{} catch(){}finally{} return;
     2 显然程序按顺序执行。
     3 
     4 
     5 情况2:try{ return; }catch(){} finally{} return;
     6 程序执行try块中return之前(包括return语句中的表达式运算)代码;
     7 再执行finally块,最后执行try中return;
     8 finally块之后的语句return,因为程序在try中已经return所以不再执行。
     9 
    10 
    11 情况3:try{ } catch(){return;} finally{} return;
    12 程序先执行try,如果遇到异常执行catch块,
    13 有异常:则执行catch中return之前(包括return语句中的表达式运算)代码,再执行finally语句中全部代码,
    14 最后执行catch块中return. finally之后也就是4处的代码不再执行。
    15 无异常:执行完try再finally再return.
    16 
    17 
    18 情况4:try{ return; }catch(){} finally{return;}
    19 程序执行try块中return之前(包括return语句中的表达式运算)代码;
    20 再执行finally块,因为finally块中有return所以提前退出。
    21 
    22 
    23 情况5:try{} catch(){return;}finally{return;}
    24 程序执行catch块中return之前(包括return语句中的表达式运算)代码;
    25 再执行finally块,因为finally块中有return所以提前退出。
    26 
    27 
    28 情况6:try{ return;}catch(){return;} finally{return;}
    29 程序执行try块中return之前(包括return语句中的表达式运算)代码;
    30 有异常:执行catch块中return之前(包括return语句中的表达式运算)代码;
    31 则再执行finally块,因为finally块中有return所以提前退出。
    32 无异常:则再执行finally块,因为finally块中有return所以提前退出。
    33 
    34 最终结论:任何执行try 或者catch中的return语句之前,都会先执行finally语句,如果finally存在的话。
    35 如果finally中有return语句,那么程序就return了,所以finally中的return是一定会被return的,
    36 编译器把finally中的return实现为一个warning。
    View Code

    Exception(异常) 
    是程序本身可以处理的异常。主要包含RuntimeException等运行时异常和IOException,SQLException等非运行时异常。 
    运行时异常 包括:都是RuntimeException类及其子类异常,如NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)等,这些异常是不检查异常,程序中可以选择捕获处理,也可以不处理。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。 
    运行时异常的特点是Java编译器不会检查它,也就是说,当程序中可能出现这类异常,即使没有用try-catch语句捕获它,也没有用throws子句声明抛出它,也会编译通过。 
    非运行时异常(编译异常) 包括:RuntimeException以外的异常,类型上都属于Exception类及其子类。从程序语法角度讲是必须进行处理的异常,如果不处理,程序就不能编译通过。如IOException、SQLException等以及用户自定义的Exception异常,一般情况下不自定义检查异常

    程序运行时异常由Java虚拟机自动进行处理。捕获到的异常不仅可以在当前方法中处理,还可以将异常抛给调用它的上一级方法来处理。

    捕获异常时,先捕获子类异常,再捕获父类异常。

    四、static

    1.static方法中不能直接处理非static变量,但可以通过对象调用处理,比如main方法。

    2.static方法不能被子类重写。

    3.static代码块只在类第一次加载时初始化一次。

    4.static方法无论是类调用还是对象调用,都是类调用其实,比如Test test = null;test.hello()编译通过,且正确运行,因为test.hello()相当于Test.hello()。而引用不同于指针,引用中既包含指向对象的指针、又包含指向类的指针,test中指向对象的指针确实为空,但指向Test的指针可不为空啊。

  • 相关阅读:
    Windows7与Window2008 64位IIS7上面DCOM配置Excel、Word
    C#连接SQLite的...方法
    VS2010版快捷键
    ajax 安装包下载
    Type InvokeMember()用法简介
    Lambda表达式
    多源最短路径算法
    单源点有权图的最短路径算法
    单源无权图的最短路径算法
    Tree Traversals Again
  • 原文地址:https://www.cnblogs.com/cing/p/8193812.html
Copyright © 2020-2023  润新知