方法传递和内部方法的不同char转换行为

时间:2014-02-14 08:09:34

标签: java casting char

我的代码很简单:

class A {
     public static void main(String[] args){
        char c = 65; // ok
        new A().m(65); // compile error
     }     
     void m(char c){}
}

我想知道原因

char c = 65; 

是可能的,但是

new A().m(65); // compile error

不可能!

谁能解释?

谁可以为类似问题指定通用规则?

2 个答案:

答案 0 :(得分:11)

您正在研究的是方法调用转换和分配转换之间的区别。

用简单的语言来说,在两种情况下,转换规则是不同的

案例#1:作业转换

char c = 5;

如您所知,这是一份作业陈述。当被分配的对象不是预期的类型时,可能会发生一些转换,无论如何都要进行分配。

案例#2:方法调用转换

def foo(char c){}
[...]
foo(5);

这(最后一行)是一个方法调用。这是类型文字可能与声明不匹配的另一个地方,因此转换规则可能适用。

那么,为什么它们不同?

Java的设计者已经为这两种情况实现了不同的转换规则。在案例#1中,规则是(来自JLS):

  

...缩小的原始转换可能   如果满足以下所有条件,则使用:

     
      
  • 表达式是byte,short,char或int类型的常量表达式。
  •   
  • 变量的类型是byte,short或char。
  •   
  • 表达式的值(在编译时已知,因为它是一个常量表达式)可以在类型中表示   变量。
  •   

所以int - >案例#1中的char转换正在由Java编译器进行专门检查并自动解决。

然而,案例#2中的规则是不同的。在这里,Java的设计者不希望实现他们用于赋值语句的自动转换。从“程序员指南到Java认证:综合入门”:

  

请注意,方法调用和赋值转换的区别在于一个   方面:方法调用转换不包含隐式   缩小对整数常量表达式执行的转换。

那么,为什么两种情况有不同的规则?基本上,Java的设计者认为自动转换是有用且方便的,但是由于具有太多的键入灵活性,它可能会使事情过于复杂。他们认为案例#1是一个足够简单的情况,我们可以进行转换而不会失去清晰度,但案例#2则不然。以下是JLS的理由:

  

方法调用转换特别不包含隐式   缩小整数常量,这是赋值转换的一部分。   Java编程语言的设计者认为包括   这些隐含的缩小转换会增加额外的复杂性   到重载方法匹配解决过程。

具体而言,这是JLS 5.1, 5.2 and 5.3

修改

关于“重载方法匹配解决过程的额外复杂性”,我的假设是他们试图避免这种情况:

def foo(int i){}
def foo(char c){}

foo(5); // OH NO which of the above gets called??@!?!?! 

答案 1 :(得分:-3)

阅读规范是正确的,但对我来说很难。

我提供的权利较少但答案更简单:

我写的时候:

new A().m(65); // compile error

完全模拟:

int n =65;
char c = n;

显然(显然对我来说)编译错误

我希望有人希望。