java筆試——錯題集1

Java基礎&糾錯
1.知識點:null,靜態(靜態方法也叫類方法)
public class TestClass {
private static void testMethod(){
System.out.println(“testMethod”);
}
public static void main(String[] args) {
((TestClass)null).testMethod();
}
}
//編譯正確,輸出testMethod

A.null可以被強制類型轉換成任意的類型(TestClass)null,這裏被轉成了一個類,所以可以通過類名調用靜態方

法。

package NowCoder;
class Test {
public static void hello() {
System.out.println(“hello”);
}
}
public class MyApplication {
public static void main(String[] args) {
// TODO Auto-generated method stub
Test test=null;
test.hello();
}
}
//編譯正確,能正確運行

B.值得一說的是這個空指針問題,如果出現空指針必須去引用堆對象纔會有空指針,在這個地方hello()是直接通

過類名調用的靜態方法,根本不存在空指針問題
C.另外值得一提的是Test test = null;這句,可以先把他理解成,在棧中開闢空間給了Test test 然後這個所指

向的地址值爲空吧,所以這個類是進行了初始化的,可以使用其中的靜態方法,靜態變量。
D.靜態要注意一點,無法在靜態上下文引用非靜態變量,所以直接調用方法的時候,要注意要麼都是靜態,要麼都

是非靜態。不然就要通過創建對象,實例化調用方法

2.知識點:同步
下面關於java的一些細節問題,描述錯誤的是?
a.構造方法不需要同步化
b.一個子類不可以覆蓋掉父類的同步方法

A.構造方法每次都是創建新的對象,不存在多個線程同時讀寫同一對象中屬性的問題,所以不需要同步;
B.如果父類中的某個方法是用了synchronized關鍵字,而子類中也覆蓋這一方法,那默認情況下子類的這個方法是

不同步的,必須顯示的在子類的這個方法中加上synchronized關鍵字纔可;當然也可以在子類中調用父類中相應的

方法,這樣雖然子類中的方法並不是同步的,但子類調用了父類的同步方法,也就相當於子類方法也同步了

3.知識點:構造方法,方法和類名
下面說法正確的有
a.constructor必須與class同名,但是方法不能與class同名

A.方法可以與類同名,和構造方法的唯一區別就是,構造方法是沒有返回值的,構造方法可以由任意訪問修飾符修

飾訪問,如public,protected,private,但是不能由static,finally等修飾符修飾。

4.知識點:泛型數據
在開發中使用泛型數據取代非泛型數據(比如用ArrayList取代ArrayList),程序運行時的性能會更好


錯誤

A.泛型僅僅是java語法的語法糖,它不會影響java虛擬機生成彙編代碼,在編譯階段,虛擬機就會把泛型的類型還

原成沒有泛型的代碼,頂多編譯速度稍微曼一些,但是執行的時候,速度是完全沒有區別的

5.知識點:方法重寫和方法重載

A.方法重載:同一個類下,同名方法的參數的類型、順序、個數不同。和返回值類型無關,返回值類型可以相同也

可以不同,當同一個類中方法同名同參數類型順序和個數,只有返回值不同的時候,編譯報錯。

class A{
public A foo(){return this;}
}
class B extends A{
public A foo(){
return this;
}
}
class C extends B

{
_

}
下面哪句可以放到橫線位置,使程序正確編譯運行?
a.public void foo(){}
b.public int foo(){return 1;}
c.public A foo(B b){return b;}
d.public A foo(){return A;}
答案是c

B.子類重寫父類方法要遵循”兩同兩小一大原則”
1)兩同:方法名相同,形參列表完全相同
2)兩小:子類方法的返回值類型應該比父類方法的返回值類型更小或者相等;子類方法拋出的異常類應該比父類

方法拋出的異常類更小或者相等。(這裏要注意,返回值類型的更大更小,是對於同一類型而言的,也就是說,返

回值的類型需要有繼承關係次啊會去考慮大小這個概念,類型不同會報錯。即使父類返回double,子類返回int也

不行)
3)一大:子類方法的訪問權限應該比父類方法的訪問權限更大,或者相等

