The output from the following code is 123
because substring
takes from beginIndex to EndIndex - 1. However, I am surprised how char
so substring's function declaration looks like substring(int startIndex, int endIndex). Now when you pass char it is automatically promoted to integer (endIndex) and hence treated as int.
Technically, this is because char
is a subtype of int
.
To determine whether substring(int,int)
is applicable to argument (int,char)
, we first try 15.12.2.2 Phase 1: Identify Matching Arity Methods Applicable by Subtyping, we need to test whether char
is a subtype of int
. Per 4.10.1 Subtyping among Primitive Types, it is.
Then, to assign the char
argument to the int
parameter, per 15.12.4.5 Create Frame, Synchronize, Transfer Control, we apply 5.3 Method Invocation Conversion, which converts char
to int
, per 5.1.2 Widening Primitive Conversion
This goes all the way back to C, where char
is in essence a narrow integer type and gets implicitly converted to int
whenever necessary.
In Java, this is technically known as a "widening primitive conversion", and is covered in section 5.1.2 of the JLS.
This is known as implicit casting. The same occurs if you assign an int value to a double. Quick example
double d = 1;
1 is an int
but it is implicitly cast to double
(1.0).
In char a = 3;
, you could think of it as storing 0011
, the binary value of 3. The char '3' is not actually being stored: If you tried treating is a char, you would not get 3
. But if you did
char a = '3';
Now you're storing the char 3, an ascii value of 51, and if you tried using it as in int, you would get 51.
Take a look at section 5.1.2, where it discusses widening conversions.