福州思企互联网站建设公司怎么样,哪里有网站开发定制,企业融资的10种方法,网站收录了但是搜索不到典型回答
final 可以用来修饰类、方法、变量#xff0c;分别有不同的意义#xff0c;final 修饰的 class 代表不可以继承扩展#xff0c; final 的变量是不可以修改的#xff0c;而 final 的方法也是不可以重写的#xff08;override#xff09;。
finally 则是 Java 保…典型回答
final 可以用来修饰类、方法、变量分别有不同的意义final 修饰的 class 代表不可以继承扩展 final 的变量是不可以修改的而 final 的方法也是不可以重写的override。
finally 则是 Java 保证重点代码一定要被执行的一种机制。我们可以使用 try - finally 或者 try - catch - finally 来进行类似关闭 JDBC 连接、保证 unlock 锁等动作。
finalize 是基础类 java.lang.Object 的一个方法它的设计目的是保证对象被垃圾收集前完成特定资源的回收。finalize 机制现在已经不推荐使用并且在 JDK9 开始被标记为 deprecated。
知识扩展
关于 final
final 是一个非访问修饰符仅适用于变量方法或类。
final 修饰变量
当使用 final 关键字声明类成员变量或局部变量后其值不能被再次修改也经常和 static 关键字一起作为 类常量 使用。 很多时候会容易把 static 和 final 关键字混淆static 作用于成员变量用来表示只保存一份副本而 final 的作用是用来保证变量不可变。 如果 final 变量是引用这意味着该变量不能重新绑定到引用另一个对象但是可以更改该引用变量指向的对象的内部状态即可以从 final 数组或 final 集合中添加或删除元素。最好用全部大写来表示 final 变量使用下划线来分隔单词。
//一个final成员常量
final int THRESHOLD 5;
//一个空的final成员常量
final int THRESHOLD;
//一个静态final类常量
static final double PI 3.141592653589793;
//一个空的静态final类常量
static final double PI;初始化final变量
我们必须初始化一个final变量否则编译器将抛出编译时错误。final 变量只能通过初始化器或赋值语句初始化一次。初始化 final 变量有三种方法
可以在声明它时初始化 final 变量。这种方法是最常见的。如果在声明时未初始化则该变量称为空 final 变量。下面是初始化空 final 变量的两种方法。可以在 instance-initializer 块 或内部构造函数中初始化空的final变量。如果您的类中有多个构造函数则必须在所有构造函数中初始化它否则将抛出编译时错误。可以在静态块内初始化空的 final 静态变量。
这里注意有一个很普遍的误区。很多人会认为 static 修饰的 final常量必须在声明时就进行初始化否则会报错。但其实则不然我们可以先使用 static final 关键字声明一个类常量然后再在静态块内初始化空的 final 静态变量。
何时使用 final 变量
普通变量和 final 变量之间的唯一区别是我们可以将值重新赋值给普通变量但是对于 final 变量一旦赋值我们就不能改变 final 变量的值。因此final 变量必须仅用于我们希望在整个程序执行期间保持不变的值。
final 修饰类
当使用 final 关键字声明一个类时它被称为 final 类。被声明为 final 的类不能被扩展继承。final 类有两种用途
一个是彻底防止被继承因为 final 类不能被扩展。例如所有包装类如 IntegerFloat 等都是 final 类。我们无法扩展它们。final 类的另一个用途是创建一个类似于 String 类的不可变类。只有将一个类定义成为 final 类才能使其不可变。
Java支持把 class 定义成 final似乎违背了面向对象编程的基本原则但在另一方面封闭的类也保证了该类的所有方法都是固定不变的不会有子类的覆盖方法需要去动态加载。这给编译器做优化时提供了更多的可能最好的例子是 String它就是 final类Java 编译器就可以把字符串常量那些包含在双引号中的内容直接变成 String 对象同时对运算符 “” 的操作直接优化成新的常量因为 final 修饰保证了不会有子类对拼接操作返回不同的值。
final关键字在效率上的作用主要可以总结为以下三点
缓存final 配合 static 关键字提高了代码性能JVM和Java应用都会缓存 final 变量。同步final 变量或对象是只读的可以安全的在多线程环境下进行共享而不需要额外的同步开销。内联使用 final 关键字JVM会显式地主动对方法、变量及类进行内联优化。
关于 finally
try 关键字最后可以定义 finally 代码块。 finally 块中定义的代码总是在 try 和任何 catch 块之后、方法完成之前运行。
正常情况下不管是否抛出或捕获异常 finally 块都会执行。
啥时候 finally 不会被执行
尽管通常编写 finally 代码块是为了这段代码一定被执行到但是也有一些特殊情况会导致 JVM 不会执行 finally 代码块。
如果操作系统中断了我们的程序那么 finally 代码块可能就不能被执行。也有很多其他类似的行为导致 finally 代码块不被执行。
调用 System.exit 函数
try {System.out.println(Inside try);System.exit(1);
} finally {System.out.println(Inside finally);
}结果 Inside try调用 halt 函数
try {System.out.println(Inside try);Runtime.getRuntime().halt(1);
} finally {System.out.println(Inside finally);
}结果 Inside try守护线程
如果守护线程刚开始执行到 finally 代码块此时没有任何其他非守护线程那么虚拟机将退出此时 JVM 不会等待守护线程的 finally 代码块执行完成。
Runnable runnable () - {try {System.out.println(Inside try);} finally {try {Thread.sleep(1000);System.out.println(Inside finally);} catch (InterruptedException e) {e.printStackTrace();}}
};
Thread regular new Thread(runnable);
Thread daemon new Thread(runnable);
daemon.setDaemon(true);
regular.start();
Thread.sleep(300);
daemon.start();输出 Inside tryInside tryInside finallytry 代码块中无限循环
try {System.out.println(Inside try);while (true) {}
} finally {System.out.println(Inside finally);
}try 代码块出现无限循环且不出现异常finally 也将永远得不到执行。
常见陷阱
忽视异常
finally 代码块包含返回语句没有处理未捕获的异常。
try {System.out.println(Inside try);throw new RuntimeException();
} finally {System.out.println(Inside finally);return from finally;
}此时try 代码块中的 RuntimeException 会被忽略函数返回 from finally字符串。
覆盖其他返回语句
如果 finally 代码块中存在返回语句则 try 和 catch 代码块如果存在返回语句就会被忽略。
try {System.out.println(Inside try);return from try;
} finally {System.out.println(Inside finally);return from finally;
}此段代码总是返回 “from finally” 。
改变 throw 或 return 行为
如果再 finally 代码块中扔出异常则 try 和 catch 中的异常扔出或者返回语句都将被忽略。
try {System.out.println(Inside try);return from try;
} finally {throw new RuntimeException();
}这段代码永远都不会有返回值总是会抛出 RuntimeException。