6.知識點:抽象類和接口

A.抽象類:

1)抽象類有構造方法(不給出就是默認的無參),但是不能創建對象實例化。
2)抽象類中可以存在普通屬性,靜態屬性,普通方法和靜態方法
3)抽象類中可以沒有抽象方法,只有普通方法,也可以是抽象類;但是隻要有抽象方法的類就一定是抽象類
4)抽象類中的抽象方法是一定要被子類實現(重寫的),所以抽象方法不可以被private,static,synchronized,native修飾,可以說這就是其設計的目的,如果子類沒有重寫抽象類

中抽象方法,那麼子類也必須是一個抽象類
5)抽象類類名的修飾符必須要有abstract,訪問修飾符既可以是public也可以是默認修飾符

B.接口:

1)接口名的修飾符默認是abstract(默認是隱藏的,所以可以加上去),訪問修飾符既可以是public也可以是默認

修飾符
2)接口中只有常量,因爲在接口中成員變量都被public static final默認修飾
3)接口沒有構造方法,也不能被創建對象實例化
4)接口中只有方法的聲明,沒有方法體
5)接口中的方法都被public abstract默認修飾
6)接口可以多實現,即一個類可以實現多個接口
7)接口中的所有方法實現類必須全部重寫,如果實現類不能實現接口中的所有方法,那麼這個類必須被定義爲抽

象類
8)Jdk1.8的新特性接口可以有靜態方法,默認方法了,也就是說可以有static void method(){};靜態方法和

default void method(){}默認方法了 ,需要注意的是static,default,abstract,三個修飾符對一個方法

只能三選一(都被public默認修飾),被static,default修飾時候{}不可以省略,並且接口的實現類可以重寫這

個方法,也可以不重寫這個方法,但是如果被abstract修飾,是一個抽象方法,那還必須符合之前的定義

7.知識點:ArrayList,LinkList,instanceof

public static void main(String args[]) {
List Listlist1 = new ArrayList();
Listlist1.add(0);
List Listlist2 = Listlist1;
System.out.println(Listlist1.get(0) instanceof Integer);
System.out.println(Listlist2.get(0) instanceof Integer);
}
//輸出結果:true true

A.collection類型的集合(ArrayList,LinkList)只能裝入對象類型的數據,該題中裝入了0,是一個基本類型,但

是在jdk5以後提供了自動裝箱和自動拆箱,所以int類型就自動裝箱成了Interger類型,能夠正常的編譯
B.instanceof是java中的關鍵字,用於判斷一個對象是否屬於某個特定類的實例,並返回boolean類型的返回值,

顯然這兩個都是Integer類型的值

8.知識點:異常小分類

A.checked exception:指的是編譯時異常,該類異常是本函數必須處理的,用try和catch處理,或者用throws拋

出異常,然後交給調用者去處理
B.Runtime exception:指的是運行時異常,該類異常不是本函數必須處理的,當然也可以處理

9.知識點:Thread.sleep(),Object.wait()

A.thread:線程;interrupt 中斷;Thread.sleep()和Object.wait()都可以拋出InterruptedException(中斷

異常)這個異常是不能被忽略的,屬於checked exception(檢測異常),而lllegalArgumentException(非法運

算)屬於Runtim exception
10.知識點:try,catch,finally

1.public abstract class Test {
public static void main(String[] args) {
System.out.println(beforeFinally());
}

public static int beforeFinally(){
    int a = 0;
    try{
        a = 1;
        return a;
    }finally{
        a = 2;
    }
}

}
/**output:
1
*/

2.public abstract class Test {
public static void main(String[] args) {
System.out.println(beforeFinally());
}

public static int beforeFinally(){
    int a = 0;
    try{
        a = 1;
        return a;
    }finally{
        a = 2;
        return a;
    }
}

}
/**output:
2
*/

A.Code1執行流程:當程序執行到try{}語句中的return方法時,會做這麼一件事,將要返回的結果儲存到一個臨

