Normally, integer literals are always interpreted as int - the reason that it works in a line where you declare and initialize a byte is because that statement is treated as a special case by the Java compiler.
The reason why Java does not allow this with a method that takes a byte is because it can lead to confusing situations. For example:
To avoid all these potential problems, Java simply does not automatically convert values to a byte.
Note also that the byte declaration and initialization only works when you initialize the byte with a compile-time constant. This, for example, doesn't work:
Nick Widelec wrote:And how come that for widening conversion it works.. that's quite confusing.
Why shouldn't it? We're talking about numeric conversions here, so it stands to reason that if I can store 1 in a byte, I should be able to convert it to a short, int or long.
What is slightly more mystifying is why Java allows double→float conversions without a specific cast; but I'm sure they had their reasons.
Method invocation conversions specifically do not include the implicit narrowing of integer constants which is part of assignment conversion (§5.2). The designers of the Java programming language felt that including these implicit narrowing conversions would add additional complexity to the overloaded method matching resolution process (§15.12.2).
Thus, the program:
causes a compile-time error because the integer literals 12 and 2 have type int, so neither method m matches under the rules of (§15.12.2). A language that included implicit narrowing of integer constants would need additional rules to resolve cases like this example.