黑马程序员技术交流社区

标题: 小面试题 [打印本页]

作者: 孙铭泽    时间: 2012-8-20 22:44
标题: 小面试题
                                           :::::希望各位在不查看的情况下你们知道 吗,你们以该怎样回答。
       (1)final.finally.finalize这三者用法意义列举在你的心里。
   这是一个小小的面试题但是我没回答上来跟你们分享一下 。
作者: 唐杨老师    时间: 2012-8-20 23:29
final 用来定义最终变量,不希望在定义之后被改变的变量
finally.在捕捉异常时使用的,结构有try() finally{}    ,  try()catch(){}finally{}
用来放一些在上边try代码执行后一定要执行的代码,比如输入输出流的关闭
finalize应该是垃圾回收机制,,这个记不太清楚了
作者: 廉伟    时间: 2012-8-21 07:22
final—修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重载。
  finally—再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。
  finalize—方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。
作者: 马林康    时间: 2012-8-21 11:25
变态32问里的题
作者: 胡进辉    时间: 2012-8-21 12:01
final可以让你控制你的成员、方法或者是一个类是否可被覆写或继承.
finally 关键字是对 Java 异常处理模型的最佳补充。 finally 结构使代码总会执行,而不管有无异常发生。使用 finally 可以维护对象的内部状态,并可以清理非内存资源
finalize用于一些不容易控制、并且非常重要资源的释放,例如一些I/O的操作,数据的连接。这些资源的释放对整个应用程序是非常关键的。在这种情况下,程序员应该以通过程序本身管理(包括释放)这些资源为主,以finalize函数释放资源方式为辅,形成一种双保险的管理机制,而不应该仅仅依靠finalize来释放资源。
作者: 李知伦    时间: 2012-8-21 12:12
final关键字
先看看final关键字,它可以被用于以下几个地方:
1、修饰属性、局部变量、方法参数:
如果final修饰的是一个基本类型,就表示这个变量所赋予的值不可修改,即它是个常量;如果final修饰的是一个对象,就表示这个变量被赋予的引用不可修改(但我们可以修改该引用所指向对象里的内容,这里所说的不可修改是指final修改的引用一但指向了谁,就不能再指向别的对象了)。下面来看看修改属性与变量时需要注意的几点:

在方法中定义的内部类只能访问方法中的final类型的局部变量,因为用final定义的局部变量是一个常量,运行时不是放在栈里的,因此它的生命同期超出了方法运行的生命周期:
Java代码  收藏代码

    //final不能去掉,否则编译通不过  
    public Comparable f(final Comparable o1) {  
        return new Comparable() {  
            public int compareTo(Object o2) {  
                return o1.compareTo(o2);  
            }  
        };  
    }  

final修改的静态属性,必须在声明的同时或者在静态块中初始化;final修饰的非静态属性,必须在声明的同时、或非静态块中或者是构造函数中初始化:
Java代码  收藏代码

    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时才调用,而静态属性在对象还没有创建时也能使用,所以有可能还未初始化就使用了,也还有可能初始化多次),当然非静态属性更不能在静态块中、构造函数中初始化(因为在静态块中不能访问非静态属性、变量及方法):
Java代码  收藏代码

    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,只能在定义时就初始化:
Java代码  收藏代码

    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);  
        }  
    }  

这里提到了静态区与非静态区,它们的区别是,静态区在类装载时执行一次,而非静态区每在实例化一个对象时就执行一次:
Java代码  收藏代码

    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修改的方法不能被覆写。
Java代码  收藏代码

    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类比普通类拥有更高的效率:
Java代码  收藏代码

    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是不允许的:
Java代码  收藏代码

    // !! 接口不能用final来修饰  
    public final interface A {}  
      
    // !! 抽象类不能用final来修饰  
    public final abstract class A {}  
作者: 李知伦    时间: 2012-8-21 12:13
finally关键字
finally关键字用在try/catch语句最末,表示不管是否抛出异常,finally块中的语句最终肯定、一定会被执行,执行的顺序为 try块 —> finally块(不抛异常情况下)或 try块 —> catch块(抛异常情况下)—> finally块 :
Java代码  收藏代码

    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语句时,到底从哪里返回:
Java代码  收藏代码

    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)之前被执行的:
Java代码  收藏代码

    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 方法抛出未捕获的异常,那么该异常将被忽略,并且该对象的终结操作将终止:
Java代码  收藏代码

    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);  
    }  
作者: 黑马王建伟    时间: 2012-8-21 12:21
final:定义常量,,定义方法不能被重写,定义类不能被继承
finally:try{}catch(){}finally{},异常处理语句关键字,表示不管有没有异常,总会执行
finalize:垃圾处理机制,需要垃圾处理时,可以主动调用,但java虚拟机可以在空闲时间自动调用
作者: 李毅    时间: 2012-8-21 14:02
final是修饰词,一般用来修饰常量。但常量肯定是final,final不一定是常量。
finally是捕获异常是用到的,除非在try里有system.exit(0),否则一定会执行finally里的内容。
finalize是java的垃圾回收机制,垃圾收集器在删除对象之前会调用它。
作者: 王峰    时间: 2012-8-21 14:20
final—修饰符(关键字)
   如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract的,又被声明为final的。
   将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。
   被声明为final的方法也同样只能使用,不能重载。
finally—再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。
finalize—方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2