从下面的代码的输出是因为123
substring
从beginIndex花费ENDINDEX - 1。然而,我很惊讶char
这里如何被理解为3(INT),因为取substring
两个整数。这背后的概念是什么?传递焦炭引入方法与int参数
String x = "12345";
char a = 3;
x = x.substring(0, a);
System.out.println(x);
从下面的代码的输出是因为123
substring
从beginIndex花费ENDINDEX - 1。然而,我很惊讶char
这里如何被理解为3(INT),因为取substring
两个整数。这背后的概念是什么?传递焦炭引入方法与int参数
String x = "12345";
char a = 3;
x = x.substring(0, a);
System.out.println(x);
这又回到C,其中char
在本质上是窄的整数类型和被隐式转换为int
每当必要的所有道路。
在Java中,这在技术上被称为“扩展原始转换”,并在section 5.1.2 of the JLS中进行了介绍。
so substring的函数声明看起来像substring(int startIndex,int endIndex)。 现在,当你传递char时,它会自动提升为整数(endIndex),因此被视为int。
查看5.1.2部分,其中讨论了扩大转换。
这就是所谓的隐式铸造。如果将一个int值赋给double,则会发生同样的情况。 快速示例
double d = 1;
1为int
但它是隐式转换为double
(1.0)。
其他人已经解释了为什么它可以工作,但请注意,对于索引使用char变量是一种不好的做法,因为它们具有不同的关联语义,因此使用char作为索引会造成混淆。
只能使用字符来存储字符数据,可能更好:尽量避免使用char,因为它们甚至不足以存储每个字符(请参阅Unicode和代码点的讨论)。使用int来存储字符代码点。
在char a = 3;
中,你可以把它看作存储0011
,二进制值为3. char'3'实际上并没有被存储:如果你尝试了治疗是一个字符,你不会得到3
。但是,如果你没有
char a = '3';
现在要存储的焦炭3,51 ASCII值,如果你试图用它作为INT,你会得到51
技术上讲,这是因为char
是int
的子类型。
要确定substring(int,int)
是否适用于争论(int,char)
,我们首先尝试15.12.2.2 Phase 1: Identify Matching Arity Methods Applicable by Subtyping,我们需要测试char
是否是int
一个亚型。 Per 4.10.1 Subtyping among Primitive Types,是。
随后,向char
参数分配给int
参数,每15.12.4.5 Create Frame, Synchronize, Transfer Control,我们应用5.3 Method Invocation Conversion,它转换char
到int
,每5.1.2 Widening Primitive Conversion
+1 ..它归结为不考虑'char'作为字母或字符,而是作为计算机能够映射到字母或字符的一部分数据。然后,为了促进这个过程,我们做了一些快捷方式让我们直接将字母或字符分配给'char's(比如'char c ='x';'意思是“变量c表示的一段数据是值映射到字符'x'。“变量'c'不再是系统中任何其他数据的字母。) – corsiKa