2017-10-19 48 views
0

我在Android的寫一些JUnit測試,如果我這樣做:曖昧方法調用與整數

public void testSetId(){ 
    Friend friend = new Friend(5); 
    assertEquals(5,friend.getId()); 
} 

我得到一個模棱兩可的方法調用錯誤。

曖昧的方法調用: 兩者的assertEquals(INT,INT)和 的assertEquals(對象,對象)相匹配

但如果我這樣做:

public void testSetId(){ 
    Integer ID = 5; 
    Friend friend = new Friend(ID); 
    assertEquals(ID, friend.getId()); 
} 

它的工作原理。我覺得第二個功能應該完成同樣的事情。

這是怎麼回事?

+1

是否定義了'id' Friend是int還是Integer? – GriffeyDog

+0

ID是一個整數 – user2782067

+0

您可以確認getId()的返回類型是Integer而不是int嗎? –

回答

2

在Java 5之前,沒有自動裝箱或自動拆箱。這意味着,如果fooInteger類型的參數的方法,下面沒有編譯

foo(5); // 5 needs to be autoboxed 

同樣,如果barint類型的參數的方法,這並不能編譯

bar(new Integer(5)); // The Integer needs to be unboxed 

當引入自動裝箱和自動拆箱時,現有代碼必須繼續以與以前完全相同的方式工作。因此,當編譯器決定調用哪個方法時,它首先只考慮不需要自動裝箱或自動拆箱的適用方法。只有在沒有這樣的方法時,編譯器纔會考慮需要自動裝箱和/或自動拆箱的方法。

getId由於返回一個Integer,所述ObjectObject方法可以在不情況下自動裝箱當第一個參數也是Integer被調用。但是隻能通過自動拆箱第二個參數來調用int,int方法。因此在第二個例子中,第一遍選擇了Object,Object過載。

在第一個示例中,您嘗試通過intIntegerint,int方法僅適用於自動拆箱第二個參數,而Object,Object方法僅適用於自動裝箱第一個參數。因此,在第一遍中不能選擇重載,並且因爲兩種方法都不比其他方法更具體(您需要查看最後一頁),編譯器無法在兩種方法之間進行選擇。

重載解析是非常複雜的,我實際上已經簡化了一下(還有涉及var-args的規則)。然而在實踐中,你並不需要了解所有這些規則 - 如果有的話,你需要告訴要應用的方法,你總可以顯式轉換或鑄編譯:

assertEquals((Integer) id, friend.getId());