简体   繁体   English

java中方法的最终参数

[英]Final parameter in a method in java

I have 2 questions with this code segments 我对这段代码有2个问题

  1. method 1 is working fine and method 2 doesn't. 方法1工作正常,方法2没有。 What is the reason for this? 这是什么原因?
  2. In method 1 return value is byte(8 bit). 在方法1中,返回值是字节(8位)。 But we actually return a char value(16 bit). 但实际上我们返回一个char值(16位)。 what is actually happening here? 这里到底发生了什么?

//method 1 //方法1

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

//method 2 //方法2

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

char in Java is a 16 bit unsigned value, while byte is 8 bit signed value. Java中的char16位无符号值,而byte8位有符号值。 Allowed range for byte is [-128, 127] . 允许的字节范围是[-128, 127] So, not all character can be assigned in byte . 因此,并非所有字符都可以在byte分配。

In your first method, you are returning a char with code point = 1 ( 'b' - 'a' ). 在第一个方法中,您将返回一个代码点为1'b' - 'a' )的char Now since you have defined char as final , and assigning to it a constant expression, it becomes a compile time constant. 现在,因为您已将char定义为final ,并为其分配常量表达式,所以它将成为编译时常量。 So, compiler doesn't give any compiler error. 因此,编译器不会给出任何编译器错误。

From JLS Section 5.2 : 来自JLS第5.2节

If the expression is a constant expression (§15.28) of type byte, short, char, or int: 如果表达式是byte,short,char或int类型的常量表达式(第15.28节):
- A narrowing primitive conversion may be used if the type of the variable is byte, short, or char, and the value of the constant expression is representable in the type of the variable. - 如果变量的类型是byte,short或char,则可以使用缩小的基元转换,并且常量表达式的值可以在变量的类型中表示

Emphasis mine. 强调我的。

However, if you make c non-final, it will also result in a compiler error: 但是,如果你使c非final,它也会导致编译错误:

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

The reason is, c is not a compile time constant any more, and compiler doesn't do an implicit downcast. 原因是, c不再是编译时常量,编译器不进行隐式向下转换。

In 2nd method you are returning the char that you passed. 在第二种方法中,您将返回您传递的char The parameter c there is not a compile time constant. 参数c没有编译时常量。 It isn't known at compile time what value the method might get. 在编译时不知道该方法可能得到什么值。 Like, if you pass a char with code points not in range of allowed byte value, it won't work. 就像,如果你传递一个char在允许的范围与代码点不是byte值,它不会工作。

To make the 2nd method work, you can do an explicit cast: 要使第二种方法有效,您可以进行显式转换:

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

In m1() the compiler sees that char c is constant with value 1 and therefore does not complain as it knows it can be fit into byte. m1() ,编译器看到char c是值为1常量,因此不会抱怨,因为它知道它可以适合字节。 If you changed it to final char c = 128 where 127 is the maximum size of the byte you would get complaint, as you also would when you removed the final variable descriptor from char c . 如果你将它更改为final char c = 128 ,其中127是你将得到投诉的byte的最大大小,就像你从char c删除final变量描述符时一样。

In method 2, the compiler cannot make a narrowing implicit cast from chat to byte, because it could result in a loss of precision (Java supports Unicode characters, and its char primitive type is defined with the size of 16-bits of information, differently from C language where it is usually 8 bits) 在方法2中,编译器不能从聊天到字节进行缩小的隐式转换,因为它可能导致精度损失(Java支持Unicode字符,并且其char原语类型定义为16位信息的大小,不同从C语言,它通常是8位)

In method 1 though, the compiler can determine that the constant value 'b'-'a' will not actually result in a loss of precision, and so allows you to perform the implicit cast. 但是在方法1中,编译器可以确定常量值'b' - 'a'实际上不会导致精度损失,因此允许您执行隐式转换。

Take a look at: http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html 看看: http//docs.oracle.com/javase/specs/jls/se7/html/jls-5.html

Now the reason m1() works and m3() doesn't is because in m1() c is a compile-time constant . 现在m1()工作的原因和m3()不起作用是因为在m1() c是compile-time constant

Analyse this code: 分析这段代码:

    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

Compiler will not do an implicit cast which can possibly result in loss of data, for run-time variables. 对于运行时变量,编译器不会进行可能导致数据丢失的隐式转换。

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

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