Java 中方法中的最后一个参数

2022-09-03 05:39:43

我有2个问题与此代码段

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

方法 1

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

方法 2

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

答案 1

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

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

来自 JLS 第 5.2 节

如果表达式是字节、短整型、字符型或整型的常量表达式 (§15.28):
- 如果变量的类型为 byte、short 或 char,并且常量表达式的值可在变量类型中表示,则可以使用缩小基元转换。

强调我的。

但是,如果您使非 final,它也将导致编译器错误:c

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

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

在第二种方法中,您将返回您通过的。那里的参数没有编译时常量。在编译时,不知道该方法可能获得什么值。例如,如果您传递的码位不在允许值的范围内,则它将不起作用。charccharbyte

要使第二种方法起作用,您可以执行显式强制转换:

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

答案 2

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