java中方法的最终参数

时间:2013-08-11 10:05:21

标签: java methods final

我对此代码段有2个问题

  1. 方法1工作正常,方法2没有。这是什么原因?
  2. 在方法1中,返回值是字节(8位)。但实际上我们返回一个char值(16位)。 这里到底发生了什么?
  3. //方法1

    static byte m1() {
        final char c = 'b'-'a';
        return c; 
    }
    

    //方法2

    static byte m3(final char c) {
        return c; // 3
    }
    

4 个答案:

答案 0 :(得分:23)

Java中的

char 16位无符号值,而byte 8位有符号值。允许的字节范围是[-128, 127]。因此,并非所有字符都可以在byte中分配。

在第一种方法中,您将返回char 代码点= 1 'b' - 'a')。现在,由于您已将char定义为final,并为其分配常量表达式,因此它将成为编译时常量。因此,编译器不会给出任何编译器错误。

来自JLS Section 5.2

  

如果表达式是byte,short,char或int类型的常量表达式(第15.28节):
       - 如果变量的类型是byte,short或char,并且变量类型中的常量表达式的值,则可以使用缩小的原始转换。

强调我的。

但是,如果你使c成为非最终版,它也会导致编译错误:

static byte m1() {  // This will be an error
    char c = 'b'-'a';
    return c; 
}

原因是,c不再是编译时常量,编译器不会进行隐式向下转换。

在第二种方法中,您将返回您传递的char。参数c没有编译时常量。在编译时不知道该方法可能得到什么值。 例如,如果您传递的char代码点不在允许的byte范围内,则无效。

要使第二种方法有效,您可以进行显式转换:

static byte m3(final char c) {
    return (byte)c; // 3
}

答案 1 :(得分:2)

m1()中,编译器看到char c与值1保持不变,因此不会抱怨,因为它知道它可以适合字节。如果您将其更改为final char c = 128,其中127是您将收到投诉的byte的最大尺寸,就像您从final删除char c变量描述符时一样。

答案 2 :(得分:1)

在方法2中,编译器无法从聊天到字节进行缩小隐式转换,因为它可能导致精度损失(Java支持Unicode字符,并且其char原语类型定义为16位大小信息,与C语言不同,通常为8位)

在方法1中,编译器可以确定常数值''' a'实际上不会导致精度损失,因此允许您执行隐式转换。

看看:http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html

答案 3 :(得分:0)

现在m1()起作用的原因和m3()不起作用的原因是因为m1() c中的compile-time constant

分析此代码:

    byte b = 'x'; //compile-time constant
    int i = 'x'; //compile-time constant
    char c = 'x'; //compile-time constant
    c = i; //compilation error
    c = b; //compilation error
    b = i; //compilation error
    b = c; //compilation error
    i = b;  // Okay
    i = c;  // Okay

对于运行时变量,编译器不会进行隐式转换,这可能会导致数据丢失。