2

The following IMHO valid java program doesn't compile because the Oracle 1.7 javac compiler thinks there's a possible loss of precision in lines 5 and 6. If you uncomment line 3 and comment out line 4, it compiles fine.

Would someone explain why the compiler believes there is a loss of precision on the assignment to either byte b2 or b3?

public class BUG {
    public static void main( String[] args ) {
        //final byte b1 = 9;
        byte b1 = 9;
        final byte b2 = -b1;    // fine if line 3 is uncommented and line 4 is commented
        final byte b3 = 0 - b1; // fine if line 3 is uncommented and line 4 is commented
    }
}

If my sample code is correct, then I'd like to report this as a bug but I can't find out where. Would someone explain what the compiler error message is saying in this case and why it's correct?

4
  • 5
    If you think you've found a bug in a compiler or other basic tool used by thousands of people, you're usually wrong (not always, but you are in this case). Jul 22 '13 at 11:19
  • 1
    BUt if it were a bug, you could report it here: bugreport.sun.com/bugreport Jul 22 '13 at 11:28
  • Thanks for editing the question. I was thinking of doing this myself but I wasn't sure if this was considered done in this forum. Jul 22 '13 at 12:55
  • As long as you don't fundamentally change what you asked, you (and anyone else, for that matter) are free to edit your question to make it easier to grasp. Jul 22 '13 at 12:56
11

It's not a bug, it's acting exactly as specified.

With the final byte b1 the compiler is sure that b1 will have the value 9 and -b1 becomes a compile time constant expression. The compiler can then check that the value is still acceptable for a byte and let's you do it.

When b1 is not final then -b1 is an expression like any other and as such b1 will be promoted to int (see JLS §5.6.1. Unary Numeric Promotion). And since the conversion from int back to byte can result in loss of precision, the compiler doesn't allow it (without an explicit cast).

7
  • Thanks Joachim. Are you saying that '-b1' in the context of byte b1 results in an int? I'd have to read up the language spec if that's true... Jul 22 '13 at 11:53
  • @MarcvanDongen: exactly. I've edited my answer to link to the relevant part of the JLS. Jul 22 '13 at 11:56
  • Thanks. I'm not sure if I like this idea of promoting byte expressions to ints. I wanted to write some document some code using bytes to indicate the range of the expressions was in the byte realm. If I have to cast the results of promoted values back to byte, this completely defeats the purpose of the exercise. Anyway, I'll study the section in the JLS. Jul 22 '13 at 12:07
  • 1
    @MarcvanDongen: byte is a definite second-class citizen in the Java world, and only existed because they really couldn't do without it. For any kind of calculation int and long behave much more natural. Jul 22 '13 at 12:10
  • 1
    @JoachimSauer: Indeed not. The type system rules to deduce the expression type may be identical here, the consequences of the resulting type mismatch are not.
    – MSalters
    Jul 22 '13 at 13:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.