java面试题-经典选择题部分

ajie9909

贡献于2018-08-28

字数:29811 关键词: 面试题目 试题

1 、给出如下代码 : class Test{ private int m; public static void fun() { // some code... } } 如何使成员变量 m 被函数 fun() 直接访问 ? C A 、将 private int m 改为 protected int m B 、将 private int m 改为 public int m C 、将 private int m 改为 static int m D 、将 private int m 改为 int m 2 、下面哪个函数是 public void example(){...} 的重载函数? D A 、 private void example( int m){...} B 、 public int example(){...} C 、 public void example2(){...} D 、 public int example ( int m, float f){...} 3 、给出下面的代码段 : public class Base{ int w, x, y ,z; public Base(int a,int b) { x=a; y=b; } public Base(int a, int b, int c, int d) { // assignment x=a, y=b w=d; z=c; } } 在代码说明 // assignment x=a, y=b 处写入如下哪个代码是正确的? D A 、 Base(a,b); B 、 x=a, y=b; C 、 this(a),this(b); D 、 this(a,b); 4 、已知如下定义: String s = "story"; 下面哪个表达式是合法的? A A 、 s += "books"; B 、 char c = s[1]; C 、 int len = s.length; D 、 String t = 100; 5 、 Java 中 main() 函数的返回值是什么 ? D A 、 String B 、 int C 、 char D 、 void 6 、如下哪个字串在Java 中可作为自定义标识符? A A 、 $number B 、 super C 、 3number D 、 #number 7 、如下哪个不是 Java 中有效的关键字? B A 、 const B 、 NULL C 、 false D 、 this 8 、如下哪个不是 Java 中正确的整数表示 ? D A 、 22 B 、 0x22 C 、 022 D 、 22H 9 、下面的代码段中,执行之后 i 和 j 的值是什么 ? C int i = 1; int j; j = i++; A 、 1, 1 B 、 1, 2 C 、 2, 1 D 、 2, 2 10 、下面句话是正确的 ? A A >> 是算术右移操作符 . B << 是算术右移操作符 . C >>> 是算术右移操作符 D <<< 是算术右移操作符 11 、下面哪个赋值语句不是合法的? A A 、 float a = 2.0 B 、 double b = 2.0 C 、 int c = 2 D 、 long d = 2 12 、下面哪个是 main() 函数的合法参数 ? C A 、 char args[] B 、 char args[][] C 、 String arg[] D 、 String args 13 、已知表达式 int m[] = {0, 1, 2, 3, 4, 5, 6 }; 下面哪个表达式的值与数组最大下标数相等? B A 、 m.length() B 、 m.length-1 C 、 m.length()+1 D 、 m.length+1 14.指出下列程序运行的结果(D) public class Example{ String str=new String(″good″); char[]ch={′a′,′b′,′c′}; public static void main(String args[]){ Example ex=new Example(); ex.change(ex.str,ex,ch); System.out.print(ex.str+″and″); System.out.print(ex.ch); } public void change(String str,char ch[]){ str=″test ok″; ch[0]=′g′; } } A.good and abc   B.good and gbc C.test ok and abc  D.test ok and gbc 15 .函数重载是指 ( A) A.两个或两个以上的函数取相同的函数名,但形参的个数或类型不同 B.两个以上的函数取相同的名字和具有相同的参数个数,但形参的类型可以不同 C.两个以上的函数名字不同,但形参的个数或类型相同 D.两个以上的函数取相同的函数名,并且函数的返回类型相同 16.在异常处理中,如释放资源、关闭文件、关闭数据库等由( C)来完成。 A.try子句      B.catch子句 C.finally子句    D.throw子句 17. 下面哪条语句定义了5个元素的数组( A ) A、int [] a={22,23,24,25,12}; B、int a []=new int(5); C、int [5] array; D、int [] arr; 18 、已知如下的命令执行 java MyTest a b c 请问哪个语句是正确的? C A 、 args[0] = "MyTest a b c" B 、 args[0] = "MyTest" C 、 args[0] = "a" D 、 args[1]= 'c' 19. Applet类的直接父类是(D ) A.Component类   B.Container类 C.Frame类    D.Panel类 20.对于catch子句的排列,下列哪种是正确的( B ) A.父类在先,子类在后 B.子类在先,父类在后 C.有继承关系的异常不能在同一个try程序段内 D.如何排列都可以 21. 下面哪个语句不能定义一个字符变量( B ) A、char c1=’a’; B、char c2=” S ” ; C、char c4=97 ; D、char c3=’\u0041’; 22.构造方法何时被调用( B) A.类定义时     B.创建对象时 C.调用对象方法时  D.使用对象的变量时 23.下面的表达式中正确的是( AE) A.String s=″你好″;int i=3;s+=i; B.String s=″你好″;int i=3;if(i==s){s+=i}; C.String s=″你好″;int i=3;s=i+s; D.String s=″你好″;int i=3;s=i+; 24 、已知如下代码: public class Test { long a[] = new long[10]; public static void main ( String arg[] ) { System.out.println ( a[6] ); } } 请问哪个情况是正确的? C A 、 输出为 null. B 、 输出为 0. C 、 编译时出错 D 、 运行时出错 25 、Frame的默认的布局管理器是下列哪一个( B) A.FlowLayout       B.BorderLayout C.GridLayout       D.CardLayout 26.下列语句片段 int a=10,b=4,c=20,d=6; System.out.println(a++*b+c*--d); 的结果为( C) A.144    B.28 C.140    D.不能执行 27.下列语句片段: int a=-67,b=116,c=78; int d=~a|b&c; System.out.println(d)的结果为( A) A.70    B.67 C.78    D.56 28. 对象使用时,下面描述错误的是( B) A.通过“.”运算符调用成员变量和方法 B.通过成员变量的访问权限设定限制自身对这些变量方法的调用 C.将一个对象申明为类的成员时,必须在使用前为其分配内存 D.在方法中使用对象作为参数时,采用引用调用 29. 执行下列代码后,哪个结论是正确的String[] s=new String[10]; B A.s[10]为″″      B.s[9]为null C.s[0]为未定义     D.s.length为101 30. Java编程所必须的默认引用包为(B ) A.java.sys包     B.java.lang包 C.java.new包     D.以上都不是 31.定义一个类名为“MyClass.java”的类,并且该类可被一个工程中的所有类访问,那么该类的正确声明应为:( C) A.private class MyClass extends Object   B.class MyClass extends Object   C.public class MyClass   D.private class MyClass extends Object 32 、以下哪个方法用于定义线程的执行体? C A 、 start() B 、 init() C 、 run() D 、 main() E 、 synchronized() 33 如果类中的成员变量可以被同一包访问,则使用如下哪个约束符 ? D A 、 private B 、 public C 、 protected D 、 缺省 E 、 final 34 、以下哪个约束符可用于定义成员常量? B A 、 static B 、 final C 、 abstract D 、 finally 35. 当方法遇到异常又不知如何处理时,下列哪种说法是正确的(B ) A.捕获异常    B.抛出异常 C.声明异常   D.嵌套异常 36. Java程序的执行过程中用到一套JDK工具,其中java.exe是指( C) A.Java文档生成器  B.Java解释器 C.Java编译器    D.Java类分解器 37.下列不属于容器的是(B ) A.Window   B.TextBox C.Panel     D.ScrollPane 38 、已知如下类说明: public class Test { private float f = 1.0; int m = 12; static int n=1; public static void main(String arg[]) { Test t = new Test(); // some code... } } 如下哪个使用是正确的? D A 、 t.f B 、 this.n C 、 Test.m D 、 Test.n 39 、已知如下代码: 1: class Example{ 2: String str; 3: public Example(){ 4: str= "example"; 5: } 6: public Example(String s){ 7: str=s; 8: } 9:} 10: class Demo extends Example{ 11: } 12: public class Test{ 13:public void f () { 14:Example ex = new Example("Good"); 15:Demo d = new Demo("Good"); 16:} } 哪句语句会导致错误? E A 、 line 3 B 、 line 6 C 、 line 10 D 、 line 14 E 、 line 15 40 、已知如下类定义: class Base { public Base (){ //... } public Base ( int m ){ //... } public void fun( int n ){ //... } } public class Child extends Base{ // member methods } 如下哪句可以正确地加入子类中? D A 、 private void fun( int n ){ //...} B 、 void fun ( int n ){ //... } C 、 protected void fun ( int n ) { //... } D 、 public void fun ( int n ) { //... } 41 在如下源代码文件 Test.java 中 , 哪个是正确的类定义? B A 、 public class test { public int x = 0; public test(int x) { this.x = x; } } B 、 public class Test{ public int x=0; public Test(int x) { this.x = x; } } C 、 public class Test extends T1, T2 { public int x = 0; public Test (int x) { this.x = x; } } D、 protected class Test extends T2{ public int x=0; public Test(int x){ this.x=x; } } 42、当 Frame 改变大小时,放在其中的按钮大小不变,则使用如下哪个 layout? A A 、 FlowLayout B 、 CardLayout C 、 BorderLayout D 、 GridLayout 43 、如下哪个方法可以从 WindowEvent 获取事件源 ? C A 、 getFrame() B 、 getID() C 、 getSource() D 、 getEvent() 44监听器接口的方法返回值是什么? C A 、 int B 、 String C 、 void D 、 Object 45下面哪个方法与 applet 的显示无关 ? B A 、 update() B 、 draw() C 、 repaint() D 、 paint() 46下面哪个不是 Java 中的容器 ? B A 、 ScrollPane B 、 Canvas C 、 Dialog D 、 Applet 47在Java中,属于整数类型变量的是( C) A.single    B.double C.byte    D.char  48下面哪个描述是正确的( C ) A、Applet程序中不需要main()方法,也不能有 B、Application程序中可以没有main()方法。 C、Applet程序中可以不定义init( )方法 D、Application程序中必须有run( )方法  49 给出一段程序,试判断哪个是正确的结果( B ) public class rtExcept{ public static void throwit(){ System.out.print(“throwit”); throw new RuntimeException(); } public static void main(String [] aa){ try{ System.out.print(“hello “); throwit(); } catch(Exception re){ System.out.print(“caught ”); } finally{ System.out.print(“finally ”); } System.out.print(“after ”); } } A、hello throwit caught B、hello throwit caught finally after C、hello throwit RuntimeException after D、hello throwit caught finally after RuntimeException 50. 下列哪个方法可用于创建一个可运行的类( A) A.public class X implements Runable{ public void run(){......} } B.public class X implements Thread{ public void run(){......} } C.public class X implements Thread{ public int run(){......} } D.public class X implements Runable{ protected void run(){......} } 1.Which statement is true? A.An anonymous inner class may be declared as final. B.An anonymous inner class can be declared as private. C.An anonymous inner class can implement multiple interfaces . D.An anonymous inner class can access final variables in any enclosing scope. E.Construction of an instance of a static inner class requires an instance of the enclosing outer class. 答案是D anonymous inner class can not declared with any modifyer. and can only implement one interface 2. Which statement about static inner classes is true? A.An anonymous class can be declared as static B.A static inner class cannot be a static member of the outer class C.A static inner class does not require an instance of the enclosing class D.Instance members of a static inner class can be referenced using the class name of the static inner class 答案是C because static , it needn't instance of enclosing outer class and it's instance member need it's instance. 3.public class Foo{ public static void main(String sgf[]){ StringBuffer a = new StringBuffer("A"); StringBuffer b = new StringBuffer("B"); operate(a,b); System.out.println(a+","+b); } static void operate(StringBuffer x,StringBuffer y){ x.append(y); y=x; } } What is the result? A.The code compiles and prints “A.B”. B.The code compiles and prints “A.A”. C.The code compiles and prints “B.B”. D.The code compiles and prints “AB.B”. E.The code compiles and prints “AB.AB”. 答案是D java中都是按值传递的,所以a,b还是指向原来的地址空间,经过operate操作后,x更改了该地址空间的值,而y没有. public class Foo{ public static void main(String sgf[]){ StringBuffer a = new StringBuffer("A"); StringBuffer b = new StringBuffer("B"); operate(a,b); //方法调用完以后,a对象的内容为:AB,b对象的内容为:B System.out.println(a+","+b); } static void operate(StringBuffer x,StringBuffer y){ //对象传递进来以后又分别复制了一个x和y对象x'和y', x'和x指向同一个对象。y'和y指向同一个对象。 x.append(y); //所以执行此步操作以后,main中的x对象的内容也变化了。             //因为本来就是指向同一个对象吗! y=x; //执行此步操作以后,main中的y对象的内容没变!     //因为此y费彼y也! } } class ValHold{        public int i = 10; } public class ObParm{ public static void main(String argv[]){        ObParm o = new ObParm();        o.amethod();        }        public void amethod(){                int i = 99;                ValHold v = new ValHold();                v.i=30;                another(v,i);                System.out.println(v.i);        }//End of amethod        public void another(ValHold v, int i){                i=0;                v.i = 20;                ValHold vh = new ValHold();                v =  vh;                System.out.println(v.i+ " "+i);        }//End of another } 1) 10,0, 30 2) 20,0,30 3) 20,99,30 4) 10,0,20 答案是4) 首先必须明白一点 参数传递到方法内的时候实际上是复制了一份 而且java并不直接处理对象,而是通过对象参考来处理的。 public static void main(String argv[]){       ObParm o = new ObParm();       o.amethod();       }       public void amethod(){               int i = 99;               ValHold v = new ValHold();               v.i=30;               another(v,i);               System.out.println(v.i);       }//End of amethod       public void another(ValHold v, int i){               //参数v,i传进来后进行复制,并且两个v都是指向同一个对象               i=0;               v.i = 20; //这里就导致所指向的对象的i值变化               ValHold vh = new ValHold();               v =  vh; //这里改变了v的对象参考,指向新的一个ValHold对象               System.out.println(v.i+ " "+i);       }//End of another }   Which of the following statements is/are true? Choose all correct options. A) At the moment a thread calls an object's wait() method, the thread must own that object's lock. B) At the moment a thread calls an object's wait() method, the thread loses that object's lock. C) At the moment a waiting thread is notified, it is given the lock of the object for which it was   waiting. D) At any moment, a thread may not be waiting for the lock of more than one object. 首先,可以肯定c是错误的。因为当一个thread被notify后,它只是从wait pool 转向object's lock pool,不一定马上能够拿到lock. 其次,a,b两项应该是正确的。当一个thread在call wait()之前,它手中拿着该object的lock,当它call完wait( )之后,就把object's lock交出,排到wait pool里等待。 Correct selection is: A, B, D A and B are true because the whole point of wait() is to force a thread that owns an object's lock to give up the lock and block. C is false: the notified thread must now contend for the object's lock. D is true because after the thread calls wait() on the first object, it is no longer running, so it cannot call wait() on another object.   Given the following code class Base {} class Agg extends Base{ public String getFields(){ String name =  "Agg"; return name; } } public class Avf{ public static void main(String argv[]){        Base a = new Agg(); //Here } } What code placed after the comment //Here will result in calling the getFields method resulting in the output of the string "Agg"? 1) System.out.println(a.getFields()); 2) System.out.println(a.name); 3) System.out.println((Base) a.getFields()); 4) System.out.println( ((Agg) a).getFields()); answer 1:a's reference type is Base ,not Agg,so method getFields not found ...         Base a=new Agg();  change>>>>  Agg a =new Agg();  compile correct.. answer 2:variable name not found.. answer 3:the reason  is the same as answer1 answer 4:correct   Which of the following thread state transitions are valid? A From ready to running. B From running to ready. C From running to waiting. D From waiting to running. E From waiting to ready. F From ready to waiting. thread has four states: ready, running, non-runnable(sleeping, waiting,Blocked),dead The relationship is shown as following ready   <-> running running -> dead, non-runnable non-runnable -> ready             so the answer is A,B,C,E               请看以下例子: 1. public class Test{ public static void main(String argv[]){ Test t = new Test(); t.amothed(); } void amothed(){ byte[] a; System.out.println(a[0]); } } 编译时报错:变量a可能未被初始化。 2. public class Test{ public static void main(String argv[]){ Test t = new Test(); t.amothed(); } void amothed(){ byte[] a = new byte[5]; System.out.println(a[0]); } } 编译通过,输出0。   数组是会自动初始化的……这肯定没错…… 但你必须先把它实例化…… int[] a;//定义一个整型数组,但尚未实例化…… a = new int[3];//实例化a,同时a的所有元素被初始化为0…… System.out.println(a[0]); System.out.println(a[1]); System.out.println(a[2]); For the following code: class Super {  int index = 5;   public void printVal()      {  System.out.println( "Super" );      } } class Sub extends Super {  int index = 2;   public void printVal()   {  System.out.println( "Sub" );   } } public class Runner {  public static void main( String argv[] )   {  Super sup = new Sub();      System.out.print( sup.index + "," );      sup.printVal();   } } What will be printed to standard output? The code compiles and "5, Sub" is printed to standard output. 1. 成员变量是编译时绑定, Super sup = new Sub(); //这里声明sup为Super, 所以在编译时,就确定了sup.index=5 System.out.print( sup.index + "," ); //打印出5 成员函数则是动态绑定, sup.printVal(); //尽管sup被声明为super,但是实际上是new Sub(),所以在运行时,sup实际上指向的一个Sub对象。由于是动态绑定,所以这里执行的是Sub的方法。 What happens when you try to compile and run the following program? class Mystery {  String s;  public static void main(String[] args) {    Mystery m = new Mystery();    m.go();  }  void Mystery() {    s = "constructor";  }    void go() {    System.out.println(s);  } } Select the one right answer. this code runs and writes "null" in the standard output 构造函数没有返回值,即在构造函数前面不要写任何东西,void也不能写(除了可以写public). 如果写了void或者其他返回类型,比如此例中的 void Mystery();//这时,这个函数已经不是构造函数了,而且一个普通的函数,尽管与类和构造函数同名,但是他已经是一个普通的函数了,返回类型是void. 也就是说在此例中,其实是没有显示的写出构造函数。所以s当然为空。 1)class A {   static int si=5;   static { System.out.println(si);}   A(){ si++;}   public static void main(String args[]) {          for (int i=0;i<3;i++)               new A();        }   }   参考答案:print out "5" once 当类加载的时候首先是初始化static类变量和执行static类方法,只有这一次机会。此时也许还没有一个类实例。以后所有对象都共享static变量。对static类变量的修改会影响到 所有的类实例。 2)class Z {        public static void main(String args[]) {               System.out.println("AAA"+new Z());        }        public String toString() {               System.out.println("###");               return "Z";        }   }   参考答案:"###" followed by "AAAZ" 要打印"AAA"+new Z(),就要先把他翻译成字符串,要想翻译成字符串就要先执行z.toString(),所以先遇到了打印“###”,于是打印了出来,然后z.toString()执行完毕,然后开始执行打印"AAA"+"z",顺序是这样的。 What is the result of attempting to compile and run the following program? 1. public class Test { 2. private int i = j; 3. private int j = 10; 4. 5. public static void main(String args[]) { 6. System.out.println((new Test()).i); 7. } 8. } [Select one correct answer] a. Compiler error complaining about access restriction of private variables of Test. b. Compiler error complaining about forward referencing. c. No error - The output is 0; d. No error - The output is 10; 答案是: b JAVA中类的编译顺序是只要建立了对象实例,即NEW,就会先初始化变量,在调用CONSTRUCTOR,而变量的初始化是必须按顺序的,所以,第一题选B What is the output of the following program 1. public class Test { 2. private int i = giveMeJ(); 3. private int j = 10; 4. 5. private int giveMeJ() { 6. return j; 7. } 8. 9. public static void main(String args[]) { 10. System.out.println((new Test()).i); 11. } 12. } Select one correct answer a. Compiler error complaining about access restriction of private variables of AQuestion. b. Compiler error complaining about forward referencing. c. No Compilation error - The output is 0; d. No Compilation error - The output is 10; 答案是: c。生成test类,首先为i,j分配空间并初始化为0,然后执行i=giveMeJ(),这时j还是0,所以i的结果为0;然后执行j=10。所以最后输出为0。 Which two cannot directly cause a thread to stop executing? A.exiting from a synchronized block B.calling the wait method on an object C.calling the notify method on an object D.calling a read method on an InputStream object E.calling the setPriority method on a thread object Answer:CE there are 7 possible for causing thread to stop executing: 1\exiting from synchronized block 2/calling the wait method on the object/ 3\calling read method on the InputStream object 4/priorer thread enters ready state/ 5\calling system.exit(0) 6/The thread executes a sleep() call 7\A call to the thread's stop method. ·2 ways to synchronize: 1.Synchronize the entire method ·Declare the method to be synchronized - very common practice. ·Thread should obtain the object’s lock. 2.Synchronize part of the method ·Have to pass an arbitrary object which lock is to be obtained to execute the synchronized code block (part of a method). Synchronized(target) {statements} ·We can specify “this” in place object, to obtain very brief locking – not very common ·If target is null, then the NullPointerException is thrown. Which of the following are correct, if you compile the following code? public class CloseWindow extends Frame implements WindowListener { public CloseWindow() { addWindowListener(this); // This is listener registration setSize(300, 300); setVisible(true); } public void windowClosing(WindowEvent e) { System.exit(0); } public static void main(String args[]) { CloseWindow CW = new CloseWindow(); } } A) Compile time error B) Run time error C) Code compiles but Frames does not listen to WindowEvents D) Compile and runs successfully 这道题考得很隐蔽,考你implement 抽象类,必须实例化里面所有的方法,由于没有都实例化,所以答案是A 先说抽象类吧,A类如果要继承抽象类B,那么A类必须对抽象类里的所有抽象方法实例化,即override这些抽象方法,同时去掉abstract 前缀。 WindowListener 是 interface,而接口里的方法默认都为抽象的,当然也就.... 出题人认为:我们都应该猜到至少WindowListener有比如关闭..之类的方法,而此中没有对这些抽象方法实例话...so ..... Which statements about garbage collection are true? Select all valid answers. a) You can directly free the memory allocated by an object. b) You can directly run the garbage collector whenever you want to. c) The garbage collector informs your object when it is about to be garbage collected. d) The garbage collector reclaims an object memory as soon as it becomes a candidate for garbage collection. e) The garbage collector runs in low-memory situations. 答案是ade 对于声明为final类型的成员变量,可以在声明语句中进行初始化如 final int i=0; 也可以在类的构造函数中进行初始化,如果有多个构造函数,每个都必须进行初始化 class test{ final int i; test(){ i=0; } } 甚至可以在类的初始化block中进行初始化, class test{ final int i; { int i=0; } } final变量只能初始化一次。 Which of the following statements are true? 1) The x,y coordinates of an instance of MouseEvent can be obtained using the getX() and getY() methods 2) The x,y coordinates of an instance of MouseEvent can be obtained using the X and Y integer fields 3) The time of a MouseEvent can be extracted using the getTime() method 4) The time of a MouseEvent can be extracted using the when parameter of the MouseEvent constructor 1,4. What will happen if you compile/run the folowing lines of code? 1: Vector a = new Vector(); 2: 3: a.addElement(10); 4: 5: System.out.println(a.elementAt(0)); A) Prints 10. B) Prints 11. C) Compilation error at line 3. D) Prints some garbage. 答案是C。Vetor 接受的是一个对象,不是一个primitive type Which statements describe guaranteed behavior of the garbage collection and finalization mechanisms? 1) Objects are deleted when they can no longer be accessed through any reference. 2) The finalize() method will eventually be called on every object. 3) The finalize() method will never be called more than once on an object. 4) An object will not be garbage collected as long as it is possible for an active part of the program to access it through a reference. 5) The garbage collector will use a mark and sweep algorithm. finalize can be called explicitly,but the finalize method will be called before the garbage collector sweeps  away the object.answer is 4,5 serialization(串行化)- 简单的不太确切的说就是把 对象 构造成 stream(数据串,所以叫串行化),发出去。 deserialization - 把接收到的 stream 重新构造成 对象. serialization主要用在 RMI(远程调用,2个对象通过socket通讯) transient 用于声明类的 成员变量 ,在java语言规格书中没有被详细说明,主要是用在 serialization 的情况, 以保护类中的某些信息. 比如说 类 classA 中有个变量 abc 被声明为transient,那么classA在串行化的时候,abc不被串行化. classA的1个实例在client端串行化为stream发出去,在server端被收到还原成classA,但是这时abc是不被还原的. 这个程序之所以显得正确,是因为每个thread都非常之快地运行结束。 public class SyncTest{ public static void main(String[] args){ final StringBuffer s1=new StringBuffer(); final StringBuffer s2=new StringBuffer(); new Thread() { public void run(){  //只有拥有s1的锁,才可以执行后面的代码,   synchronized(s1){   //现在当前线程有S1的锁       s1.append("A");        synchronized(s2){   // 当前线程有S2的锁        s2.append("B");      System.out.print(s1);      System.out.print(s2);      }      }   } }.start();  // 如果足够快的话,当前线程结束运行,释放S1和S2的锁。 new Thread(){  //此时上一个线程可能已经结束,S1和S2的锁都已经释放。  public void run(){    synchronized(s2){  //当前线程有S2的锁      s2.append("C"); synchronized(s1){  //当前线程有S2的锁   s1.append("D");   System.out.println(s2);   System.out.println(s1);   } } } }.start(); } }   你可以试验一下,在两个线程中各加上几个yield(),当第一个线程刚刚得到S1时,第二个线程已经得到了S2的锁。然后第一个线程在等S2,第二个线程等S1,就会形成死锁。   Java本身并没有提供避免这种死锁的方法,只有靠程序员自己去注意了。因此,良好的程序设计方法是,(尽量)保持同样的顺序去获取锁。 class Mammal{        Mammal(){                System.out.println("Creating Mammal");        }                 } public class Human extends Mammal{ public static void main(String argv[]){        Human h = new Human();        }        Human(){        System.out.println("Creating Human");       } } 输出: Creating Mammal Creating Human 子类构造器会自动调用父类的缺省构造器。 相当于构造器中第一行加了一句 super(); 看一下类的初始化顺序,逐级向下,父类:先static,后非static,初始化成员变量,执行constructor,-〉 子类:先static,后非static,初始化成员变量,执行constructor-〉。。。 1)  public class X{ 2)     public Object m(){ 3)         Object o = new Float(3.14f); 4)         Object[] oa = new Object[]; 5)         oa[0] = o; 6)         o = null;         7)         oa[0] = null;         System.out.println(oa[0]); 9)     } 10) } Which line is the earliest point the object a refered is definitely eligible to be garbage collectioned? a). After line 4   b). After line 5   c). After line 6   d). After line 7 e). After line 9 Answer is D 5) oa[0] = o;        //Then oa[0] also point to the object created by:        // Object o = new Float(3.14f); 6) o = null;        // Now o is not point to the original object, but oa[0] still point to it. The object can not be gc if there is any object reference point to it. 7) oa[0] = null;        //After here, no reference point to the original object. Can be gc. Here is the earliest point. 8)System.out.println(oa[0]);          //You can say here is the second earliest point (?) :). Just choose D class Base { int i=99; public void amethod(){        System.out.println("Base.amethod()");        } } public class RType extends Base{ int i=-1;        public static void main(String argv[]){        Base b = new RType();//<= Note the type        System.out.println(b.i);        b.amethod();        }        public void amethod(){                System.out.println("RType.amethod()");        } } Base b = new RType(); The class type of b is Base, and the object reference it contain is RType. All the variable is compile time binding, so when ever we using b.i (variable), JVM going to find the value in Base (class type). Methods are late binding, so while we try b.amethod, JVM will looking for the method in RType (object reference type). ·Variables can also be overridden, it’s known as shadowing or hiding. But, member variable references are resolved at compile-time. So at the runtime, if the class of the object referred by a parent class reference variable, is in fact a sub-class having a shadowing member variable, only the parent class variable is accessed, since it’s already resolved at compile time based on the reference variable type. Only methods are resolved at run-time. public class Shadow {  public static void main(String s[]) { S1 s1 = new S1(); S2 s2 = new S2(); System.out.println(s1.s); // prints S1 System.out.println(s1.getS()); // prints S1 System.out.println(s2.s); // prints S2 System.out.println(s2.getS()); // prints S2 s1 = s2; System.out.println(s1.s); // prints S1, not S2 -          // since variable is resolved at compile time System.out.println(s1.getS()); // prints S2 -     // since method is resolved at run time  } } class S1 {  public String s = "S1";  public String getS() { return s;  } } class S2 extends S1{  public String s = "S2";  public String getS() { return s;  } } In the above code, if we didn’t have the overriding getS() method in the sub-class and if we call the method from sub-class reference variable, the method will return only the super-class member variable value. For explanation, see the following point. ·Also, methods access variables only in context of the class of the object they belong to. If a sub-class method calls explicitly a super class method, the super class method always will access the super-class variable. Super class methods will not access the shadowing variables declared in subclasses because they don’t know about them. (When an object is created, instances of all its super-classes are also created.) But the method accessed will be again subject to dynamic lookup. It is always decided at runtime which implementation is called. (Only static methods are resolved at compile-time) public class Shadow2 {  String s = "main";  public static void main(String s[]) { S2 s2 = new S2(); s2.display();  // Produces an output – S1, S2 S1 s1 = new S1(); System.out.println(s1.getS()); // prints S1 System.out.println(s2.getS()); // prints S1 – since super-class method always     // accesses super-class variable  } } class S1 {  String s = "S1";  public String getS() { return s;  }  void display() { System.out.println(s);  } } class S2 extends S1{  String s = "S2";  void display() { super.display();   // Prints S1 System.out.println(s); // prints S2  } } ·With OO languages, the class of the object may not be known at compile-time (by virtue of inheritance). JVM from the start is designed to support OO. So, the JVM insures that the method called will be from the real class of the object (not with the variable type declared). This is accomplished by virtual method invocation (late binding). Compiler will form the argument list and produce one method invocation instruction – its job is over. The job of identifying and calling the proper target code is performed by JVM. ·JVM knows about the variable’s real type at any time since when it allocates memory for an object, it also marks the type with it. Objects always know ‘who they are’. This is the basis of instanceof operator. Question 43: What letters get written to the standard output with the following code? class Unchecked { public static void main(String[] args) { try { method(); } catch (Exception e) { } } static void method() { try { wrench(); System.out.println("a"); } catch (ArithmeticException e) { System.out.println("b"); } finally { System.out.println("c"); } System.out.println("d"); } static void wrench() { throw new NullPointerException(); } } Select all valid answers. a) "a" b) "b" c) "c" d) "d" e) none of these I think only 'c' will be printout. static void method() {  try {    wrench();                     //get NullPointerException, go to catch block.    System.out.println("a");      //not print "a"  } catch (ArithmeticException e) {    System.out.println("b");      //Not the right exception, not "b"  } finally {    System.out.println("c");      //finally always execute (print "c")  }                               //Because the exception does not handled, method stopped.  System.out.println("d");        //not print "d" } 我把题修改了一下,巩固一下各位知识,打印出是多少? class Untitled1{ public static void main(String[] args) { try { method(); } catch (Exception e) { System.out.println('m'); } System.out.println('n'); } static void method() { try { wrench(); System.out.println("a"); } catch (ArithmeticException  e) { System.out.println("b"); } finally { System.out.println("c"); } System.out.println("d"); } static void wrench() { throw new NullPointerException(); } } 现在的答案是: c m n Object o1=new Object(); Object o2=new Object(); why o1.equals(o2) return false? equals() in Object is not check the class of the object, but check the object reference. o1 and o2 are two separate object reference of Object, so o1.equals(o2) is false. If: Object o1=new Object(); Object o2=o1; Then o1.equals(o2) is true Question 15: When Static Initializers Detour Determine the result of attempting to compile and run the following code (assume class A is the class to be executed): 1: public class A { 2:    static String a = "aaa"; 3:    static String b = new B().sayHi_B(); 4:    static { 5:       System.out.println("A.static: A's vars are: {" + A.a + ',' + A.b + '}'); 6:    } 7:    void sayHi_A() { 8:       System.out.println("A.sayHi(): A's vars are: {" + A.a + ',' + A.b + '}'); 9:    } 10:    public static void main(String[] parms) {} 11: } 12: 13: class B { 14:    static { 15:       System.out.println("B.static #1: A's vars are: {" + A.a + ',' + A.b + '}'); 16:       new A().sayHi_A(); 17:       System.out.println("B.static #2: A's vars are: {" + A.a + ',' + A.b + '}'); 18:    } 19:    String sayHi_B() { 20:       return "Hi"; 21:    } 22: } Answer 15: When Static Initializers Detour The output is: B.static #1: A's vars are: {aaa,null} A.sayHi(): A's vars are: {aaa,null} B.static #2: A's vars are: {aaa,null} A.static: A's vars are: {aaa,Hi} 第一步:   虽然main中没有内容,但class A 中的 static 初始化步骤还是会执行:     static String a = "aaa";     static String b = new B().sayHi_B(); 第二步:   在上面的第二行中,因为有new B(),所以去执行 B 的 static 初始化步骤:     static {         System.out.println("B.static #1: A's vars are: {" + A.a + ',' + A.b + '}');           //这时A中a的初始化已经完成,所以是"aaa";         //而b的部分还没有完成(现在正在初始化),所以现在memory中没有值,所以是null         new A().sayHi_A(); 第三步:   在上面一行中,new A()将再建立一个A的object,这时A的class已经load,所以static初始化过程不再执行(static初始化只执行一遍,虽然现在依然没有完成,但也不再执行)。   于是运行method sayHi_A()。这时A.a依然是"aaa",A.b依然没有完成,所以还是null 第四步:   A().sayHi_A()执行完之后,回到B的static block中继续执行:         System.out.println("B.static #2: A's vars are: {" + A.a + ',' + A.b + '}');         //同样,A.a还是"aaa",A.b仍然没有完成,所以还是null     } 第五步:   B的static初始化完成,运行B.sayHi_B()得到返回值"Hi"赋给A.b。 第六步:   然后执行A的static block:     static {         System.out.println("A.static: A's vars are: {" + A.a + ',' + A.b + '}');     }     //此时A.a还是"aaa",A.b已经得到B.sayHi_B()的返回值"Hi" 第七步:   A的所有static初始化完成,main中又没有任何其他的调用,程序结束。 程序运行输出的结果是: B.static #1: A's vars are: {aaa,null} A.sayHi(): A's vars are: {aaa,null} B.static #2: A's vars are: {aaa,null} A.static: A's vars are: {aaa,Hi} When will the object created as myObject become eligible for deletion? class example { public static void main( String args[] ) { UseObject(); } private void UseObject() { String anObject = AllocateObject(); System.out.println( anObject ); } private String AllocateObject() { String myObject = new String( "When will I be deleted?" ); return myObject; } };  A. When the AllocateObject() function completes  B. When the call to System.out.println() completes  C. When the UseObject() function completes  D. When the main program completes private String AllocateObject() {    String myObject = new String( "When will I be deleted?" );    return myObject; } //Object myObject was created here, then return the object reference back. private void UseObject() {    String anObject = AllocateObject();    System.out.println( anObject ); } //Local variable anObject receive the returned object reference, so that object new is acturally be hold by anObject. //Because anObject is a local variable, after UseObject() finish, it will not be used anywhere else. //So we choose C. When the UseObject() function completes What is the output of the following code? 1. public class Note { 2. public static void main(String args[]) { 3. String name[] = {"Killer","Miller"}; 4. String name0 = "Killer"; 5. String name1 = "Miller"; 6. swap(name0,name1); 7. System.out.println(name0 + "," + name1); 8. swap(name); 9. System.out.println(name[0] + "," + name[1]); 10. } 11. public static void swap(String name[]) { 12. String temp; 13. temp=name[0]; 14. name[0]=name[1]; 15. name[1]=temp; 16. } 17. public static void swap(String name0,String name1) { 18. String temp; 19. temp=name0; 20. name0=name1; 21. name1=temp; 22. } 23. } // end of Class Note a. Killer,Miller followed by Killer,Miller b. Miller,Killer followed by Killer,Miller c. Killer,Miller followed by Miller,Killer d. Miller,Killer followed by Miller,Killer answer c 1、不论是数组还是其他变量,作为函数参数传递进去的变量,不论在函数中怎样操作,都是不会改变的。    对于数值型变量来说,传入的值是不会改变的。    对于object变量来说,传入的是object的reference的值,也是不会改变的。 2、String是一个object,它作为函数参数的时候,reference的值是不会改变的;而同时String object本身,在一旦建立之后就不会改变了。 3、数组也是个object,它作为函数参数的时候,reference的值也是不会改变的;但数组中的内容却并不象String一样不能改变。 所以你那个问题实在是很好的,一方面考了函数参数传递的概念(在函数中,所有的入口参数只是复制了值的引用),一方面考了String和array的基本概念。 For example, after this:    int aI = int [5]; The array aI was created, aI itself can not be change again, its type, its length, etc. (This is about array's object reference. When send to a method as a parameter, any value can not be change.) But the value in each elements of the array, like aI[0], it can be change. For String, the object reference can not be change, the value in the object also can not be change. For StringBuffer, the reference can not change, but value can change. Your code here: public static void swap(String name0,String name1) {  //name0 and name1 each hold an object reference, it can not be change. All the usage in the method is using a copy of the value.   String temp;   temp=name0;   name0=name1; // Here name0 point to another object, value changed. But remember name0 here are not name0 in method parameter.   name1=temp;  // Same as name1 }   //When method finished, nothing changed on name0 and name1 public static void swap(String name[]) {  //Pass in an array's object reference    String temp;    temp=name[0];      // name here also a copy of the value in parameter    name[0]=name[1];   // But name[0] is same element as in parameter. name0 also point to the real array's reference.    name[1]=temp;      // When you using a copied reference, the element in real object also changed. } 如何理解这道题 import java.io.*; public class TestIOApp { public static void main(String args[]) throw IOException { RandomAccessFile file = new RandomAccessFile(“test.txt”, “rw”); file.writeBoolean(true); file.writeInt(123456); file.writeInt(7890); file.writeLong(10000000); file.writeInt(777); file.writeFloat(.0001f); file.seek(5); System.out.println(file.readInt()); file.close(); } } import java.io.*; public class TestIOApp { public static void main(String args[]) throw IOException { RandomAccessFile file = new RandomAccessFile(“test.txt”, “rw”); file.writeBoolean(true);  // 1 byte. boolean should be just one bit, but will use 1 byte when write to file. file.writeInt(123456);    // 4 byte for an integer file.writeInt(7890);      // 4 byte for second integer file.writeLong(10000000); // 8 byte for long file.writeInt(777);       // 4 byte for third integer file.writeFloat(.0001f);  // 4 byte for a float file.seek(5);             // Set after 5th byte System.out.println(file.readInt());  // will get the integer from 6th byte, so is 7890. file.close(); } } 1:public Object methodA() 2:{ 3:  Object o = new Float(3.1F); 4:  Object[] oa = new Object[1]; 5:  oa[o] = o; 6:  o = null; 7:  return oa[0]; 8:} 问什么时候o可以被gc收集 A.after line 5 B.after line 6 C.as the method returns D.never in this method 答案是d,因为,在o的reference被释放前,reference已经被赋给了oa[0] class EnclosingOne{  public class InsideOne{  }  public staic void main()  {    EnclosingOne eo = new EnclosingOne();    //Inside main  } } Which could replace //Inside main in the main method A.InsideOne ei = eo.new InsideOne(); B.EnclosingOne.InsideOne ei = eo.new InsideOne(); 第2题的答案应该是B,对于非静态的内部类,有两种方法创建其实例,以此题为例: (1)EnclosingOne eo=new EnclosingOne();     EnclosingOne.InsideOne ei = eo.new InsideOne(); (2)EnclosingOne.InsideOne ei = new EnclosingOne().new InsideOne(); 此题用的是第一种方法。 对于静态内部类public static class InsideOne{}用InsideOne ei=new EnclosingOne.InsideOne();来创建其实例 which is eligible A.Float foo = -1; B.Float foo = 1.0; C.Float foo = 42e1; D.Float foo = 2.02f; E.Float foo = 3.03d; F.Float foo = 0x123 答案是A D F

下载文档,方便阅读与编辑

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 10 金币 [ 分享文档获得金币 ]
0 人已下载

下载文档

相关文档