In theory, a byte can't be assigned to a char as the byte is signed and the char unsigned. The final modifier allows compile time optimizations (See Bruce Eckels book: "In the case of a compile-time constant, the compiler is allowed to �fold� the constant value into any calculations in which it�s used; that is, the calculation can be performed at compile time, eliminating some run-time overhead. In Java, these sorts of constants must be primitives and are expressed with the final keyword. A value must be given at the time of definition of such a constant."). I guess this may have to do with the answer. Anyway, does the real exam include these types of questions (optimization questions - this one, String optimization with pools, etc.). Besides, don't they depend on the special compiler (I mean, does the JLS say something about it ?)
The "char" is unsigned datatype in that it stores only positive values. The "byte" datatype on the other hand stores both positive and negative values.
The conversion from byte to char will only happen if the compiler can determine the value of the byte variable ( variable b in ur example) at compile time. Since u have specified the byte variable with the final modifier, the compiler knows the value that you are assigning to the char variable at compile time.
When you removed the final modifier the compiler could not determine the value of the byte variable at compile time. So it could be that the byte value might have negative values so the compiler complains that the types are incompatible.