- 浏览: 152420 次
- 性别:
- 来自: 南京
文章分类
最新评论
-
chen_zujun:
java Object生成实例的new和newInstance的区别? -
honey00125:
感谢楼主分享!
JQuery权威指南源代码整理下载 -
Jojay90:
真的不错, 谢谢此分享!
JQuery权威指南源代码整理下载 -
wjyuian:
感谢楼主,好资料,,下了看看
JQuery权威指南源代码整理下载 -
toefllitong:
感谢楼主的分享,支持越来越多的人分享
JQuery权威指南源代码整理下载
一、java
作用域public ,private
,protected
及不写时的区别
在说明这四个关键字之前,我想就class之间的关系做一个简单的定义,对于继承自己的class,base class可以认为他们都是自己的子女,而对于和自己一个目录下的classes,认为都是自己的朋友。
1、public:public表明该数据成员、成员函数是对所有用户开放的,所有用户都可以直接进行调用
2、private
:private
表示私有,私有的意思就是除了class自己之外,任何人都不可以直接使用,私有财产神圣不可侵犯嘛,即便是子女,朋友,都不可以使用。
3、protected
:protected
对于子女、朋友来说,就是public的,可以自由使用,没有任何限制,而对于其他的外部class,protected
就变成private
。
作用域 当前类 同一package 子孙类 其他package
public √ √ √ √
protected
√ √ √ ×
friendly √ √ × ×
private
√ × × ×
不写时默认为friendly
二、final、finally和finalize的区别是什么?
final、finally和finalize虽然长得像孪生三兄弟一样,但是它们的含义和用法却是大相径庭。这一次我们就一起来回顾一下这方面的知识。
我们首先来说说final。它可以用于以下四个地方:
- 定义变量,包括静态的和非静态的。
- 定义方法的参数。
- 定义方法。
- 定义类。
我们依次来回顾一下每种情况下final的作用。首先来看第一种情况,如果final修饰的是一个基本类型,就表示这个变量被赋予的值是不可变的,即它是个常量;如果final修饰的是一个对象,就表示这个变量被赋予的引用是不可变的,这里需要提醒大家注意的是,不可改变的只是这个变量所保存的引用,并不是这个引用所指向的对象。在第二种情况下,final的含义与第一种情况相同。实际上对于前两种情况,有一种更贴切的表述final的含义的描述,那就是,如果一个变量或方法参数被final修饰,就表示它只能被赋值一次,但是JAVA虚拟机为变量设定的默认值不记作一次赋值。
被final修饰的变量必须被初始化。初始化的方式有以下几种:
- 在定义的时候初始化。
- 在初始化块中初始化。
- 在类的构造器中初始化。
- 静态变量也可以在静态初始化块中初始化。
通过下面的代码可以验证以上的观点:
- public class FinalTest{
- //在定义时初始化
- public final int A= 10 ;
- public final int B;
- //在初始化块中初始化
- {
- B= 20 ;
- }
- //静态常量,在定义时初始化
- public static final int STATIC_C= 30 ;
- public static final int STATIC_D;
- //静态常量,在静态初始化块中初始化
- static {
- STATIC_D= 40 ;
- }
- public final int E;
- public static int STATIC_F;
- //在构造器中初始化
- public FinalTest(){
- E= 50 ;
- //静态变量也可以在构造器中初始化
- STATIC_F= 60 ;
- //给final的变量第二次赋值时,编译会报错
- //A=99;
- //STATIC_C=99;
- }
- //静态变量不能在初始化块中初始化
- //publicstaticfinalintSTATIC_G;
- //{
- //STATIC_G=70;
- //}
- //final变量未被初始化,编译时就会报错
- //publicfinalintH;
- //静态final变量未被初始化,编译时就会报错
- //publicstaticfinalintSTATIC_I;
- }
public class FinalTest { // 在定义时初始化 public final int A = 10; public final int B; // 在初始化块中初始化 { B = 20; } // 静态常量,在定义时初始化 public static final int STATIC_C = 30; public static final int STATIC_D; // 静态常量,在静态初始化块中初始化 static { STATIC_D = 40; } public final int E; public static int STATIC_F; // 在构造器中初始化 public FinalTest() { E = 50; // 静态变量也可以在构造器中初始化 STATIC_F = 60; // 给final的变量第二次赋值时,编译会报错 // A = 99; // STATIC_C = 99; } // 静态变量不能在初始化块中初始化 // public static final int STATIC_G; // { // STATIC_G = 70; // } // final变量未被初始化,编译时就会报错 // public final int H; // 静态final变量未被初始化,编译时就会报错 // public static final int STATIC_I; }
我们运行上面的代码之后出了可以发现final变量(常量)和静态final变量(静态常量)未被初始化时,编译会报错;另外还可以发现,静态final变量可以在构造器中初始化,却不可以在初始化块中初始化。
用final修饰的变量(常量)比非final的变量(普通变量)拥有更高的效率,因此我们在实际编程中应该尽可能多的用常量来代替普通变量,这也是一个很好的编程习惯。
当final用来定义一个方法时,会有什么效果呢?正如大家所知,它表示这个方法不可以被子类重写,但是它这不影响它被子类继承。我们写段代码来验证一下:
- class ParentClass{
- public final void TestFinal(){
- System.out.println( "父类--这是一个final方法" );
- }
- }
- public class SubClass extends ParentClass{
- /**
- *子类无法重写(override)父类的final方法,否则编译时会报错
- */
- //publicvoidTestFinal(){
- //System.out.println("子类--重写final方法");
- //}
- public static void main(String[]args){
- SubClasssc= new SubClass();
- sc.TestFinal();
- }
- }
class ParentClass { public final void TestFinal() { System.out.println("父类--这是一个final方法"); } } public class SubClass extends ParentClass { /** * 子类无法重写(override)父类的final方法,否则编译时会报错 */ // public void TestFinal() { // System.out.println("子类--重写final方法"); // } public static void main(String[] args) { SubClass sc = new SubClass(); sc.TestFinal(); } }
这里需要特殊说明的是,具有private访问权限的方法也可以增加final修饰,但是由于子类无法继承private方法,因此也无法重写它。编译器在处理private方法时,是按照final方法来对待的,这样可以提高该方法被调用时的效率。不过子类仍然可以定义同父类中的private方法具有同样结构的方法,但是这并不会产生重写的效果,而且它们之间也不存在必然联系。
最后我们再来回顾一下final用于类的情况。这个大家应该也很熟悉了,因为我们最常用的String类就是final的。由于final类不允许被继承,编译器在处理时把它的所有方法都当作final的,因此final类比普通类拥有更高的效率。final的类的所有方法都不能被重写,但这并不表示final的类的属性(变量)值也是不可改变的,要想做到final类的属性值不可改变,必须给它增加final修饰,请看下面的例子:
- public final class FinalTest{
- int i= 10 ;
- public static void main(String[]args){
- FinalTestft= new FinalTest();
- ft.i= 99 ;
- System.out.println(ft.i);
- }
- }
public final class FinalTest { int i = 10; public static void main(String[] args) { FinalTest ft = new FinalTest(); ft.i = 99; System.out.println(ft.i); } }
运行上面的代码试试看,结果是99,而不是初始化时的10。
接下来我们一起回顾一下finally的用法。这个就比较简单了,它只能用在try/catch语句中,并且附带着一个语句块,表示这段语句最终总是被执行。请看下面的代码:
- public final class FinallyTest{
- public static void main(String[]args){
- try {
- throw new NullPointerException();
- } catch (NullPointerExceptione){
- System.out.println( "程序抛出了异常" );
- } finally {
- System.out.println( "执行了finally语句块" );
- }
- }
- }
public final class FinallyTest { public static void main(String[] args) { try { throw new NullPointerException(); } catch (NullPointerException e) { System.out.println("程序抛出了异常"); } finally { System.out.println("执行了finally语句块"); } } }
运行结果说明了finally的作用:
- 程序抛出了异常
- 执行了finally语句块
请大家注意,捕获程序抛出的异常之后,既不加处理,也不继续向上抛出异常,并不是良好的编程习惯,它掩盖了程序执行中发生的错误,这里只是方便演示,请不要学习。
那么,有没有一种情况使finally语句块得不到执行呢?大家可能想到了return、continue、break这三个可以打乱代码顺序执行语句的规律。那我们就来试试看,这三个语句是否能影响finally语句块的执行:
- public final class FinallyTest{
- //测试return语句
- public ReturnClasstestReturn(){
- try {
- return new ReturnClass();
- } catch (Exceptione){
- e.printStackTrace();
- } finally {
- System.out.println( "执行了finally语句" );
- }
- return null ;
- }
- //测试continue语句
- public void testContinue(){
- for ( int i= 0 ;i< 3 ;i++){
- try {
- System.out.println(i);
- if (i== 1 ){
- continue ;
- }
- } catch (Exceptione){
- e.printStackTrace();
- } finally {
- System.out.println( "执行了finally语句" );
- }
- }
- }
- //测试break语句
- public void testBreak(){
- for ( int i= 0 ;i< 3 ;i++){
- try {
- System.out.println(i);
- if (i== 1 ){
- break ;
- }
- } catch (Exceptione){
- e.printStackTrace();
- } finally {
- System.out.println( "执行了finally语句" );
- }
- }
- }
- public static void main(String[]args){
- FinallyTestft= new FinallyTest();
- //测试return语句
- ft.testReturn();
- System.out.println();
- //测试continue语句
- ft.testContinue();
- System.out.println();
- //测试break语句
- ft.testBreak();
- }
- }
- class ReturnClass{
- public ReturnClass(){
- System.out.println( "执行了return语句" );
- }
- }
public final class FinallyTest { // 测试return语句 public ReturnClass testReturn() { try { return new ReturnClass(); } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("执行了finally语句"); } return null; } // 测试continue语句 public void testContinue() { for (int i = 0; i < 3; i++) { try { System.out.println(i); if (i == 1) { continue; } } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("执行了finally语句"); } } } // 测试break语句 public void testBreak() { for (int i = 0; i < 3; i++) { try { System.out.println(i); if (i == 1) { break; } } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("执行了finally语句"); } } } public static void main(String[] args) { FinallyTest ft = new FinallyTest(); // 测试return语句 ft.testReturn(); System.out.println(); // 测试continue语句 ft.testContinue(); System.out.println(); // 测试break语句 ft.testBreak(); } } class ReturnClass { public ReturnClass() { System.out.println("执行了return语句"); } }
上面这段代码的运行结果如下:
- 执行了return语句
- 执行了finally语句
- 0
- 执行了finally语句
- 1
- 执行了finally语句
- 2
- 执行了finally语句
- 0
- 执行了finally语句
- 1
- 执行了finally语句
很明显,return、continue和break都没能阻止finally语句块的执行。从输出的结果来看,return语句似乎在finally语句块之前执行了,事实真的如此吗?我们来想想看,return语句的作用是什么呢?是退出当前的方法,并将值或对象返回。如果finally语句块是在return语句之后执行的,那么return语句被执行后就已经退出当前方法了,finally语句块又如何能被执行呢?因此,正确的执行顺序应该是这样的:编译器在编译return new ReturnClass();时,将它分成了两个步骤,new ReturnClass()和return,前一个创建对象的语句是在finally语句块之前被执行的,而后一个return语句是在finally语句块之后执行的,也就是说finally语句块是在程序退出方法之前被执行的。同样,finally语句块是在循环被跳过(continue)和中断(break)之前被执行的。
最后,我们再来看看finalize,它是一个方法,属于java.lang.Object类,它的定义如下:
protected void finalize() throws Throwable { }
众所周知,finalize()方法是GC(garbage collector)运行机制的一部分,关于GC的知识我们将在后续的章节中来回顾。
在此我们只说说finalize()方法的作用是什么呢?
finalize()方法是在GC清理它所从属的对象时被调用的,如果执行它的过程中抛出了无法捕获的异常(uncaught exception),GC将终止对改对象的清理,并且该异常会被忽略;直到下一次GC开始清理这个对象时,它的finalize()会被再次调用。
请看下面的示例:
- public final class FinallyTest{
- //重写finalize()方法
- protected void finalize() throws Throwable{
- System.out.println( "执行了finalize()方法" );
- }
- public static void main(String[]args){
- FinallyTestft= new FinallyTest();
- ft= null ;
- System.gc();
- }
- }
public final class FinallyTest { // 重写finalize()方法 protected void finalize() throws Throwable { System.out.println("执行了finalize()方法"); } public static void main(String[] args) { FinallyTest ft = new FinallyTest(); ft = null; System.gc(); } }
运行结果如下:
- 执行了finalize()方法
程序调用了java.lang.System类的gc()方法,引起GC的执行,GC在清理ft对象时调用了它的finalize()方法,因此才有了上面的输出结果。调用System.gc()等同于调用下面这行代码:
Runtime.getRuntime().gc();
调用它们的作用只是建议垃圾收集器(GC)启动,清理无用的对象释放内存空间,但是GC的启动并不是一定的,这由JAVA虚拟机来决定。直到JAVA虚拟机停止运行,有些对象的finalize()可能都没有被运行过,那么怎样保证所有对象的这个方法在JAVA虚拟机停止运行之前一定被调用呢?答案是我们可以调用System类的另一个方法:
public static void runFinalizersOnExit(boolean value) { //other code }
给这个方法传入true就可以保证对象的finalize()方法在JAVA虚拟机停止运行前一定被运行了,不过遗憾的是这个方法是不安全的,它会导致有用的对象finalize()被误调用,因此已经不被赞成使用了。
由于finalize()属于Object类,因此所有类都有这个方法,Object的任意子类都可以重写(override)该方法,在其中释放系统资源或者做其它的清理工作,如关闭输入输出流。
通过以上知识的回顾,我想大家对于final、finally、finalize的用法区别已经很清楚了
转自:
http://yangmingjiayou.iteye.com/blog/151865
http://www.iteye.com/topic/213051
发表评论
-
Struts2 action中获取web.xml中的context-param以及获取request, response对象的方法
2012-06-28 19:15 3576web.xml中的context-param参数:<co ... -
web.xml加载顺序与web.xml常用节点解析
2012-06-28 16:31 9310web.xml加载顺序 应用服务器启动时web.xml加载过 ... -
Annotation-java注解
2012-03-29 17:21 1097Java中提供3个内置注释类型 a. Overr ... -
memcache基础知识-stats参数
2012-03-22 23:53 7255安装memcache: #tar -xvf libe ... -
Log4j扩展的一个按天滚动的appender类,同时支持动态日志
2012-03-22 23:43 2330扩展的一个按天滚动的appender类 暂时不支持datePa ... -
log4j 配置说明
2012-03-01 17:03 1526Log4J 基本使用方法 l ... -
JSP下动态INCLUDE与静态INCLUDE的区别,Forward和Redirect的区别分析
2008-11-03 23:02 1520动态INCLUDE与静态INCLUDE的区别 动态inc ... -
关于switch case 语句的总结!
2008-11-12 18:03 1305最近面试过程中遇到一道试题: public class Te ... -
web.xml中参数的问题:context-param和init-param的区别
2011-02-28 11:28 869web.xml里面可以定义两种参数: (1)applicat ... -
Java集合的Stack、Queue、Map的遍历
2010-11-11 17:45 1545import java.util.HashMap; impo ... -
Java中的容器讲解
2010-11-11 17:42 1275线性表,链表,集合,哈希表是常用的数据结构,在进行Java开发 ... -
Map--读"找出数组中重复次数最多的元素并打印"有感Map的使用
2010-10-09 11:51 3875目的:了解Map的containsKey的是用以及Map的遍历 ... -
Web应用中request获取各种获取path或URI,URL的方法
2010-08-19 17:25 6845Web应用中有各种获取path或URI,URL的方法,假设网页 ... -
Java连接各种数据库代码
2010-03-04 14:53 8821、Oracle8/8i/9i数据库(thin模式) Cla ... -
String StringBuffer StringBuilder 三者的区别
2010-02-01 10:20 993String是固定长度的字符串,如果要发生变化必须重新生成新的 ... -
java.util.date 和 java.sql.date 两者之间区别!
2010-01-13 11:32 1603今天在调用一存储过程中setDate参数过程是出错,查资料才发 ... -
java Object生成实例的new和newInstance的区别?
2009-09-09 16:15 2572在初始化一个类,生成 ... -
java里抽象类和接口的区别
2009-08-26 00:23 788对interface和abstract class之间的区别一 ... -
java之运行时异常与编译时异常区别
2009-07-27 22:45 3334JAVA中用2种方法处理异常: 1.在发生异常的地方 ...
相关推荐
8. 访问修饰符public、private、protected、以及不写(默认)时的区别? 访问修饰符用于控制访问权限,public是公开的,private是私有的,protected是保护的,默认是包访问权限。 9. break ,continue ,return 的区别...
8. 访问修饰符 public、private、protected、以及不写(默认)时的区别?public 是公开的,private 是私有的,protected 是保护的,默认是缺省的。 三、多态、重载、重写 9. break ,continue ,return 的区别及作用...
17、请说出作用域public,private,protected,以及不写时的区别 14 18、Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型? 15 19、构造器Constructor是否可被override? 16 20、接口是否可继承...
17、请说出作用域public,private,protected,以及不写时的区别 13 18、Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型? 14 19、构造器Constructor是否可被override? 15 20、接口是否可继承...
5.作用域public,private,protected,以及不写时的区别?(难度1级) 6.Java 有几种修饰符?默认的是什么? 7. final, finally, finalize的区别?(难度1级) 8.float型float f=3.4是否正确?(难度1级) 9. short s1 = ...
Java基础面试题知识点总结 在这篇文章中,我们将总结Java基础面试题中的...这篇文章总结了Java基础面试题中的知识点,从final、finally、finalize的区别到GC的作用等,涵盖了Java的基本语法和集合框架等方面的知识。
public、private、protected 以及不写时的区别在于:public 可以被所有类访问,private 只能被当前类访问,protected 可以被当前类和子类访问,不写时表示 friendly,表示可以被当前类和同一个包中的类访问。...
以上是C#常见面试题目及答案,包括错误处理机制、访问修饰符、大规模数据并发处理、String和StringBuilder的异同、单例模式、ASP.NET页面间传递、重载和覆盖、Web Services和UDDI、final、finally和finalize、虚函数...
17、请说出作用域public,private,protected,以及不写时的区别 18、Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型? 19、构造器Constructor是否可被override? 20、接口是否可继承接口? ...
public 表示可以被所有类访问,private 表示只能被当前类访问,protected 表示可以被当前类和子类访问,friendly 表示可以被当前类和同一个包下的类访问。 8. 重载和重写的区别 重载是指同一个类中,方法名称相同...
17. public、private、protected和无访问修饰符的区别? public修饰的类、方法、变量在任何地方都可以访问;private修饰的只在本类中可以访问;protected在本包内以及子类中可以访问;无访问修饰符时在本包内可以...
本文档总结了 Java 面试的基础知识点,涵盖了面向对象、继承、多态、抽象、final、finally、finalize 的区别、整数和整数包装类的区别、重载和重写的区别、抽象类和接口的区别、反射机制的用途和实现等主题。...
2、作用域public,private,protected,以及不写时的区别? 8 3、String 是最基本的数据类型吗? 8 4、float 型float f=3.4是否正确? 8 5、语句float f=1.3;编译能否通过? 8 6、short s1 = 1; s1 = s1 + 1;有什么错? 8...
Java 支持 4 种不同的访问权限:private、default、protected 和 public。 七、&和&&的区别 & 运算符有两种用法:按位与和逻辑与。&& 运算符是短路与运算。逻辑与跟短路与的差别是非常巨大的,虽然二者都要求...
2. 作用域public, protected, private, 以及不写时的区别? public表示公开的,可以被所有其他类访问。protected表示受保护的,可以被同一包内的类以及不同包的子类访问。private表示私有的,只能被定义它的类访问...
2. **作用域public,protected/private,以及不写时的区别?** - `public` 访问权限最大,可以被任何其他类访问。 - `protected` 访问权限次之,仅可以被子类及同一个包内的其他类访问。 - `private` 访问权限最小...
17、请说出作用域public,private,protected,以及不写时的区别 13 18、Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型? 14 19、构造器Constructor是否可被override? 15 20、接口是否可继承...
40. final、finally、finalize的区别? final用于声明属性、方法和类,表示不可变、不可覆盖、不可继承。finally是异常处理中使用的一个关键字,用于声明最终要执行的代码块,不论是否发生异常都会执行。finalize是...
17. 请说出作用域public,private,protected,以及不写时的区别。 public表示公开的,可以被任何其他类访问;private表示私有的,只能在同一个类内部访问;protected表示受保护的,可以被同一个包内的类以及所有...
2. 作用域public, protected, private, 以及不写时的区别? public是完全公开的,可以在任何地方被访问;protected对于同一包内以及不同包的子类可见;private只能在本类中访问;不写时,即默认访问权限,它也是包内...