2017-08-02 58 views
2

爲了改進ESAPI的編碼方法來處理非BMP字符,我遇到了意想不到的行爲。這是有趣的,至少可以說...爲什麼char不能自動裝箱到Java中的字符?

這個單元測試:

public void testCSSEncodeChar0x100() 
{ 
    char in = 0x100; 
    String inStr = Character.toString(in); 
    String expected = "\\100 "; 
    String result; 

     result = cssCodec.encodeCharacter(EMPTY_CHAR_ARRAY, in); 
    // this should be escaped 
     assertFalse(inStr.equals(result)); 
     assertEquals(expected,result); 
} 

我曾在我的腦海裏 - 只有一個目標方法。我有兩種方法:

@Override 
public String encodeCharacter(char[] immune, Character c) { 
    return ""+c; 
} 

@Override 
public String encodeCharacter(char[] immune, int codePoint) { 
    return new StringBuilder().appendCodePoint(codePoint).toString(); 
} 

我本來期望的Java的變量in autobox到Character,而是它上溯造型得到了一個int並最終調用第二種方法。

Tried Google,在這個非直觀的行爲上沒有得到任何答案。

至於什麼工作,只需更改in的類型從charCharacter解決了這個問題。

+0

向後兼容性 - 當他們加入自動裝箱,他們無法改變依賴於自動裝箱不會發生的舊代碼的含義。這裏有一個地方有一個地方。 – user2357112

回答

6

的Java 可以charCharacter完美輕鬆。這將工作得很好:

Character c = in; 

但是,爲了向後兼容,重載分辨率出現在多個階段。在早期版本的Java中(自動裝箱之前),第二種方法已經適用(因爲總是有從charint的擴大轉換),但第一種方法不會是......所以這是第二種方法。

當您將in的類型從char更改爲Character時,只有第一種方法適用,因此用它來代替。

JLS 15.12.2包含的細節:

該過程的其餘部分被分成三個階段,以確保的Java SE 5.0之前,Java編程語言的版本兼容。的階段是:

  • 第一階段(§15.12.2.2),而不允許拳擊或取消裝箱轉換,或使用可變元數的方法調用的執行重載解析。如果在此階段沒有找到適用的方法,則處理繼續到第二階段。 [...]

  • 第二階段(§15.12.2.3)在允許裝箱和取消裝箱的同時執行重載解析,但仍排除使用變量方法調用。如果在此階段沒有找到適用的方法,則處理繼續到第三階段。 [...]

  • 第三階段(§15.12.2.4)允許將重載與變量arity方法,裝箱和拆箱相結合。
+0

向後兼容性...我的意思是,我不應該感到驚訝......謝謝你也指出,我被困在自動裝箱,並沒有考慮重載解決方案! – avgvstvs

相關問題