1. 程式人生 > >java細節整理(易錯點)

java細節整理(易錯點)

1)==用於基本資料型別的比較,在引用資料型別上面使用的時候比較的是地址值
例:
下面程式的執行結果是()

String str1 = "hello";
String str2 = "he" + new String("llo");
System.err.println(str1 == str2);

A hello B he C true D false

答案:false 解析:因為str2中的llo是新申請的記憶體塊,而==判斷的是物件的地址而非值,所以不一樣。如果是String str2 = str1,那麼就是true了。

2)普通類的方法名字其實是可以與類名一致的,和建構函式唯一的區別就是建構函式沒有返回值型別,而普通方法有返回值型別
例:
下列說法正確的有()
A. class中的constructor不可省略
B. constructor必須與class同名,但方法不能與class同名
C. constructor在一個物件被new時執行
D.一個class只能定義一個constructor

答案:C 解析:這裡可能會有誤區,其實普通的類方法是可以和類名同名的,
和構造方法唯一的區分就是,構造方法沒有返回值

3)Thread類中start()方法和run()方法的使用區別:
start()是用來啟動一個執行緒,當呼叫了start方法之後,系統才會開啟一個新的執行緒,進而呼叫run()方法來執行任務,而單獨的呼叫run()方法其實就和普通方法一樣,按照順序執行,不會單獨開闢一個執行緒,從而失去了執行緒的特性了。因此在啟動一個執行緒的時候一定要使用start()而不是run()。
例:
下面程式的執行結果:()

  public static void main(String args[]) {
             Thread t = new Thread() {
                 public void run() {
                     pong();
                 }
             };
             t.run();
             System.out.print("ping");
  }

  static void pong() {
             System.out.print("pong"
); }

A pingpong B pongping C pingpong和pongping都有可能 D 都不輸出

答案:B 解析:這裡考的是Thread類中start()和run()方法的區別了。start()用來啟動一個執行緒,當呼叫start方法後,系統才會開啟一個新的執行緒,進而呼叫run()方法來執行任務,而單獨的呼叫run()就跟呼叫普通方法是一樣的,已經失去執行緒的特性了。

4)關於介面和介面中的修飾符
a.介面中的成員常量和方法都必須是public型別的。因為介面用於描述系統對外提供的所有服務,要確保外部使用者能夠訪問它們。
b.介面中的方法都是抽象型別abstract的。因為介面僅僅描述系統能夠做什麼,但是不指明如何去做,為此介面中的方法都是抽象型別的。
c.介面中的變數型別只有final,static型別。因為介面中的變數是所有實現類所共有的,既然共有,就是不變的東西,所以變數是不可變的final型別,也就是常量了;介面不涉及和任何具體例項相關的細節,通俗的話講就是介面不能夠被new,因此介面沒有構造方法,不能夠被例項化,沒有例項變數,只有靜態static變數。
d.介面中不能夠出現變數,如果有變量出現,就和介面提供的統一抽象的這種思想相抵觸了。所以介面中的屬性必然是一個常量,只能夠讀不能夠被修改,這樣才能為實現介面的物件提供一個統一的屬性。通俗的講,如果有認為是要變化的東西,就放到實現介面的類中去實現,而不應該放到介面中去,介面只是對一類事物的屬性和行為更高層次的抽象。
e.綜上:介面的方法預設是public abstract,介面的屬性預設是public static final常量,且必須賦值。
例:
Java介面的修飾符可以為()

A private B protected C final D abstract

答案:cd

5)ArrayList擴充問題
ArrayList預設的長度為10個,但是如果在宣告的時候指定了長度的話,就會一次性建立指定長度,而不需要擴充。
例:
ArrayList list = new ArrayList(20);中的list擴充幾次()

A 0 B 1 C 2 D 3

答案:A 解析:這裡有點迷惑人,大家都知道預設ArrayList的長度是10個,所以如果你要往list裡新增20個元素肯定要擴充一次(擴充為原來的1.5倍),但是這裡顯示指明瞭需要多少空間,所以就一次性為你分配這麼多空間,也就是不需要擴充了

6)異常try……catch語句塊的執行順序
當有多個catch語句的時候,從最前面的catch語句塊依次進行異常型別的匹配,僅僅匹配一個,當按順序來從上到下匹配到一個之後,後續的匹配都不會再執行了;如果父類異常在子類異常的前面的時候,首先匹配的就是父類異常,子類異常是不會得到匹配並執行的。所以在寫程式碼的時候,父類異常Exception一般都放在catch語句塊的最後一個。
例:
getCustomerInfo()方法如下,try中可以捕獲三種類型的異常,如果在該方法執行中產生了一個IOException,將會輸出什麼結果()

public void getCustomerInfo() {
             try {
               // do something that may cause an Exception
             } catch (java.io.FileNotFoundException ex) {
                    System.out.print("FileNotFoundException!");
             } catch (java.io.IOException ex) {
                    System.out.print("IOException!");
             } catch (java.lang.Exception ex) {
                    System.out.print("Exception!");
             }
  }

A IOException!
B IOException!Exception!
C FileNotFoundException!IOException!
D FileNotFoundException!IOException!Exception!

答案:A 解析:考察多個catch語句塊的執行順序。當用多個catch語句時,catch語句塊在次序上有先後之分。從最前面的catch語句塊依次先後進行異常型別匹配,這樣如果父異常在子異常類之前,那麼首先匹配的將是父異常類,子異常類將不會獲得匹配的機會,也即子異常型別所在的catch語句塊將是不可到達的語句。所以,一般將父類異常類即Exception老大放在catch語句塊的最後一個。

7)編譯時異常:變數沒有初始化的時候不能夠輸出。
Java中所有定義的基本型別或物件都必須初始化才能輸出值,否則會發生編譯時異常。
例:
下面程式碼的執行結果為:()

import java.io.*;
import java.util.*;

public class foo{
  public static void main (String[] args){
             String s;
             System.out.println("s=" + s);
  }
}

A 程式碼得到編譯,並輸出“s=”
B 程式碼得到編譯,並輸出“s=null”
C 由於String s沒有初始化,程式碼不能編譯通過
D 程式碼得到編譯,但捕獲到 NullPointException異常

答案:C

8)引數傳遞與修改
不管是物件、基本型別還是物件陣列、基本型別陣列,在函式中都不能改變其實際地址但能改變其中的內容

例:
下列程式的執行結果是:

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

9)關於switch語句:
case語句後面如果沒有break,那麼就會一直往下執行。
例:
下面的方法,當輸入為2的時候返回值是多少?()

 public static int getValue(int i) {
             int result = 0;
             switch (i) {
             case 1:
                 result = result + i;
             case 2:
                 result = result + i * 2;
             case 3:
                 result = result + i * 3;
             }
  return result;
  }

A 0 B 2 C 4 D 10

答案:D 解析:注意這裡case後面沒有加break,所以從case 2開始一直往下執行。

10)抽象類細節
a)類中只有成員變數和成員函式,是不能夠出現語句的;
b)抽象類中的抽象函式定義的時候是不能夠有方法體的,就是{};
c)抽象類和介面不同,介面是公開的,裡面的方法都是public的,裡面不能夠有私有的方法或者變數,介面就是讓別人使用的;而抽象類不同,抽象類是可以有私有的方法和變數的。

例:
選項中哪一行程式碼可以替換題目中//add code here而不產生編譯錯誤?()

public abstract class MyClass {
  public int constInt = 5;
  //add code here
  public void method() {
  }
}

A public abstract void method(int a);
B constInt = constInt + 5;
C public int method();
D public abstract void anotherMethod() {}