閱讀807 返回首頁    go 阿裏雲 go 技術社區[雲棲]


java麵試題—精選30道Java筆試題解答(二)

19. 下麵程序能正常運行嗎()

複製代碼
public class NULL {

    public static void haha(){
        System.out.println("haha");
    }
    public static void main(String[] args) {
        ((NULL)null).haha();
    }

}
複製代碼

答案:能正常運行

解析:輸出為haha,因為null值可以強製轉換為任何java類類型,(String)null也是合法的。但null強製轉換後是無效對象,其返回值還是為null,而static方法的調用是和類名綁定的,不借助對象進行訪問所以能正確輸出。反過來,沒有static修飾就隻能用對象進行訪問,使用null調用對象肯定會報空指針錯了。這裏和C++很類似。這裏感謝@Florian網友解答。

 

20. 下麵程序的運行結果是什麼()

複製代碼
class HelloA {

    public HelloA() {
        System.out.println("HelloA");
    }
    
    { System.out.println("I'm A class"); }
    
    static { System.out.println("static A"); }

}

public class HelloB extends HelloA {
    public HelloB() {
        System.out.println("HelloB");
    }
    
    { System.out.println("I'm B class"); }
    
    static { System.out.println("static B"); }
    
    public static void main(String[] args) { 
     new HelloB(); 
   }

}
複製代碼

答案:

static A
static B
I'm A class
HelloA
I'm B class
HelloB

解析:說實話我覺得這題很好,考查靜態語句塊、構造語句塊(就是隻有大括號的那塊)以及構造函數的執行順序。

對象的初始化順序:(1)類加載之後,按從上到下(從父類到子類)執行被static修飾的語句;(2)當static語句執行完之後,再執行main方法;(3)如果有語句new了自身的對象,將從上到下執行構造代碼塊、構造器(兩者可以說綁定在一起)。

下麵稍微修改下上麵的代碼,以便更清晰的說明情況:

 View Code

此時輸出結果為:

複製代碼
static A
static B
-------main start-------
I'm A class
HelloA
I'm B class
HelloB
I'm A class
HelloA
I'm B class
HelloB
-------main end-------
複製代碼

  如果你想學習java可以來這個群,首先是二二零,中間是一四二,最後是九零六,裏麵有大量的學習資料可以下載。

21. 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!");

        }

    }
複製代碼

IOException!

BIOException!Exception!

CFileNotFoundException!IOException!

DFileNotFoundException!IOException!Exception!

答案:A

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

 

22. 下麵代碼的運行結果為:()

複製代碼
import java.io.*;
import java.util.*;

public class foo{

    public static void main (String[] args){

        String s;

        System.out.println("s=" + s);

    }

}
複製代碼

代碼得到編譯,並輸出“s=

代碼得到編譯,並輸出“s=null

由於String s沒有初始化,代碼不能編譯通過

代碼得到編譯,但捕獲到 NullPointException異常

答案:C

解析:開始以為會輸出null什麼的,運行後才發現Java中所有定義的基本類型或對象都必須初始化才能輸出值。


23.  System.out.println("5" + 2);的輸出結果應該是()。

52                   B7                     C2                     D5

答案:A

解析:沒啥好說的,Java會自動將2轉換為字符串。

 

24. 指出下列程序運行的結果 

複製代碼
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 

答案:B

解析:大家可能以為Java中String和數組都是對象所以肯定是對象引用,然後就會選D,其實這是個很大的誤區:因為在java裏沒有引用傳遞,隻有值傳遞

這個值指的是實參的地址的拷貝,得到這個拷貝地址後,你可以通過它修改這個地址的內容(引用不變),因為此時這個內容的地址和原地址是同一地址,

但是你不能改變這個地址本身使其重新引用其它的對象,也就是值傳遞,可能說的不是很清楚,下麵給出一個完整的能說明情況的例子吧:

 View Code

程序有些囉嗦,但能反映問題,該程序運行結果為:

複製代碼
對象交換前:p1 = Alexia female
對象交換前:p2 = Edward male

對象交換後:p1 = Alexia female
對象交換後:p2 = Edward male

對象數組交換前:arraya[0] = Alexia female, arraya[1] = Edward male
對象數組交換前:arrayb[0] = jmwang female, arrayb[1] = hwu male

對象數組交換後:arraya[0] = Alexia female, arraya[1] = Edward male
對象數組交換後:arrayb[0] = jmwang female, arrayb[1] = hwu male

基本類型數組交換前:a[0] = 0, a[1] = 1
基本類型數組交換前:b[0] = 1, b[1] = 2

基本類型數組交換後:a[0] = 0, a[1] = 1
基本類型數組交換後:b[0] = 1, b[1] = 2

