问题
Why this is giving the compile time error? 2 is constant at compile time, therefore narrowing should be allowed here since 2 is in range of byte.
public class Test {
public static void main(String[] args) {
ForTest test=new ForTest();
test.sum(1, 2); //compile time error here
}
}
class ForTest
{
public int sum(int a,byte b)
{
System.out.println("method byte");
return a+b;
}
}
The error is: The method sum(int,byte) in the type ForTest is not applicable for the arguements (int,int).
Edit: I think the answer lies here: http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.3 but I am not getting it :(
回答1:
You have to distinguish between assignment conversion and method invocation conversion.
Narrowing Primitive Conversion
First of all, look at JLS §5.1.3:
22 specific conversions on primitive types are called the narrowing primitive conversions:
[...]
int to byte, short, or char
[...]
Note, that this only explains the mechanism but not the places where such conversions are allowed or not.
Assignment Conversion
Next, look at JLS §5.2:
[...]
In addition, 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.
[...]
This clearly describes that in the assignment byte b = 2
the narrowing conversion from type int to type byte is allowed.
Method Invocation Conversion
However, when reading JLS §5.3 you will not read anything about a narrowing conversion. So the compiler is doing a correct job.
回答2:
This is because 2 is interpreted as an int, which cannot be implicitly converted into a byte.
Your choices are either to change the method signature to (int a, int b
), or to explicitly do a casting: test.sum(1, (byte)2)
回答3:
You can't type cast int
to byte
implicitly.
Call method as:
sum(1, (byte)2);
回答4:
Revised answer:
The java language specification says that when looking for candidate matches for function calls, after the candidates have been found based upon the name of the function, and the number of actual vs. formal parameters, it eventually arrives at phase 2.
"If m is not a generic method, then m is applicable by loose invocation if, for 1 ≤ i ≤ n, either ei is compatible in a loose invocation context with Fi or ei is not pertinent to applicability."
Evidently, when it arrive at the second actual parameter, it is deciding that an 'int' is not compatible in a 'loose invocation context' with 'byte'. Therefore it rejects the one and only matching candidate it found in phase 1.
I'm unable to find a formal definition of "loose invocation" in the JLS.
Thanks to VikasMangal and KisHanarsecHaGajjar for pointing out the stupidity of my original answer which is repeated below for eternal shame.
My original answers the comments refer to is below.
Java spec section 5.1.3 says you should be able to do this.
Additionally in section 5.2 on assignment of constants it says
"In addition, 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."
However, the compiler seems to be going it's own way.
回答5:
Since Narrowing Primitive Conversions(§5.1.3) says that narrowing of int
is done into byte
, short
, or char
. So you need to cast the int
to byte
where you calling the method. Like this :
test.sum(1, (byte)2);
回答6:
You can achieve more with the primitive integer. Thus, everytime you write a value that can be an "integer" value, Java automatically wants to cast and thus treat it like an integer.
The converse of this is what happens when you try what you tried here. Java sees a value which can fit as an integer but for it to treat it as a byte, you need to explicitly tell. It's a bit like saying, OK, I know what I am doing and I do realize that casting a number to a byte has its limitations but I want you to do it anyway.
来源:https://stackoverflow.com/questions/24424686/how-does-narrowing-work-in-method-invocation-in-java