对象在Java中很容易理解。对象被构造,在堆中被分配空间,然后你把它分配给一个指向它的变量名(引用)。没什么大不了的。但是原始类型是如何表示的呢?它们位于何处(堆栈或堆)?
当我想知道Integer.toString(int)
方法可能是什么样子时,我想到了这个问题。它无法解析文本,因为。。。它不是文本。它不能显式或隐式调用toString()
方法,因为这既是循环逻辑,也是公然无视基元类型不能为其分配方法这一事实(因为它们不是对象)。我认为,对于Integer.MIN_VALUE
和Integer.MAX_VALUE
之间的所有可能的int
值,该方法在逻辑上可能具有大量的if/else
条件,但这似乎也比它应该的复杂得多
那么这是怎么回事呢?
但是基元类型是如何表示的?
基元类型的实例在内存中表示为位模式。因此,例如,int
被表示为32位(4个字节,1个32位字)。
它们位于哪里(堆栈或堆)?
两者皆有。这取决于您将原始值保存在哪种变量中。
我想知道Integer.toString(int)方法可能是什么样子。
该方法的核心是一个简单的算法,它是一个重复的循环
- 通过取余数10取最后一个十进制数字,并且
- 将数字除以10
就像手动将二进制数转换为十进制数一样。
(有关详细信息,请查看源代码。每个Sun/Oracle JDK都包含核心库的源代码。或者,您可以通过谷歌搜索在互联网上轻松找到源代码(各种版本)。)
无需怀疑Integer.toString(int)
是什么样子的(链接显示了Java 6的OpenJDK实现),它使用了一个包专用帮助函数getChars
,它只需将数字的每一位以10为基数进行划分。
以下是代码的关键:(从第354行开始)
// Generate two digits per iteration
while (i >= 65536) {
q = i / 100;
// really: r = i - (q * 100);
r = i - ((q << 6) + (q << 5) + (q << 2));
i = q;
buf [--charPos] = DigitOnes[r];
buf [--charPos] = DigitTens[r];
}
方法是使用Java字节码实现的。查看此参考资料,了解如何使用字节码实现一个简单的方法。通常,解释器或实时编译器(JIT)执行这些字节码。
从本质上讲,有一个堆栈可以包含对象引用或基元类型。字节码允许您对堆栈上的项进行操作(添加其中两个,或对其中一个调用方法,等等)