已关闭,此问题需要更focused。它目前不接受回答。
**想改善这个问题吗?**更新问题,使其只关注editing this post的一个问题。
昨天关门了。
Improve this question
当我们对一个变量做一些操作时,我们只是改变指针到另一个字面量?我对“字面”一词的确切含义有点困惑。
假设int x = 3;// 3是文字和不可变的,x是变量
正在为ex进行操作:X++
现在x == 4所以我们的变量x只是指向一个新的字面量。计算机只记得3 + 1等于4吗?
已关闭,此问题需要更focused。它目前不接受回答。
**想改善这个问题吗?**更新问题,使其只关注editing this post的一个问题。
昨天关门了。
Improve this question
当我们对一个变量做一些操作时,我们只是改变指针到另一个字面量?我对“字面”一词的确切含义有点困惑。
假设int x = 3;// 3是文字和不可变的,x是变量
正在为ex进行操作:X++
现在x == 4所以我们的变量x只是指向一个新的字面量。计算机只记得3 + 1等于4吗?
1条答案
按热度按时间r7knjye21#
x不是指针。
JVM规范只是说明了发生了什么;* 如何 * 它发生是故意不指定。所以,这个答案只是解释了它如何在我所知道的所有JVM上工作。几乎一样好。它当然应该澄清一些问题:
在这里,任何时候执行
new Example()
,都会为这个示例保留一些内存块。对象的示例只是一个内存块,它保存了它的基本属性(包括这是一个Example
类型的对象)和存储 every 非静态字段值的空间。在本例中,int x
-这是一个非静态字段。基元是特殊的数据类型:这是一个硬编码列表:int、long、short、byte、double、float、boolean和char。就这样。这就是整个列表,你不能添加任何新类型。它们是“特殊的”--任何原始类型的值都只是值。不是指针。
因此,
int x = 3
意味着任何创建新Example示例(new Example()
)的尝试都会在内存中保留一些空间来存储x
字段的值,该值为 directly 3。它不是一个指向3对象的指针。只是... 3.它至少需要32位(因为int
是32位),实际上可能需要64位(CPU几乎要求对象很好地对齐:在64位CPU上,它们从一个可被64整除的值开始)。x++
简单地找到位序列为0000.0000011的内存位置(0011
是'3'的二进制),并将其递增,将其变为0000.0000100。相反,让我们尝试一个对象-任何不在原语列表中的东西都是对象,所有这样的值都是指针。(在Java中,“引用”)。所以,在这个稍微改变的代码中:
一些非常非常不同的事情正在发生。对于初学者来说,自动装箱:这是语法糖,编译起来就像你写的那样:
为什么?因为JLS是这么说的--这就是当你尝试
x++
时会发生的事情,其中x
是一个非原始类型,* 但是 *,可以自动装箱为int
。那么,这里发生了什么?谁知道呢?谁在乎呢-
valueOf
的代码做了它做的事情。它按照规范说的那样工作,问 * 如何工作 * 通常没有用。但是,如果你感兴趣:Integer
(类)在加载时(它总是这样,因为它是这样的核心类)创建一个“缓存”,并为-128和+127之间的每个值创建1个缓存对象。Integer.valueOf
将返回该高速缓存中的值(即传递给它的参数在-128和+127之间),否则它会创建一个新的对象。假设3和4适合,你会得到这样的结果:Java中的
x + 1
可以工作,因为规范是这样说的。它没有一些查找表,说'3 + 1是4',增加的概念是烘焙到CPU。忘记指针之类的东西吧,计算机是二进制的,所以数字只能严格地以零和一的形式存在。因此,即使是-1也很棘手(没有'-'。只有0和1!然而,仅仅因为一个数字是以二进制存储的,并不意味着加法是不可能的。假设,5和9:
要把它们相加,你要做的和把两个十进制数相加一样。添加每个元素,并确保携带任何多余的。所以:
???????0
??????10
。?????110
。等等到达
00001110
。不需要查找表来完成此操作。只是一个重复的应用这个微不足道的表:| 搬入|数字1|数字2|输出|携带|
| --|--|--|--|--|
| 0 | 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 1 | 0 |
| 0 | 0 | 1 | 1 | 0 |
| 0 | 1 | 1 | 0 | 1 |
| 1 | 0 | 0 | 1 | 0 |
| 1 | 1 | 0 | 0 | 1 |
| 1 | 0 | 1 | 0 | 1 |
| 1 | 1 | 1 | 1 | 1 |
这个逻辑(那个“表”+重复应用于每个数字的逻辑)被烘焙到你的CPU的硅中。