5 j7 I1 I# T( ?" U6 ~2 O$ w 第十九,List, Set, Map是否继承自Collection接口? ; ?/ W( G2 R9 L# N ( ~- g+ y* Q, i4 H3 Y Q List,Set是 0 S" a. B, e9 Z3 G5 V% _# G: F# c1 T* H* U3 y
Map不是 $ M3 E( H* |# b( V" Y m
3 i3 M; i# ?. S* n' J7 m" ~, h9 W 第二十,abstract class和interface有什么区别? / F1 U/ k3 `# a, _1 B7 f - T# n) a$ K+ h/ d7 G' m$ z; S 声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。 ; r. a. d) ?' i) v
& b u2 P$ I: p8 ]: ~% w, _ 接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口。 " z+ [" y, U' [6 X" D# B ^3 _3 |" u0 h* d
第二十一,abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized? ! T% ~' O8 z2 Q: \7 _7 J" t
2 ~3 l8 [6 k. F& a9 W( i 都不能 3 Q7 H; @4 @* H" w; C , F# _8 Z" ^' u9 z3 K3 y 第二十二,接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承实体类(concrete class)? , M$ l9 D; t3 J
. h* m! `, z3 m% Q j
接口可以继承接口。抽象类可以实现(implements)接口,抽象类是否可继承实体类,但前提是实体类必须有明确的构造函数。 ) \, o4 ]+ [! j
& _% M9 F8 e, R
第二十三,启动一个线程是用run()还是start()? % p d$ x7 Z$ m: j! z/ C+ G$ O
" w4 \: B- x; J9 T& l% G, H 启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行。这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。 $ F- I+ T8 f2 X& O9 b
% m; L# M, I. r ; d1 H3 X) C6 _2 n a" E7 P: z% c : q; {. |- o) S) v* s6 A* S7 n 第二十四,构造器Constructor是否可被override? ; o2 o2 T, A$ ]: T* g8 [9 d7 y' J0 p$ e8 W1 `4 i
构造器Constructor不能被继承,因此不能重写Overriding,但可以被重载Overloading。 8 J7 y5 U4 g1 h6 T1 M) s
: e6 a$ h* ]4 v4 G; L 第二十五,是否可以继承String类? . ?; Y8 ~. \. s& v: q& u. L
6 P& S1 D8 Y6 q% W$ _+ I9 W String类是final类故不可以继承。 # O1 \, q$ @- A: z# Q6 H, n2 p ) _/ E$ j+ T+ Q- y# ~% A' f6 h 第二十六,当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法? % a7 W7 z Z9 d. z9 U& e
0 q6 I8 ]- W8 W* w2 b 不能,一个对象的一个synchronized方法只能由一个线程访问。 ; _$ u; a( g' x' D3 W4 G; x
# z4 d, k# J$ H. i) d
第二十七,try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后? 6 \7 \! k7 W% @& N2 v3 \
! k. N! x) Y1 S* [/ [8 I8 a 会执行,在return前执行。 - ~$ m9 f4 w+ |7 h1 L
0 x( g9 Y$ o- w! D. w2 k
第二十八,编程题: 用最有效率的方法算出2乘以8等於几? . a2 }& A/ T; o
) P5 H5 Z# c6 Z# [ 有C背景的程序员特别喜欢问这种问题。 % n c, z* n7 H# o, R& s
3 e: l" @6 t S+ q/ h 2 << 3 / V# Q M2 n8 H, Y% U3 ^9 @ x/ C+ b' m
第二十九,两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对? & m4 p6 z I# {! F+ b
/ L& X% u% }5 D5 i8 _. W 不对,有相同的hash code。 / x+ L! s& s5 C% a6 [$ ^4 \ , w/ c7 t) F. Q 第三十,当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 9 f9 ^( E7 y. O, _( T$ Q2 [: p ( f3 V: X" f) e+ _3 |' a+ X ` 是值传递。Java 编程语言只由值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。 E& P2 ^% u U) H) f& H4 `$ x' |5 x. n* \
3 d* @& V6 w7 k5 Q. T4 k 第三十一,swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上? 0 C/ V& W" G( f0 L5 K' ^ v
) C, {3 L+ {! x) v" t
switch(expr1)中,expr1是一个整数表达式。因此传递给 switch 和 case 语句的参数应该是 int、 short、 char 或者 byte。long,string 都不能作用于swtich。 ) y% M- O. ]( j
l' _6 A% X) {6 w v+ Y" ^0 \ 第三十二,编程题: 写一个Singleton出来。 3 O* O3 n0 D' A3 }1 `/ A- r/ V" T2 ~1 F6 y4 e
Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。 I0 P* \5 [; M' z t- c
# g/ }' M- w8 j2 J: { 一般Singleton模式通常有几种种形式: 9 ~7 I$ v/ j; X4 N2 Q, G# _# [% A; W
' k7 ^& ^% e) @' m# `# L7 q
第一种形式: 定义一个类,它的构造函数为private的,它有一个static的private的该类变量,在类初始化时实例话,通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。 ( d- Z6 c6 C/ Q4 W- L: J" f2 L
, U; l$ A8 U2 g W# \; P
public class Singleton { : d- a0 l; w7 L& s7 ?1 a private Singleton(){} % j3 q. I J6 w6 T& A
//在自己内部定义自己一个实例,是不是很奇怪? 6 | ?, u" O1 L+ X8 M
//注意这是private 只供内部调用 C% G7 m3 x( E- Z6 x
private static Singleton instance = new Singleton(); ) j1 d- @5 a4 F //这里提供了一个供外部访问本class的静态方法,可以直接访问 6 x2 v) @3 v' g2 J; r7 @6 b- T: q
public static Singleton getInstance() { 7 ~+ G: L0 g2 W* f return instance; : N; H% Q+ O" Z j B$ Y5 K
} ; e9 S, W7 b. I# _6 G) x$ k
} % A4 J2 n: `% y9 t1 q) q- a; U
6 c [0 M) P- s1 B0 x 第二种形式: . A& A3 y( R# L J+ M$ S' m2 W6 [$ W& M1 T
public class Singleton { ! [$ \ r0 p! f" o7 ~% b
private static Singleton instance = null; - K, ?; H8 a, c5 ]# D! ^
public static synchronized Singleton getInstance() { 4 P7 t9 c; s- I7 U9 }
//这个方法比上面有所改进,不用每次都进行生成对象,只是第一次 0 E6 w9 @! R) j* ?% w
//使用时生成实例,提高了效率! * \6 \* ^( u5 J
if (instance==null) * L" S" v* a7 f' g& I6 } instance=new Singleton(); ) U, Q1 y+ J e. H
return instance; } $ ~3 F. J" I" e* X {
} 3 X$ k1 C1 L! @2 o$ V5 c7 A4 o$ p # g3 P' q h5 z; s( Y# U 其他形式: $ _4 {% y$ Z. b9 ^4 m% j, X, W# ^
定义一个类,它的构造函数为private的,所有方法为static的。 ; P, ]2 d8 U& @3 j* C
* @* B ` l7 L8 v
一般认为第一种形式要更加安全些 - F: c$ F9 \$ R0 S# K9 s
# f V7 S7 k6 G, u# X& g 第三十三 Hashtable和HashMap 5 z+ L0 c" k* l( i# @ & n' _2 H( U) B9 L/ ]) r. Z Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现 ( p$ P$ j/ N7 T8 U" h- }
/ o6 r0 C# b2 S6 ]+ M1 b
HashMap允许将null作为一个entry的key或者value,而Hashtable不允许 . @# l# o, l: Z8 r: O2 d, u- U
, q3 e, s5 U4 z/ w$ L
还有就是,HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。 6 Z7 p! b5 M# Y7 N- F) U1 e# H" ^
( _) R( O% x0 F! v, J
最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap就必须为之提供外同步。 + t( ]4 d0 I7 m0 Q# U6 f; _, N- ~$ x 6 C& V4 V1 V0 j; X7 p Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。