- 浏览: 1324559 次
- 性别:
- 来自: 湖南澧縣
文章分类
最新评论
-
虾米小尹:
不行啊!2.2-0.25=1.9500000000000002 ...
JavaScript浮点数运算 —— 精度问题 -
heluping000000:
引用String a= "abc",首先在 ...
String,到底创建了多少个对象? -
mack:
谢谢分享matcher.appendReplacement(s ...
string.replaceAll()中的特殊字符($ \)与matcher.appendReplacement -
wzt3309:
完全理解,比网上其他资料都要详细
String,到底创建了多少个对象? -
u014771876:
Java中十六进制转换 Integer.toHexString()
final关键字
先看看final关键字,它可以被用于以下几个地方:
1、修饰属性、局部变量、方法参数:
如果final修饰的是一个基本类型,就表示这个变量所赋予的值不可修改,即它是个常量;如果final修饰的是一个对象,就表示这个变量被赋予的引用不可修改(但我们可以修改该引用所指向对象里的内容,这里所说的不可修改是指final修改的引用一但指向了谁,就不能再指向别的对象了)。下面来看看修改属性与变量时需要注意的几点:
在方法中定义的内部类只能访问方法中的final类型的局部变量,因为用final定义的局部变量是一个常量,运行时不是放在栈里的,因此它的生命同期超出了方法运行的生命周期:
//final不能去掉,否则编译通不过 public Comparable f(final Comparable o1) { return new Comparable() { public int compareTo(Object o2) { return o1.compareTo(o2); } }; }
final修改的静态属性,必须在声明的同时或者在静态块中初始化;final修饰的非静态属性,必须在声明的同时、或非静态块中或者是构造函数中初始化:
public class A { private final int a = 1;//非静态属性在定义时初始化 private final static int b = 1;//静态属性在定义时初始化 private final int c;//非静态属性在定义时未初始化 { //非静态属性在非静态块中初始化 c = 1; } private final static int d;//静态属性在定义时未初始化 static { //静态属性在静态块中初始化 d = 1; } private final int e;//非静态属性在定义时未初始化 A() { //非静态属性在构造函数中初始化 e = 1; } }
静态属性不能在非静态块中初始化 (因为非静态块是在new时才调用,而静态属性在对象还没有创建时也能使用,所以有可能还未初始化就使用了,也还有可能初始化多次),当然非静态属性更不能在静态块中、构造函数中初始化(因为在静态块中不能访问非静态属性、变量及方法):
public class A { private final int a;//!! 非静态属性未初始化 private final static int b;//!! 静态属性未初始化 private final int c; static { //!! 非静态属性不能在静态块中初始化 c = 1; } private final static int d; { //!! 静态属性在非静态块中初始化 d = 1; } private final static int e; A() { //!! 静态属性不能在构造函数中初始化 e = 1; } }
接口中的属性成员默认就是 public final static,只能在定义时就初始化:
package A; public interface A { //接口中的属性成员默认就是 public final static int i = 1; // !! 接口中的访问修饰符只能是 public ,但可不写 //protected int a = 1; // !! 接口中的属性只能在定义时就初始化 // public static final b; // !! 接口中的属性是常量,不能在静态块与非静态块中初始化,因为接口中不能有静态块与非静态块 // static{ // b=1; // } // { // b=1; // } } package B; import A.A; public class B { public static void main(String[] args) { // !! 不能修改,因为接口中的定义的属性默认就是final //A.i = 2; //接口中的定义的属性默认就是public static,因为可以被不同包静态访问 System.out.println(A.i); } }
这里提到了静态区与非静态区,它们的区别是,静态区在类装载时执行一次,而非静态区每在实例化一个对象时就执行一次:
public class A { static { System.out.println("static block"); } { System.out.println("block"); } public static void main(String[] args) { new A(); new A(); } /* output: static block block block */ }
另外,用final修饰的变量会有更高的效率,如果一个变量不在变化时,那么它就应该定义成常量,所以在需要的地方我们尽量使用常量,因为这样在编译时期就能确定。
2、修饰方法:
被final修改的方法不能被覆写。
class A { public final void f() {} } class B extends A { // !! 不能覆写final方法 // public void f() {} // public final void f() {} }
private方法默认就是final方法,编译器在处理private方法时,是按照final方法来对待的,这样可以提高该方法被调用时的效率。
3、修饰类
final类不允许被继承(如果String类),编译器在处理时把它的所有方法都当作final的(但数据成员既可以是final,也可以不是,以定义时前面修饰为准),因此final类比普通类拥有更高的效率:
final class A { //注,final中的属性可以是final,也可以不是,以定义时前面修饰为准 int i = 1; public final void f() {} //final类中的所有方法默认就是final方法 void m() {} } // !! final 类不能继承 //class B extends A {} public class C { public static void main(String[] args) { A a = new A(); a.i = 2;//可以修改final类的非final属性成员 } }
接口与抽象类不能用final来修饰,即final interface、final abstract class是不允许的:
// !! 接口不能用final来修饰 public final interface A {} // !! 抽象类不能用final来修饰 public final abstract class A {}
finally关键字
finally关键字用在try/catch语句最末,表示不管是否抛出异常,finally块中的语句最终肯定、一定会被执行,执行的顺序为 try块 —> finally块(不抛异常情况下)或 try块 —> catch块(抛异常情况下)—> finally块 :
try {//不抛异常情况下 System.out.println("try"); } catch (Exception e) { System.out.println("catch"); } finally { System.out.println("finally"); } /* output: try finally */ try {//抛异常情况下 System.out.println("try"); throw new NullPointerException(); } catch (NullPointerException e) { System.out.println("catch"); throw e;//再次抛出 } finally { //不管是try块还是catch块里抛异常,finally块最后一定会执行 System.out.println("finally"); } /* output: try catch finally */
下面看看try、catch、finally有return语句时,到底从哪里返回:
class A { public static void main(String[] args) { System.out.println(A.f1());//3 System.out.println(A.f2());//2 try { System.out.println(A.f3());//方法异常结束 } catch (Exception e) { e.printStackTrace(); } System.out.println(A.f4());//1 System.out.println(A.f5());//4 try { System.out.println(A.f6());//方法异常结束 } catch (Exception e) { e.printStackTrace(); } } /* * 如果 finally 块中有 return 语句,则忽略 try、catch 块中的retrun , * 但 finally 中有return不是一种好的编程方式,这样会引起编译时警告 */ public static int f1() { System.out.println("--f1()--"); try { System.out.println("f1 - 1"); nullExcp();//抛空指针异常 return 1; } catch (NullPointerException e) { System.out.println("f1 - 2"); return 2; } finally { System.out.println("f1 - 3"); return 3;//从这里返回 } /* * !! 这里不能有语句,因为方法在此前已从finally块中返回,或者finally 块中已抛 * 异常后方法结束,但要注意的是,不管catch块中是否抛异常,最会执行finally块 */ // return 4; } /* * 如果 finally 块中没有 return 语句,但 try、catch 块中有时,如果try中不抛 * 异常,则从try语句块中正常返回,如果try中抛出异常,则从catch块中正常返回或者 * catch抛出异常时方法异常结束 */ public static int f2() { System.out.println("--f2()--"); try { System.out.println("f1 - 1"); nullExcp();//抛空指针异常 return 1; } catch (NullPointerException e) { System.out.println("f1 - 2"); return 2;//从这里返回 } finally { System.out.println("f1 - 3"); } /* * !! 这里也不能有其他语句了,因为到此方法已经正常或异常结束了 */ // return 4; } //try与catch块都抛异常,最后方法在执行完finally块后从catch块中异常结束 public static int f3() { System.out.println("--f3()--"); try { System.out.println("f1 - 1"); nullExcp();//抛空指针异常 return 1; } catch (NullPointerException e) { System.out.println("f1 - 2"); nullExcp();//抛空指针异常,从这里方法异常结束 return 2; } finally { System.out.println("f1 - 3"); } /* * !! 这里也不能有其他语句了,因为到此方法已经正常或异常结束了 */ // return 4; } //这是我们通常写法,只在try或最后返回结果:正常从try中返回 public static int f4() { System.out.println("--f4()--"); try { System.out.println("f1 - 1"); return 1;//从这里返回 } catch (NullPointerException e) { System.out.println("f1 - 2"); } finally { System.out.println("f1 - 3"); } return 4; } //这是我们通常写法,只在try或最后返回结果:异常后从最后返回 public static int f5() { System.out.println("--f5()--"); try { System.out.println("f1 - 1"); nullExcp();//抛空指针异常 return 1; } catch (NullPointerException e) { System.out.println("f1 - 2"); } finally { System.out.println("f1 - 3"); } return 4;//从这里返回 } public static int f6() { System.out.println("--f6()--"); try { System.out.println("f1 - 1"); nullExcp();//抛空指针异常 return 1; } catch (NullPointerException e) { System.out.println("f1 - 2"); nullExcp();//抛空指针异常,从这里方法异常结束 } finally { System.out.println("f1 - 3"); } return 4; } private static void nullExcp() { throw new NullPointerException(); } }
从上面例子可以看出return语句是不会阻止finally块执行的,那么continue和break能否阻止?答案是不会的,与return一样,finally语句块是在循环被跳过(continue)和中断(break)之前被执行的:
class A { public static void main(String[] args) { int i = 0; System.out.println("--continue--"); while (i++ <= 1) { try { System.out.println("i=" + i); continue; } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("finally"); } } System.out.println("--break--"); while (i++ <= 3) { try { System.out.println("i=" + i); break; } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("finally"); } } } }
finalize关键字
finalize()是Object类的一个方法,finalize()方法是GC(garbage collector)运行机制的一部分,由对象的垃圾回收器调用此方法,当一个对象被回收时,finalize()方法将会被调用。但我们要注意的是,如果 finalize 方法抛出未捕获的异常,那么该异常将被忽略,并且该对象的终结操作将终止:
protected void finalize() throws Throwable { System.out.println("finalize"); } public static void main(String[] args) { A a = new A(); a = null; //加快GC回收,但不一定马上执行加收动作,由虚拟机决定 System.gc(); //System.gc()实质上与下面等同 //Runtime.getRuntime().gc(); // 该方法虚拟机也只是尽最大努力去完成所有未执行的终止方法,不一定会执行 //System.runFinalization(); /* * !! 该方法一定会回收,但不安全,已被废弃。因为它可能对正在使用的对象调用终结方法,而 * 其他线程同时正在操作这些对象,从而导致不正确的行为或死锁 */ // System.runFinalizersOnExit(true); }
发表评论
-
Java正则表达式
2014-03-14 10:16 1708Java正则表达式详解 作者:jzj 文 ... -
类的初始化与清理
2013-06-24 22:20 1402初始化时内存清零 当创建一个对象时,首先将在堆上为这个对象分 ... -
protected,这个错了吗?
2013-06-24 22:17 1186这几天对protected修饰符有点迷糊,随便找同事要了一本 ... -
Java中BigDecimal的8种舍入模式
2013-06-21 18:42 2134java.math.BigDecimal不可变的、任意精度的 ... -
Tomcat性能参数设置
2010-12-27 15:35 34684默认参数不适合生产环境使用,因此需要修改一些参数 1、 ... -
Java 6 JVM参数选项大全
2010-12-14 11:16 1588http://kenwublog.com/docs/java6 ... -
对象的安全构造
2013-06-21 18:43 1500在构造期间,不要公布“this”引用 一种可以将数据争用引 ... -
Java断言(assert)—— 转
2010-06-20 10:36 12026一、概述 在C和C++语言中都有assert关键,表示断言。 ... -
eclipse调试
2010-06-04 00:11 7995eclipse远程调试 在eclipse3.4前,远程调试时 ... -
protected,你真的理解了吗?
2010-05-09 17:56 2078Java中的访问控制修饰符有四个级别,但属protected最 ... -
利用反射进行深层克隆
2010-05-05 21:02 3621最近在看《effective java ... -
类与类之间的几种关系
2010-05-03 13:49 2369类和类、类和接口、接 ... -
运行java
2010-05-03 13:47 1007用javac命令编译一个打包的类时,如果没有加参数" ... -
Java内存模型与volatile
2010-04-25 13:21 18481内存模型描述的是程序 ... -
中断线程
2010-04-24 21:19 8903中断线程 线程的thread.i ... -
java中的关键字、保留字、标示符
2010-04-07 23:48 3324关键字 Java的关键字对java的编译器有特殊的意义, ... -
Java中的浮点数剖析
2010-04-07 23:27 4647定点数表达法的缺点在于其形式过于僵硬,固定的小数点位置决定了固 ... -
线程间的同步与互斥
2010-03-23 21:29 2258线程间的同步(实指线程间的通信):一般来说,一个线程相对于另 ... -
UTF-16、UTF-16BE、UTF-16LE编码方式的区别
2010-03-23 21:20 9686import java.io.IOException; ... -
方法能重写,属性能重写吗?
2010-01-22 00:56 6897覆写是多态的一种表现,我们平时所说的覆写一般是针对方式来说,在 ...
相关推荐
final, finally, finalize的区别
一,谈谈final, finally, finalize的区别。 java面试题
Java中final,finally,finalize三个关键字的区别_动力节点Java学院整理
对于Java中final、finally、finalize的有关问题做下的思维导图,便于深化记忆,希望对你有帮助!注意:文件为.mm后缀建议下载freemind打开,免费的思维导图软件!
主要介绍了详解Java编程中final,finalize,finally的区别,这个在Java面试题中简直是太常见了...需要的朋友可以参考下
final:修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为 父类被继承。因此一个类不能既被声明为abstract 的,又被声明为final 的。将变量或 方法声明为 final,可以保证它们在...
主要介绍了java 基础之final、finally和finalize的区别的相关资料,需要的朋友可以参考下
final 是 Java 中的关键字,它也是 Java 中很重要的一个关键字,final 修饰的类、方法、变量有不同的含义;finally 也是一个关键字,不过我们可以使用 finally 和其他关键字结合做一些组合操作; finalize 是一个不...
Java中final、finally、finalize的区别与用法,困扰了不少学习者,下面我们就这个问题进行一些探讨,希望对大家的学习有所帮助。
1. 注意,final 不是 immutable 2.finalize 真的那么不堪 3. 有什么机制可以替换 finalize 吗
List 和 Set 的区别,final finally finalize,Java获取反射的三种方法,Arrays.sort 和 Collections.sort 实现原理 和区别
以下是对final,finally,finalize的区别进行了详细的分析介绍,需要的朋友可以过来参考下
hi 大家好,今日,天气剧变,非常冷,不想出门,于是给大家写了篇文章,关于android final关键字及final,finally,finalize的区别相关知识,具体详情如下所示: 先预告一下,下文中仅涉及java语法的讨论,和Android...
finally finalize 反射 序列化与反序列化 transient 枚举 注解 JDK7新特性 JDK8新特性 JDK9新特性 JDK10新特性 运行时数据区 对象 OOM & SOF 内存模型 垃圾回收算法 垃圾收集器 内存分配与回收策略 类加载 参数优化 ...
1. 注意,final 不是 immutable 2.finalize 真的那么不堪 3. 有什么机制可以替换 finalize 吗
很好的Java面试题第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?
Java 中的 final、finally 和 finalize 关键字有什么区别? final:当用“final”关键字声明一个变量时,它的值一旦被赋值就不能改变。当使用“final”关键字声明方法时,它不能在子类中被覆盖。当用“final”...
《计算机基础》期末复习参考题(夜大)仅供参考