時棧中,然後程序不會立即返回,而是去執行finally{}中的程序,在執行a = 2時,程序僅僅是覆蓋了a的值,但

是不會去更新臨時棧中要返回的值,執行完之後,就會通知主程序”finally{}程序執行完畢,可以請求返回了”

,這時就會將臨時棧中的值取出來返回,所以輸出:1
B.Code2中,finally{}裏也有一個return,那麼在執行這個return時,就會更新臨時棧中的值,同樣在執行完

finally{}的程序後,會通知主程序請求返回,這時將臨時棧中的值取出來,輸出:2
C. finally語句在try或catch中的return語句執行之後,返回值返回之前執行且finally裏的修改語句不能影響

try或catch中 return已經確定的返回值,若finally裏也有return語句則覆蓋try或catch中的return語句直接返

回。
D..多個return是按順序執行的的,多個return執行了一個後,後面的return就不會執行了。(不考慮finally中有

return中的情況)
E.finally{}中return必須在輸出語句之後,否則會報錯
F.最後其實可以同樣的將finally中的return分成基本數據類型和引用數據類型,即finally中的return對基本數

據類型的返回不會有任何影響,但是對於引用的數據類型,會產生影響,這和數組等的參數傳遞問題是一脈相承的

3.public class Test{
public int add(int a,int b){
try {
return a+b;
}
catch (Exception e) {
System.out.println(“catch語句塊”);
}
finally{
System.out.println(“finally語句塊”);
}
return 0;
}
public static void main(String argv[]){
Test test =new Test();
System.out.println(“和是:”+test.add(9, 34));
}
}
//輸出結果:
//finally語句塊
//和是:43

G. 這裏先輸出finally語句塊的原因是,要考慮到字符串拼接是一個整體,所以是先要執行test.add(9,34),得到

結果後再輸出,但是這裏執行test.add(9,34)的時候,需要執行finally{},輸出”finally語句塊”

11.封裝類,Boolean

Boolean flag = false;
if (flag = true)
{
System.out.println(“true”);
}
else
{
System.out.println(“false”);
}
//編譯成功輸出:true

A.Boolean修飾的變量爲包裝類型(包裝類對象),初始值爲false,進行賦值操作的時候會調用

Boolean.valueOf(boolean b)方法自動拆箱爲基本數據類型,因此

11.知識點——類型轉換
byte b1=1,b2=2,b3,b6,b8;
final byte b4=4,b5=6,b7;
b3=(b1+b2); /語句1/
b6=b4+b5; /語句2/
b8=(b1+b4); /語句3/
b7=(b2+b5); /語句4/
System.out.println(b3+b6);
下列代碼中存在編譯錯誤的是?

1.Java表達式(千萬注意,只有出現表達式,纔會考慮類型轉換的問題,如果右邊是值,就是賦值問題,比如右邊是兩個final型的變量相加,其實就是兩個常數相加然後賦值給左邊,但是隻要有一個是變量,就要考慮類型轉換的問題,整數默認爲int類型,小數默認爲double類型)轉型規則由低到高轉換:
1、所有的byte,short,char型的值將被提升爲int型;
2、如果有一個操作數是long型,計算結果是long型;

3、如果有一個操作數是float型,計算結果是float型;

4、如果有一個操作數是double型,計算結果是double型;
5、被fianl修飾的變量不會自動改變類型,當2個final修飾相操作時,結果會根據左邊變量的類型而轉化。
————–解析————–
語句1錯誤:b3=(b1+b2);自動轉爲int,所以正確寫法爲b3=(byte)(b1+b2);或者將b3定義爲int;
語句2正確:b6=b4+b5;b4、b5爲final類型,不會自動提升,所以和的類型視左邊變量類型而定,即b6可以是任意數值類型;
語句3錯誤:b8=(b1+b4);雖然b4不會自動提升,但b1仍會自動提升,所以結果需要強轉,b8=(byte)(b1+b4);
語句4錯誤:b7=(b2+b5); 同上。同時注意b7是final修飾,即只可賦值一次,便不可再改變。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章