简体   繁体   中英

Final parameter in a method in java

I have 2 questions with this code segments

  1. method 1 is working fine and method 2 doesn't. What is the reason for this?
  2. In method 1 return value is byte(8 bit). But we actually return a char value(16 bit). what is actually happening here?

//method 1

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

//method 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. Allowed range for byte is [-128, 127] . So, not all character can be assigned in byte .

In your first method, you are returning a char with code point = 1 ( 'b' - 'a' ). Now since you have defined char as final , and assigning to it a constant expression, it becomes a compile time constant. So, compiler doesn't give any compiler error.

From JLS Section 5.2 :

If the expression is a constant expression (§15.28) of type byte, short, char, or int:
- 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.

Emphasis mine.

However, if you make c non-final, it will also result in a compiler error:

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.

In 2nd method you are returning the char that you passed. The parameter c there is not a compile time constant. 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.

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. 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 .

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)

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.

Take a look at: 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 .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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