對象數組內容交換並改變後:arraya[1] = wjl male
對象數組內容交換並改變後:arrayb[1] = Edward male

基本類型數組內容交換並改變後:a[1] = 5
基本類型數組內容交換並改變後:b[1] = 1
複製代碼

說明:不管是對象、基本類型還是對象數組、基本類型數組,在函數中都不能改變其實際地址但能改變其中的內容。

 
25. 要從文件"file.dat"中讀出第10個字節到變量c,下列哪個方法適合

A FileInputStream in=new FileInputStream("file.dat"); in.skip(9); int c=in.read();

FileInputStream in=new FileInputStream("file.dat"); in.skip(10); int c=in.read();

C FileInputStream in=new FileInputStream("file.dat"); int c=in.read();

RandomAccessFile in=new RandomAccessFile("file.dat"); in.skip(9); int c=in.readByte();

答案:A?D?

解析:long skip(long n)作用是跳過n個字節不讀,主要用在包裝流中的,因為一般流(如FileInputStream)隻能順序一個一個的讀不能跳躍讀,但是包裝流可以用skip方法跳躍讀取。那麼什麼是包裝流呢?各種字節節點流類,它們都隻具有讀寫字節內容的方法,以FileInputStream與FileOutputStream為例,它們隻能在文件中讀取或者向文件中寫入字節,在實際應用中我們往往需要在文件中讀取或者寫入各種類型的數據,就必須先將其他類型的數據轉換成字節數組後寫入文件,或者從文件中讀取到的字節數組轉換成其他數據類型,想想都很麻煩!!因此想通過FileOutputStream將一個浮點小數寫入到文件中或將一個整數寫入到文件時是非常困難的。這時就需要包裝類DataInputStream/DataOutputStream,它提供了往各種輸入輸出流對象中讀入或寫入各種類型的數據的方法。

DataInputStream/DataOutputStream並沒有對應到任何具體的流設備,一定要給它傳遞一個對應具體流設備的輸入或輸出流對象,完成類似 DataInputStream/DataOutputStream功能的類就是一個包裝類,也叫過濾流類或處理流類。它對InputOutStream/OutputStream流類進行了包裝,使編程人員使用起來更方便。其中DataInputStream包裝類的構造函數語法:public DataInputStream(InputStream in)。包裝類也可以包裝另外一個包裝類。

 如果你想學習java可以來這個群,首先是二二零,中間是一四二,最後是九零六,裏麵有大量的學習資料可以下載。

首先BC肯定 是錯的,那A正確嗎?按上麵的解析應該也不對,但我試了下,發現A也是正確的,與網上解析的資料有些出入,下麵是我的code:

 View Code

那麼D呢,RandomAccessFile是IO包的類,但是其自成一派,從Object直接繼承而來。可以對文件進行讀取和寫入。支持文件的隨機訪問,即可以隨機讀取文件中的某個位置內容,這麼說RandomAccessFile肯定可以達到題目的要求,但是選項有些錯誤,比如RandomAccessFile的初始化是兩個參數而非一個參數,采用的跳躍讀取方法是skipBytes()而非skip(),即正確的寫法是:

RandomAccessFile in = new RandomAccessFile("file.dat", "r");
in.skipBytes(9);
int c = in.readByte();

這樣也能讀到第十個字節,也就是A和D都能讀到第十個字節,那麼到底該選哪個呢?A和D有啥不同嗎?求大神解答~~~

 

26. 下列哪種異常是檢查型異常,需要在編寫程序時聲明 

ANullPointerException        BClassCastException      CFileNotFoundException       D IndexOutOfBoundsException 

答案:C

解析:看第2題的解析。

 

27. 下麵的方法,當輸入為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;
    }
複製代碼

A0                    B2                    C4                     D10

答案:D

解析:注意這裏case後麵沒有加break,所以從case 2開始一直往下運行。

 

28. 選項中哪一行代碼可以替換題目中//add code here而不產生編譯錯誤?(

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

Apublic abstract void method(int a);

B constInt = constInt + 5;

public int method();

public abstract void anotherMethod() {}

答案:A

解析:考察抽象類的使用。

抽象類遵循的原則:

(1)abstract關鍵字隻能修飾類和方法,不能修飾字段。
(2)抽象類不能被實例化(無法使用new關鍵字創建對象實例),隻能被繼承。
(3)抽象類可以包含屬性,方法,構造方法,初始化塊,內部類,枚舉類,和普通類一樣,普通方法一定要實現,變量可以初始化或不初始化但不能初始化後在抽象類中重新賦值或操作該變量(隻能在子類中改變該變量)。
(4)抽象類中的抽象方法(加了abstract關鍵字的方法)不能實現。
(5)含有抽象方法的類必須定義成抽象類。
 
