简体   繁体   English

为什么在Java中char不能自动装箱到Character?

[英]Why does char not autobox to Character in Java?

Working to improve ESAPI's encoding methods to handle non-BMP characters, I encountered unexpected behavior. 在努力改进ESAPI的编码方法以处理非BMP字符时,我遇到了意外的行为。 It was interesting, to say the least... 至少可以说这很有趣...

This unit test: 本单元测试:

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

I had in my mind--only one target method. 我脑子里只有一种目标方法。 I have two methods: 我有两种方法:

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

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

I would have expected Java to autobox the variable in to a Character , but instead, it got upcast to an int and ended up calling the second method. 我本来期望Java来autobox变量inCharacter ,而是它上溯造型得到了一个int ,最终调用第二种方法。

Tried Google , didn't get any answers on this non-intuitive behavior. 尝试过Google ,但对于这种非直觉的行为没有得到任何答案。

As to what worked, simply changing the type of in from char to Character resolved the problem. 至于有效的方法,只需将in的类型从char更改为Character解决问题。

Java can box char to Character perfectly easily. Java 可以完美地将char装箱到Character This will work fine: 这将正常工作:

Character c = in;

However, overload resolution occurs in multiple phases for the sake of backwards compatibility. 但是,为了向后兼容,过载解析会在多个阶段中发生。 In early versions of Java (before autoboxing) your second method would already have been applicable (as there's always been a widening conversion from char to int ) but the first method wouldn't have been... so it's the second method that's picked. 在Java的早期版本中(自动装箱前),您已经可以使用第二种方法(因为从charint转换一直在扩大),但是第一种方法却没有……所以,这是我们选择的第二种方法。

When you change the type of in from char to Character , only the first method is applicable, so that's used instead. 当您将in的类型从char更改为Character ,仅第一种方法适用,因此将其代替。

JLS 15.12.2 contains the details: JLS 15.12.2包含以下详细信息:

The remainder of the process is split into three phases, to ensure compatibility with versions of the Java programming language prior to Java SE 5.0. 该过程的其余部分分为三个阶段,以确保与Java SE 5.0之前的Java编程语言版本兼容。 The phases are: 这些阶段是:

  • The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. 第一阶段(第15.12.2.2节)执行重载解析,不允许装箱或拆箱转换,也不允许使用可变arity方法调用。 If no applicable method is found during this phase then processing continues to the second phase. 如果在此阶段未找到适用的方法,则处理将继续进行到第二阶段。 [...] [...]

  • The second phase (§15.12.2.3) performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation. 第二阶段(第15.12.2.3节)在允许装箱和拆箱的同时执行重载解析,但仍排除使用可变arity方法调用。 If no applicable method is found during this phase then processing continues to the third phase. 如果在此阶段未找到适用的方法,则处理将继续进行到第三阶段。 [...] [...]

  • The third phase (§15.12.2.4) allows overloading to be combined with variable arity methods, boxing, and unboxing. 第三阶段(第15.12.2.4节)允许将重载与可变arity方法,装箱和拆箱相结合。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM