來源:https://www.cnblogs.com/lanxuezaipiao/p/3371224.html

收藏必備——精選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了自身的對象,將從上到下執行構造代碼塊、構造器(兩者可以說綁定在一起)。

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

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) {
System.out.println("-------main start-------");
new HelloB();
new HelloB();
System.out.println("-------main end-------");
}
}

此時輸出結果爲:

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-------

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

A 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);
}
}

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

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

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

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

答案:C

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

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

A 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裏沒有引用傳遞,只有值傳遞

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

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

package test;
/**
* @description Java中沒有引用傳遞只有值傳遞
*
* @author Alexia
* @date 2013-10-16
*
*/
class Person {
private String name;
private String sex;
public Person(String x, String y) {
this.name = x;
this.sex = y;
}
// 重寫toString()方法,方便輸出
public String toString() {
return name + " " + sex;
}
// 交換對象引用
public static void swapObject(Person p1, Person p2) {
Person tmp = p1;
p1 = p2;
p2 = tmp;
}
// 交換基本類型
public static void swapInt(int a, int b) {
int tmp = a;
a = b;
b = tmp;
}
// 交換對象數組
public static void swapObjectArray(Person[] p1, Person[] p2) {
Person[] tmp = p1;
p1 = p2;
p2 = tmp;
}
// 交換基本類型數組
public static void swapIntArray(int[] x, int[] y) {
int[] tmp = x;
x = y;
y = tmp;
}
// 改變對象數組中的內容
public static void changeObjectArray(Person[] p1, Person[] p2) {
Person tmp = p1[1];
p1[1] = p2[1];
p2[1] = tmp;

// 再將p1[1]修改
Person p = new Person("wjl", "male");
p1[1] = p;
}
// 改變基本類型數組中的內容
public static void changeIntArray(int[] x, int[] y) {
int tmp = x[1];
x[1] = y[1];
y[1] = tmp;
x[1] = 5;
}
}
public class ByValueTest {
public static void main(String[] args) {
// 建立並構造兩個對象
Person p1 = new Person("Alexia", "female");
Person p2 = new Person("Edward", "male");
System.out.println("對象交換前:p1 = " + p1.toString());
System.out.println("對象交換前:p2 = " + p2.toString());

// 交換p1對象和p2對象
Person.swapObject(p1, p2);
// 從交換結果中看出,實際對象並未交換
System.out.println("\n對象交換後:p1 = " + p1.toString());
System.out.println("對象交換後:p2 = " + p2.toString());
// 建立兩個對象數組
Person[] arraya = new Person[2];
Person[] arrayb = new Person[2];
// 分別構造數組對象
arraya[0] = new Person("Alexia", "female");
arraya[1] = new Person("Edward", "male");
arrayb[0] = new Person("jmwang", "female");
arrayb[1] = new Person("hwu", "male");
System.out.println('\n' + "對象數組交換前:arraya[0] = "
+ arraya[0].toString() + ", arraya[1] = "
+ arraya[1].toString());
System.out.println("對象數組交換前:arrayb[0] = "
+ arrayb[0].toString() + ", arrayb[1] = "
+ arrayb[1].toString());

// 交換這兩個對象數組
Person.swapObjectArray(arraya, arrayb);
System.out.println('\n' + "對象數組交換後:arraya[0] = "
+ arraya[0].toString() + ", arraya[1] = "
+ arraya[1].toString());
System.out.println("對象數組交換後:arrayb[0] = "
+ arrayb[0].toString() + ", arrayb[1] = "
+ arrayb[1].toString());
// 建立兩個普通數組
int[] a = new int[2];
int[] b = new int[2];
// 給數組個元素賦值
for (int i = 0; i < a.length; i++) {
a[i] = i;
b[i] = i + 1;
}
System.out.println('\n' + "基本類型數組交換前:a[0] = " + a[0] + ", a[1] = " + a[1]);
System.out.println("基本類型數組交換前:b[0] = " + b[0] + ", b[1] = " + b[1]);
// 交換兩個基本類型數組
Person.swapIntArray(a, b);
System.out.println('\n' + "基本類型數組交換後:a[0] = " + a[0] + ", a[1] = " + a[1]);
System.out.println("基本類型數組交換後:b[0] = " + b[0] + ", b[1] = " + b[1]);

// 改變對象數組的內容
Person.changeObjectArray(arraya, arrayb);
System.out.println('\n' + "對象數組內容交換並改變後:arraya[1] = " + arraya[1].toString());
System.out.println("對象數組內容交換並改變後:arrayb[1] = " + arrayb[1].toString());

// 改變基本類型數組的內容
Person.changeIntArray(a, b);
System.out.println('\n' + "基本類型數組內容交換並改變後:a[1] = " + a[1]);
System.out.println("基本類型數組內容交換並改變後:b[1] = " + b[1]);
}
}

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

對象交換前: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();

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

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

D 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)。包裝類也可以包裝另外一個包裝類。

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

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class FileStreamTest {
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
FileOutputStream out = new FileOutputStream("file.dat");
byte[] b = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
out.write(b);
out.close();

FileInputStream in = new FileInputStream("file.dat");
in.skip(9); // 跳過前面的9個字節
int c = in.read();
System.out.println(c); // 輸出爲10
in.close();
}
}

那麼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題的解析。

相關文章