擴展:抽象類和接口的區別,做個總結吧:

(1)接口是公開的,裏麵不能有私有的方法或變量,是用於讓別人使用的,而抽象類是可以有私有方法或私有變量的。

(2)abstract class 在 Java 語言中表示的是一種繼承關係,一個類隻能使用一次繼承關係。但是,一個類卻可以實現多個interface,實現多重繼承。接口還有標識(裏麵沒有任何方法,如Remote接口)和數據共享(裏麵的變量全是常量)的作用。

(3)在abstract class 中可以有自己的數據成員,也可以有非abstarct的成員方法,而在interface中,隻能夠有靜態的不能被修改的數據成員(也就是必須是 static final的,不過在 interface中一般不定義數據成員),所有的成員方法默認都是 public abstract 類型的。

(4)abstract class和interface所反映出的設計理念不同。其實abstract class表示的是"is-a"關係,interface表示的是"has-a"關係。

(5)實現接口的一定要實現接口裏定義的所有方法,而實現抽象類可以有選擇地重寫需要用到的方法,一般的應用裏,最頂級的是接口,然後是抽象類實現接口,最後才到具體類實現。抽象類中可以有非抽象方法。接口中則不能有實現方法。

(6)接口中定義的變量默認是public static final 型,且必須給其初值,所以實現類中不能重新定義,也不能改變其值。抽象類中的變量默認是 friendly 型,其值可以在子類中重新定義,也可以在子類中重新賦值。

 

29. 閱讀ShapeCircle兩個類的定義。在序列化一個Circle的對象circle到文件時,下麵哪個字段會被保存到文件中? (  )

複製代碼
class Shape {

       public String name;

}

class Circle extends Shape implements Serializable{

       private float radius;

       transient int color;

       public static String type = "Circle";

}
複製代碼

Aname

radius

color

type

答案:B

解析:這裏有詳細的解釋:https://www.cnblogs.com/lanxuezaipiao/p/3369962.html

 

30.下麵是PeopleChild類的定義和構造方法,每個構造方法都輸出編號。在執行new Child("mike")的時候都有哪些構造方法被順序調用?請選擇輸出結果 ( )

複製代碼
class People {
    String name;

    public People() {
        System.out.print(1);
    }

    public People(String name) {
        System.out.print(2);
        this.name = name;
    }
}

class Child extends People {
    People father;

    public Child(String name) {
        System.out.print(3);
        this.name = name;
        father = new People(name + ":F");
    }

    public Child() {
        System.out.print(4);
    }
    
}
複製代碼

A312              B 32               C 432              D 132

答案:D

解析:考察的又是父類與子類的構造函數調用次序。在Java中,子類的構造過程中必須調用其父類的構造函數,是因為有繼承關係存在時,子類要把父類的內容繼承下來。但如果父類有多個構造函數時,該如何選擇調用呢?

第一個規則:子類的構造過程中,必須調用其父類的構造方法。一個類,如果我們不寫構造方法,那麼編譯器會幫我們加上一個默認的構造方法(就是沒有參數的構造方法),但是如果你自己寫了構造方法,那麼編譯器就不會給你添加了,所以有時候當你new一個子類對象的時候,肯定調用了子類的構造方法,但是如果在子類構造方法中我們並沒有顯示的調用基類的構造方法,如:super();  這樣就會調用父類沒有參數的構造方法。    

第二個規則:如果子類的構造方法中既沒有顯示的調用基類構造方法,而基類中又沒有無參的構造方法,則編譯出錯,所以,通常我們需要顯示的:super(參數列表),來調用父類有參數的構造函數,此時無參的構造函數就不會被調用。

總之,一句話:子類沒有顯示調用父類構造函數,不管子類構造函數是否帶參數都默認調用父類無參的構造函數,若父類沒有則編譯出錯。

 

最後,給大家出個思考題:下麵程序的運行結果是什麼?

複製代碼
public class Dervied extends Base {

    private String name = "dervied";

    public Dervied() {
        tellName();
        printName();
    }
    
    public void tellName() {
        System.out.println("Dervied tell name: " + name);
    }
    
    public void printName() {
        System.out.println("Dervied print name: " + name);
    }

    public static void main(String[] args){
        
        new Dervied();    
    }
}

class Base {
    
    private String name = "base";

    public Base() {
        tellName();
        printName();
    }
    
    public void tellName() {
        System.out.println("Base tell name: " + name);
    }
    
    public void printName() {
        System.out.println("Base print name: " + name);
    }
}

最後更新:2017-04-12 23:25:18

  上一篇:go 阻擊外掛——《龍之穀手遊》安全測試的那點事
  下一篇:go 一天學會PostgreSQL應用開發與管理 - 8 PostgreSQL 管理