Java面试宝典2011版.pdf
Java面试宝典2011版余了。3、说说&和&的区别。&和&都可以用作逻辑与的运算符,表示逻辑与(a n d),当运算符两边的表达式的结果都为true时,整个运算结果才为true,另外,我个人通常并不使用标号这种方式,而是让外层的循环条件表达式的结果可以受到里层循环体代码的控制,例如,要在二维数组中查找到某个数字。int arr=l,2,3),4,5,6,7,9);boolean found=false;for(int i=0;iarr.length&!found;i+)for(int j=0;j arri.length;j+)System.out.println(4ti=M+i+”,j=+j);if(arriU=5)found=true;break;)5、switch语句能否作用在byte上,能否作用在long上,能否作用在String?在switch(exprl)中,exprl只能是一个整数表达式或者枚举常量(更大字体),整数表达式可以是int基本类型或Integer包装类型,由于,byte,short,char都可以隐含转换为in t,所以,这些类型以及这些类型的包装类型也是可以的。显然,long和String类型都不符合switch的语法规定,并且不能被隐式转换成int类型,所以,它们不能作用于swtich语句中。6、short si=1;si=si+1;有什么错?short si=1;si+=1;有什么错?对于$11011$1=1;51=$1+1;由于sl+1运算时会自动提升表达式的类型,所以结果是int型,再赋值给short类型s i时,编译器将报告需要强制转换类型的错误。对于$11011$1=1;$1+=1;由于+=是java语言规定的运算符,java编译器会对它进行特殊处理,因此可以正确编译。7、char型变量中能不能存贮一个中文汉字?为什么?char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了汉字,所以,char型变量中当然可以存储汉字啦。不过,如果某个特殊的汉字没有被包含在unicode编码字符集中,那么,这个char型变量中就不能存储这个特殊汉字。补充说明:unicode编码占用两个字节,所以,char类型的变量也是占用两个字节。备注:后面一部分回答虽然不是在正面回答题目,但是,为了展现自己的学识和表现自己对问题理解的透彻深入,可以回答一些相关的知识,做到知无不言,言无不尽。8、用最有效率的方法算出2 乘以8 等於几?2 3,因为将 个数左移n位,就相当于乘以了 2的n次方,那么,一个数乘以8只要将其左移3位即可,而位运算cpu直接支持的,效率最高,所以,2乘以8等於几的最效率的方法是2 构造器 Constructor 是否可被 override?构造器Constructor不能被继承,因此不能重写Override,但可以被重载Overload。20、接口是否可继承接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concrete class)?抽象类中是否可以有静态的main方法?接口可以继承接口。抽象类可以实现(implements)接口,抽象类是否可继承具体类。抽象类中可以有静态的m ain方法。备注:只要明白了接口和抽象类的本质和作用,这些问题都很好回答,你想想,如果你是java语言的设计者,你是否会提供这样的支持,如果不提供的话,有什么理由吗?如果你没有道理不提供,那答案就是肯定的了。只有记住抽象类与普通类的唯一区别就是不能创建实例对象和允许有abstract方法。21、写clone。方法时,通常都有一行代码,是什么?clo n e有缺省行为,superdoneO;因为首先要把父类中的成员复制到位,然后才是复制自己的成员。22、面向对象的特征有哪些方面计算机软件系统是现实生活中的业务在计算机中的映射,而现实生活中的业务其实就是一个个对象协作的过程。面向对象编程就是按现实业务一样的方式将程序代码按一个个对象进行组织和编写,让计算机系统能够识别和理解用对象方式组织和编写的程序代码,这样就可以把现实生活中的业务对象映射到计算机系统中。面向对象的编程语言有,吗 等4个主要的特征。1封装:封装是保证软件部件具有优良的模块性的基础,封装的目标就是要实现软件部件的“高内聚、低耦合”,防止程序相互依赖性而带来的变动影响。在面向对象的编程语言中,对象是封装的最基本单位,而向对象的封装比传统语言的封装更为清晰、更为有力。面向对象的封装就是把描述一个对象的属性和行为的代码封装在一个“模块”中,也就是一个类中,属性用变量定义,行为用方法进行定义,方法可以直接访问同 个对象中的属性。通常情况下,只要记住让变量和访问这个变量的方法放在一起,将一个类中的成员变量全部定义成私有的,只有这个类自己的方法才可以访问到这些成员变量,这就基本上实现对象的封装,就很容易找出要分配到这个类上的方法了,就基本上算是会面向对象的编程了。把握一个原则:把对同一事物进行操作的方法和相关的方法放在同一个类中,把方法和它操作的数据放在同一个类中。例如,人要在黑板上画圆,这一共涉及三个对象:人、黑板、圆,画圆的方法要分配给哪个对象呢?由于画圆需要使用到圆心和半径,圆心和半径显然是圆的属性,如果将它们在类中定义成了私有的成员变量,那么,画圆的方法必须分配给圆,它才能访问到圆心和半径这两个属性,人以后只是调用圆的画圆方法、表示给圆发给消息而已,画圆这个方法不应该分配在人这个对象上,这就是面向对象的封装性,即将对象封装成一个高度自治和相对封闭的个体,对象状态(属性)由这个对象自己的行为(方法)来读取和改变。个更便于理解的例子就是,司机将火车刹住了,刹车的动作是分配给司机,还是分配给火车,显然,应该分配给火车,因为司机自身是不可能有那么大的力气将一个火车给停下来的,只有火车自己才能完成这动作,火车需要调用内部的离合游和刹车片等多个器件协作才能完成刹车这个动作,司机刹车的过程只是给火车发了一个消息,通知火车要执行刹车动作而已。抽象:抽象就是找出一些事物的相似和共性之处,然后揩这些事物归为一个类,这个类只考虑这些事物的相似和共性之处,并且会忽略与当前主题和目标无关的那些方面,将注意力集中在与当前目标有关的方面。例如,看到一只蚂蚁和大象,你能够想象出它们的相同之处,那就是抽象。抽象包括行为抽象和状态抽象两个方面。例如,定义一个Person类,如下:class PersonString name;int age;)人本来是很复杂的事物,有很多方面,但因为当前系统只需要了解人的姓名和年龄,所以上面定义的类中只包含姓名和年龄这两个属性,这就是一种抽像,使用抽象可以避免考虑一些与目标无关的细节。我对抽象的理解就是不要用显微镜去看一个事物的所有方面,这样涉及的内容就太多了,而是要善于划分问题的边界,当前系统需要什么,就只考虑什么。继承:在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并可以加入若干新的内容,或修改原来的方法使之更适合特殊的需要,这就是继承。继承是子类自动共享父类数据和方法的机制,这是类之间的一种关系,提高了软件的可重用性和可扩展性。多态:多态是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。多态性增强了软件的灵活性和扩展性。例 如,下 面 代 码 中 的UserDao是一个接口,它 定 义 引 用 变 量userDao指向的实例对象由daofactory.getDao。在执行的时候返回,有 时 候 指 向 的 是UserJdbcDao这个实 现,有时候指向的 是UserHibernateDao这个实现,这 样,不用修改源代码,就 可 以 改 变userDao指向的具体类实现,从 而 导 致userDao.insertUser。方法调用的具体代码也随之改变,即有时候调用的是UserJdbcDao 的 insertUser 方 法,有时候调用的是 UserHibernateDao 的 insertUser 方 法:UserDao userDao=daofactory.getDao();userDao.insertUser(user);比喻:人吃 饭,你看到的是左手,还是右手?23、java中实现多态的机制是什么?靠的是父类或接口定义的引用变量可以指向子类或具体实现类的实例对象,而程序调用的方法在运行期才动态绑定,就是引用变量所指向的具体实例对象的方法,也就是内存里正在运行的那个对象的方法,而不是引用变量的类型中定义的方法。24、abstract class 和 interface 有什么区别?含有abstract修饰符的class即为抽象类,abstract类不能创建的实例对象。含有abstract方法的类必须定义为abstract class,abstract class类中的方法不必是抽象的。abstract class类中定义抽象方法必须在具体(Concrete)子类中实现,所以,不能有抽象构造方法或抽象静态方法。如果的子类没有实现抽象父类中的所有抽象方法,那么子类也必须定义为abstract类型。接 口(interface)可以说成是抽象类的一种特例,接口中的所有方法都必须是抽象的。接口中的方法定义默认为public abstract类 型,接口中的成员变量类型默认为public static final,下面比较一下两者的语法区别:1.抽象类可以有构造方法,接口中不能有构造方法。2.抽象类中可以有普通成员变量,接口中没有普通成员变量3.抽象类中可以包含非抽象的普通方法,接口中的所有方法必须都是抽象的,不能有非抽象的普通方法。4.抽象类中的抽象方法的访问类型可以是public,protected和(默认类型,虽然eclipse下不报错,但应该也不行),但接口中的抽象方法只能是public类型的,并且默认即为publicabstract 类型。5.抽象类中可以包含静态方法,接口中不能包含静态方法6.抽象类和接口中都可以包含静态成员变星:,抽象类中的苗,态成员变量的访问类型可以任意,但接口中定义的变量只能是public static final类型,并且默认即为public static final类型。7.一个类可以实现多个接口,但只能继承一个抽象类。下面接着再说说两者在应用上的区别:接口更多的是在系统架构设计方法发挥作用,主要用于定义模块之间的通信契约。而抽象类在代码实现方面发挥作用,可以实现代码的重用,例如,模板方法设计模式是抽象类的个典型应用,假设某个项目的所有Servlet类都要用相同的方式进行权限判断、记录访问日志和处理异常,那么就可以定义一个抽象的基类,让所有的Servlet都继承这个抽象基类,在抽象基类的service方法中完成权限判断、记录访问日志和处理异常的代码,在各个子类中只是完成各自的业务逻辑代码,伪代码如下:public abstract class BaseServlet extends HttpScrvletfpublic final void service(HttpServletRequest request,HttpServletResponse response)throwsIOExcetion,ServletException 记录访问日志进行权限判断if(具有权限乂try(doService(request,response);)catch(Excetpion e)(记录异常信息)protected abstract void doService(HttpServlctRequcst request,HttpServletResponse response)throwsIOExcetion,ServletException;注意访问权限定义成protected,显得既专业,乂严谨,因为它是专门给子类用的public class MyServletl extends BaseServletprotected void doService(HttpServletRequest request,HtlpServletResponse response)throwsIOExcetion,ServletException(本Servlet只处理的具体业务逻辑代码父类方法中间的某段代码不确定,留给子类干,就用模板方法设计模式。备注:这道题的思路是先从总体解释抽象类和接口的基本概念,然后再比较两者的语法细节,最后再说两者的应用区别。比较两者语法细节区别的条理是:先从一个类中的构造方法、普通成员变量和方法(包括抽象方法),静态变量和方法,继承性等6个方面逐一去比较回答,接着从第三者继承的角度的回答,特别是最后用了一个典型的例子来展现自己深厚的技术功底。25、abstract的 method是否可同时是static,是否可同时是native,是否可同时是 synchronized?abstract的method不可以是static的,因为抽象的方法是要被子类实现的,而static与子类扯不上关系!native方法表示该方法要用另外一种依赖平台的编程语言实现的,不存在着被子类实现的问题,所以,它也不能是抽象的,不 能 与abstract混用。例如,FileOutputSteam类要硬件打交道,底层的实现用的是操作系统相关的a p i实现,例如,在windows用c语言实现的,所以,查 看jd k的源代码,可以发现FilcOutputStrcam的open方法的定义如下:private native void open(String name)throws FileNotFoundException;如果我们要用java调用别人写的c语言函数,我们是无法直接调用的,我们需要按照java的 要 求 写 个c语言的函数,又我们的这个c语言函数去调用别人的c语言函数。由于我们的c语言函数是按java的要求来写的,我们这个c语言函数就可以与java对接上,java那边的对接方式就是定义出与我们这个c函数相对应的方法,java中对应的方法不需要写具体的代码,但需要在前面声明nativeo关于synchronized与abstract合用的问题,我觉得也不行,因为在我几年的学习和开发中,从来没见到过这种情况,并 且 我 觉 得synchronized应该是作用在一个具体的方法匕才有意义。而且,方法上的synchronized同步所使用的同步锁对象是th is,而抽象方法上无法确定this是什么。26、什么是内部类?Static Nested Class 和 Inner Class 的不同。内部类就是在一个类的内部定义的类,内部类中不能定义静态成员(静态成员不是对象的特性,只是为了找一个容身之处,所以需要放到个类中而已,这么一点小事,你还要把它放到类内部的一个类中,过分了啊!提供内部类,不是为让你干这种事情,无聊,不让你干。我想可能是既然静态成员类似c语言的全局变量,而内部类通常是用于创建内部对象用的,所以,把“全局变量”放在内部类中就是毫无意义的事情,既然是毫无意义的事情,就应该被禁止),内部类可以直接访问外部类中的成员变量,内部类可以定义在外部类的方法外面,也可以定义在外部类的方法体中,如下所示:public class Outer(int out_x=0;public void method()Inner 1 innerl=new Inner 1();public class lnner2 在方法体内部定义的内部类(public method()(out_x=3;)Inner2 inner2=new Inner2();public class Innerl 在方法体外面定义的内部类在方法体外面定义的内部类的访问类型可以是public,protects默认的,private等4种类型,这就好像类中定义的成员变量有4种访问类型一样,它们决定这个内部类的定义对其他类是否可见;对于这种情况,我们也可以在外面创建内部类的实例对象,创建内部类的实例对象时,一定要先创建外部类的实例对象,然后用这个外部类的实例对象去创建内部类的实例对象,代码如卜:Outer outer=new Outer();Outer.Innerl innerl=outer.new Innnerl();在方法内部定义的内部类前面不能有访问类型修饰符,就好像方法中定义的局部变量样,但这种内部类的前面可以使用final或abstract修饰符。这种内部类对其他类是不可见的其他类无法引用这种内部类,但是这种内部类创建的实例对象可以传递给其他类访问。这种内部类必须是先定义,后使用,即内部类的定义代码必须出现在使用该类之前,这与方法中的局部变量必须先定义后使用的道理也是一样的。这种内部类可以访问方法体中的局部变量,但是,该局部变量前必须加final修饰符。对于这些细节,只要在eclipse写代码试试,根据开发工具提示的各类错误信息就可以马上了解到。在方法体内部还可以采用如下语法来创建一种匿名内部类,即定义某一接口或类的子类的同时,还创建了该子类的实例对象,无需为该子类定义名称:public class Outer(public void start()(new Thread(new Runable()public void run();).start();)最后,在方法外部定义的内部类前面可以加上static关键字,从而成为Static Nested C lass,它不再具有内部类的特性,所有,从狭义上讲,它不是内部类。Static Nested Class与普通类在运行时的行为和功能上没有什么区别,只是在编程引用时的语法上有一些差别,它可以定义成public、protected、默认的、private等多种类型,而普通类只能定义成public和默认的这两种类型。在外面引用Static Nested Class类的名称为“外部类名.内部类名”。在外面不需耍创建外部类的实例对象,就可以直接创建Static Nested C lass,例如,假设Inner是定义在Outer类中的Static Nested C lass,那么可以使用如下语句创建Inner类:Outer.Inner inner=new Outer.Inner();由于static Nested Class不依赖于外部类的实例对象,所以,static Nested Class能访问外部类的非static成员变量。当在外部类中访问Static Nested Class时,可以直接使用Static Nested Class的名字,而不需要加上外部类的名字了,在 Static Nested Class中也可以直接引用外部类的static的成员变量,不需要加上外部类的名字。在静态方法中定义的内部类也是Static Nested Class,这时候不能在类前面加static关键字,静态方法中的 Static Nested Class与普通方法中的内部类的应用方式很相似,它除了可以直接访问外部类中的static的成员变量,还可以访问静态方法中的局部变量,但是,该局部变量前必须加final修饰符。备注:首先根据你的印象说出你对内部类的总体方面的特点:例如,在两个地方可以定义,可以访问外部类的成员变量,不能定义静态成员,这是大的特点。然后再说一些细节方面的知识,例如,几种定义方式的语法区别,静态内部类,以及匿名内部类。27、内部类可以引用它的包含类的成员吗?有没有什么限制?完全可以。如果不是静态内部类,那没有什么限制!如果你把静态嵌套类当作内部类的一种特例,那在这种情况卜.不可以访问外部类的普通成员变量,而只能访问外部类中的静态成员,例如,下面的代码:class Outer(static int x;static class Inner(void test()(syso(x);)答题时,也要能察言观色,揣摩提问者的心思,显然人家希望你说的是静态内部类不能访问外部类的成员,但你一上来就顶牛,这不好,要先顺着人家,让人家满意,然后再说特殊情况,让人家吃惊。28、Anonymous Inner Class(匿名内部类)是否可以extends(继 承)其 它 类,是 否 可 以 implements(实现)interface(接 口)?可以继承其他类或实现其他接口。不仅是可以,而是必须!29、s u p e r .g e t C l as s ()方法调用下面程序的输出结果是多少?i m p o r t j av a.u t i l.D at e;p u bl i c cl as s T e s t e x t e n d s D at e p u bl i c s t at i c v o i d m ai n(S t r i n g ar g s)n e w T e s t().t e s t();p u bl i c v o i d t e s t ()S y s t e m.o u t.p r i n t i n(s u p e r.g e t C l as s().g e t N am e();)很奇怪,结果是T e s t这属于脑筋急转弯的题目,在一个q q 群有个网友正好问过这个问题,我觉得挺有趣,就研究了一下,没想到今天还被你面到了,哈哈。在 t e s t 方法中,直接调用g e t C l as s ().g e t N am e ()方法,返回的是T e s t 类名由于g e t C l as s ()在 O bj e ct 类中定义成了 f i n al,子类不能覆盖该方法,所以,在t e s t 方法中调用g e t C l as s ().g e t N am e ()方法,其实就是在调用从父类继承的g e t C l as s ()方法,等 效 于 调 用 s u p e r .g e t C l as s ().g e t N am e ()方法,所以,s u p e r.g e t C l as s ().g e t N am e ()方法返回的也应该是 T e s t o如果想得到父类的名称,应该用如下代码:g e t C l as s().g e t S u p e i C l as s().g e t N am e();30、String是最基本的数据类型吗?基本数据类型包括 by t e、i n t ch ar l o n g f l o at、d o u bl e bo o l e an f O s h o r t oj av aJ an g.S t r i n g 类是f i n al 类型的,因此不可以继承这个类、不能修改这个类。为了提高效率节省空间,我们应该用StringBuffer类31、String s=Hello*;s=s+world!”;这两行代码执行后,原始的String对象中的内容到底变了没有?没有。因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象。在这段代码中,s 原先指向一个String对象,内容是H ello,然后我们对s 进行了+操作,那么s 所指向的那个对象是否发生了改变呢?答案是没有。这时,s 不指向原来那个对象了,而指向了另一个String对象,内容为Hello w orld!,原来那个对象还存在于内存之中,只是 s 这个引用变量不再指向它了。通过上面的说明,我们很容易导出另一个结论,如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销。因为String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。并且,这两种类的对象转换十分容易。同时、我们还可以知道,如果要使用内容相同的字符串,不必每次都new,个String。例如我们要在构造器中对一个名叫s 的 String引用变量进行初始化,把它设置为初始值,应当这样做:public class Demo private String s;public Demo s=Initial Value;)而非s=new StringCInitial Value);后者每次都会调用构造器,生成新对象,性能低卜一且内存开销大,并且没有意义,因为String对象不可改变,所以对于内容相同的字符串,只要一个String对象来表示就可以了。也就说,多次调用上面的构造器创建多个对象,他们的String类型属性s 都指向同一个对象。上面的结论还基于这样一个事实:对于字符串常量,如果内容相同,Java认为它们代表同个 String对象。而用关键字new 调用构造器,总是会创建一个新的对象,无论内容是否相同。至于为什么要把String类设计成不可变类,是它的用途决定的。其实不只String,很多Java标准类库中的类都是不可变的。在开发一个系统的时候,我们有时候也需要设计不可变类,来传递一组相关的值,这也是面向对象思想的体现。不可变类有一些优点,比如因为它的对象是只读的,所以多线程并发访问也不会有任何问题。当然也有一些缺点,比如每个不同的状态都要一个对象来代表,可能会造成性能上的问题。所 以 Java标准类库还提供了一个可变版本,即 StringBuffero32、是否可以继承String类?String类是final类故不可以继承。33、String s=new String(xyz);创建了 几个 String Object?二者之间有什么区别?两个或一个,“xyz”对应一个对象,这个对象放在字符串常量缓冲区,常量“xyz”不管出现多少遍,都是缓冲区中的那一个。New String每写一遍,就创建一个新的对象,它一句那个常量“xyz”对象的内容来创建出一个新String对象。如果以前就用过,xyz,这句代表就不会创建“xyz”自己了,直接从缓冲区拿。34、String 和 StringBuffer 的区别JAVA平台提供了两个类:String和 StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据。这个String类提供了数值不可改变的字符串。而这个StringBuffer类提供的字符串进行修改。当你知道字符数据要改变的时候你就可以使用StringBuffer。典型地,你可 以 使 用 StringBuffers来动态构造字符数据。另 外,String实现了 equals方 法,newString(ttabc,).equals(new String(abc”)的结果为 true,而 StringBuffer 没有实现 equals 方法,所以,new StringBuffer(tabc,).equals(new StringBuffer(abc)的结果为 falseo接着要举一个具体的例子来说明,我们要把1至 IJ 100的所有数字拼起来,组成一个串。StringBuffer sbf=new StringBuffer();for(int i=0;i100;i+)(sbf.append(i);)上面的代码效率很高,因为只创建了一个StringBuffer对象,而下面的代码效率很低,因为创建了 101个对象。String str=new StringO;for(int i=0;i 100;i+)(str=str+i;)在讲两者区别时,应把循环的次数搞成10000,然后用endTime-beginTime来比较两者执行的时间差异,最后还要讲讲StringBuilder与 StringBuffer的区别。String 覆盖了 equals 方法和 hashCode 方法,而 StringBuffer 没有覆盖 equals 方法和 hashCode方法,所以,将 SlringBuffer对象存储进Java集合类中时会出现问题。35、如何把一段逗号分割的字符串转换成一个数组?如果不查j d k a p i,我很难写出来!我可以说说我的思路:1 .用正则表达式,代码大概为:S t r i n g r e s u l t =o r g S t r.s p l i t(*7,);2 .用 S t i n g T o k e n i ze r,代码为:S t r i n g T o k e n i ze r t o k e n e r =S l r i n g T o k e n i ze r(o r g S t r,);S t r i n g|r e s u l t =n e w S t r i n g|t o k e n e r .c o u n t T b k e n s();I n t i=0;wh i l e(t o k e n e r.h a s N e x t()r e s u l t|i 4-+|=t o k e r.n e x t T o k e n();J36、数组有没有length。这个方法?String有没有length。这个方法?数组没有length。这个方法,有 length的属性。String有有length。这个方法。3 7、下 面 这 条 语 句 一 共 创 建 了 多 少 个 对 象:Strings=HaH+nbn+HcH+ndn;答:对于如下代码:String si=a;String s2=sl+“b”;String s3=a+b”;System.out.println(s2=uab);System.out.println(s3=Habn);第一条语句打印的结果为false,第二条语句打印的结果为tru e,这说明javac编译可以对字符串常量直接相加的表达式进行优化,不必要等到运行期去进行加法运算处理,而是在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果。题目中的第一行代码被编译器在编译时优化后,相当于直接定义了一个“abed”的字符串,所以,上面的代码应该只创建了一个String对象。写如下两行代码,String s=a+b+c+d;System.out.println(s=abed);最终打印的结果应该为true。38、try 里有一个return语句,那么紧跟在这个try后的finally 里的code会不会被执行,什么时候被执行,在return前还是后?也许你的答案是在r e t u r n之前,但往更细地说,我的答案是在r e t u r n中间执行,请看下面程序代码的运行结果:public class Test(/*param args add by zxx zDec 9,2008*/public static void main(String args)/TODO Auto-generated method stubSystem.out.printin(new Test().test();static int test()(int x=1;try(return x;)finally(+X;)-执 行 结 果-1运行结果是1,为什么呢?主函数调用子函数并得到结果的过程,好比主函数准备一个空罐子,当子函数要返回结果时,先把结果放在罐子里,然后再将程序逻辑返回到主函数。所谓返回,就是子函数说,我不运行了,你主函数继续运行吧,这没什么结果可言,结果是在说这话之前放进罐子里的。39、下面的程序代码输出的结果是多少?public class smallT(public static void main(String args)|smallT t=new smallT();int b=t.get();System.out.println(b);public int get()return 1 ;finallyreturn 2;)返回的结果是2。我可以通过下面个例子程序来帮助我解释这个答案,从下面例子的运行结果中可以发现,try中的return语句调用的函数先于finally中调用的函数执行,也就是说return语句先执行,finally语句后执行,所以,返回的结果是2。Return并不是让函数马上返回,而 是 return语句执行后,将把返回结果放置进函数栈中,此时函数并不是马上返回,它要 执 行 finally语句后才真正开始返回。在讲解答案时可以用下面的程序来帮助分析:p ub l i c c l a ss T e st/*p a ra m a rg s a d d b y zxx zD e c 9,2 0 0 8*/p ub l i c sta ti c vo i d m a i n(S tri n g a rg s)/T O D O A uto-g e n e ra te d m e th o d stubS yste m.out.p ri n ti n(n e w T e st().te st();)i n t te st()(try(re turn f u n d ();)f i n a l l y(re turn f un c 2();)i n t f u n d ()S yste m.out.p ri n ti n(f un c i );re turn 1;)i n t f un c 2()S yste m.out.p ri n ti n(f un c 2 );re turn 2;)-执行结果-f u n df un c 22结论:finally中的代码比return和 break语句后执行40、final,finally,finalize 的区另lj。final用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。内部类要访问局部变量,局部变量必须定义成final类型,例如,-段代码finally是异常处理语句结构的一部分,表示总是执行。finalize是 Object类 的 一 个 方法,在垃圾收集器执行的 寸候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时的其他资源回收,例如关闭文件等。JVM不保证此方法总被调用41、运行时异常与一般异常有何异同?异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。42、error和 exception有什么区别?error表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。exception表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。43、Java中的异常处理机制的简单原理和应用。异常是指ja v a程序运行时(非编译)所发生的非正常情况或错误,与现实生活中的事件很相似,现实生活中的事件可以包含事件发生的时间、地点、人物、情节等信息,可以用一个对象来表示,Java使用面向对象的方式来处理异常,它把程序中发生的每个异常也都分别封装到一个对象来表示的,该对象中包含有异常的信息。Ja v a对异常进行了分类,不同类型的异常分别用不同的Ja v a类表示,所有异常的根类为java.lang.Throwable,Throwable 下面又派生了两个子类:Error 和 Exception,Error 表示应用程序本身无法克服和恢复的一种严重问题,程序只有死的份了,例如,说内存溢出和线程死锁等系统问题。Exception表示程序