Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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?

share|improve this question
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). – Joachim Sauer Jul 22 '13 at 11:19
BUt if it were a bug, you could report it here: – Joachim Sauer Jul 22 '13 at 11:28
@JoachimSauer Thanks for that. – Marc van Dongen Jul 22 '13 at 12:04
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. – Marc van Dongen 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. – Joachim Sauer Jul 22 '13 at 12:56
up vote 11 down vote accepted

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

share|improve this answer
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... – Marc van Dongen Jul 22 '13 at 11:53
@MarcvanDongen: exactly. I've edited my answer to link to the relevant part of the JLS. – Joachim Sauer 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. – Marc van Dongen Jul 22 '13 at 12:07
@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. – Joachim Sauer Jul 22 '13 at 12:10
@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 posting your answer, you agree to the privacy policy and terms of service.

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