为了改进ESAPI的编码方法以处理非BMP字符,我遇到了意外的行为。有趣的是,至少可以说......
本单元测试:
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
自动装箱到Character
,而是将其上传到int
并最终调用第二种方法。
Tried Google,对此非直观行为没有任何答案。
至于哪些方法有效,只需将in
的类型从char
更改为Character
即可解决问题。
答案 0 :(得分:6)
Java 可以框char
到Character
非常容易。这样可以正常工作:
Character c = in;
但是,为了向后兼容,多个阶段会发生重载决策。在Java的早期版本(自动装箱之前)中,您的第二种方法已经适用(因为从char
到int
的转换总是如此)但第一种方法不会......所以这是第二种方法。
当您将in
的类型从char
更改为Character
时,只有第一种方法适用,因此请改为使用。
JLS 15.12.2包含详细信息:
该过程的其余部分分为三个阶段,以确保与Java SE 5.0之前的Java编程语言版本兼容。阶段是:
第一阶段(§15.12.2.2)执行重载解析而不允许装箱或拆箱转换,或使用变量arity方法调用。如果在此阶段没有找到适用的方法,则处理继续到第二阶段。 [...]
第二阶段(第15.12.2.3节)执行重载解析,同时允许装箱和拆箱,但仍然排除使用变量arity方法调用。如果在此阶段没有找到适用的方法,则处理继续到第三阶段。 [...]
- 第三阶段(§15.12.2.4)允许重载与变量arity方法,装箱和拆箱相结合。