单个引用变量如何访问所有对象字段? [英] How can a single reference variable access to all object fields?

查看:147
本文介绍了单个引用变量如何访问所有对象字段?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Animal myAnimal = new Animal();

我上面有这个代码。据我所知,它会做这些事情:

I have this code above. As far as I know, it will do these things :


  1. 将在堆内存上创建一个动物对象

  2. 对该对象的引用将传递给引用变量myAnimal
    换句话说,myAnimal变量保存堆上Animal对象的内存地址。

我不明白的是


  1. 记忆如何地址值看起来像?

  2. 这是一个地址还是众多地址值?如果只有一个,myAnimal如何访问Animal对象的所有对象字段,如myAnimal.name,myAnimal.height,......?



<请问有人可以解释一下吗?在此先感谢。

Can anyone explain this please? Thanks in advance.

推荐答案

Java虚拟机规范

The Java Virtual Machine Specification states


有三种引用类型:类类型,数组类型,
和接口类型。 它们的值是引用到动态
创建的类实例,数组或类实例或
分别实现接口的数组。

There are three kinds of reference types: class types, array types, and interface types. Their values are references to dynamically created class instances, arrays, or class instances or arrays that implement interfaces, respectively.

澄清


reference 类型的值可以被视为 as指向对象的指针

Values of type reference can be thought of as pointers to objects.

所以变量 myAnimal in

Animal myAnimal = new Animal();

存储指向 Animal 对象的指针在堆上。

is storing a pointer to the Animal object on the heap.

你问


内存地址值是怎样的?

How does the memory address value look like?

内存地址通常只是一个数值,它是进程'已分配内存的偏移量。当进程读取该值时,它可以直接寻址该位置并从中读取或写入(将其视为数组中的偏移索引)。

A memory address is typically just a numerical value that's an offset into the process' allocated memory. When a process reads that value, it can directly address that location and read from or write to it (think of it as an offset index in an array).

对象本身不仅仅是它的地址。实际上,当垃圾收集器移动对象时,它的地址可以在JVM进程的生命周期内多次更改。

The object itself is more than just its address. In fact, its address can change multiple times over the lifetime of the JVM process as the garbage collector moves objects around.

然而, JVMS没有指定对象的内部结构。

However, the JVMS does not specify the internal structure of an object.


Java Virtual Machine不要求任何特定的内部
结构用于对象。

The Java Virtual Machine does not mandate any particular internal structure for objects.

在Oracle的一些Java虚拟机实现中,
参考一个类实例是一个指向句柄的指针,该句柄本身是
a指针对:一个包含
对象方法的表和一个指向$ b $类型的Class对象的指针b对象,另一个是从堆中分配的内存,用于
对象数据。

这没有太大帮助,但是我们可以假设为对象数据分配的内存必须足够大以包含所有对象的字段,并且数据需要快速访问,即。在恒定时间内,而不是与数据量成比例。典型的解决方案是再次使用偏移。以此类为例

This doesn't help greatly, but we can assume that the memory allocated for the object data has to be large enough to contain all the object's fields and the data needs to be accessible quickly, ie. in constant time, as opposed to proportionally to the amount of data. The typical solution is to again use offsets. Take this class for example

class Animal {
    private String name;
    private byte height;
}

字段名称 String 类型,一种引用类型,我们知道它实际上只存储一个指针。如果我们假设我们的JVM只需要32位来存储指针,我们知道这个字段只需要32位。

The field name is of type String, a reference type, which we know essentially just stores a pointer. If we assume our JVM only needs 32 bits to store a pointer, we know we only need 32 bits for this field.

字段 height 的类型为 byte ,其中指定只需要8位。

The field height is of type byte, which is specified to only need 8 bits.

因此每个 Person 对象实际上只需要 32 +8 位,其数据为5个字节。 JVM最有可能为其内部组织分配更多,但让我们简化为这5个字节。在您的示例中,JVM将为 name 分配前4个字节,为 age 分配下一个字节。类似

So each Person object really only needs 32+8 bits, 5 bytes for its data. The JVM will most likely allocate more than that for its internal organization, but let's simplify to just those 5 bytes. In your example, the JVM will allocate the first 4 bytes for the name and the next byte for the age. Something like

 0        8       16       24       32       40
 +--------+--------+--------+--------+--------+
 |               name                | height |

你问


这是一个地址还是众多地址值?如果只有一个,
myAnimal如何访问Animal对象的所有对象字段,如
myAnimal.name,myAnimal.height,...?

Is that one address or numerous address value? If only one, how can myAnimal have accesses to all object fields of Animal object like myAnimal.name, myAnimal.height,...?

myAnimal 只保留一个地址,但表达式如

myAnimal holds only one address, but an expression like

myAnimal.height

可以被认为是读取1个字节(因为我们知道 height 的类型为byte)来自内存的地址,加上4确定的地址(因为 height的数据位置 name 所需的4个字节偏移到 myAnimal 中存储的值。

can be thought of as reading 1 byte (because we know height is of type byte) from memory at the address determined by adding 4 (because the location of the data for height is offset by the 4 bytes needed for name) to the value stored in myAnimal.

考虑 myAnimal 存储指向内存地址 12 ,用名称初始化,指向内存地址 1345 的字符串和高度值为6.在内存中,这可能看起来像

Consider myAnimal storing a pointer to a memory address of 12, initialized with a name pointing to a String at memory address 1345 and a height value of 6. In memory, that could look like

                   myAnimal
                      |
                      v
Heap:             ...12.......13.......14.......15.......16.......17
Object offsets:   ....0        1        2        3        4        5
                  ....+--------+--------+--------+--------+--------+ 
                      |               1345                |    6   | 

要读取 myAnimal.height ,JVM将计算 12 + 4 = 16 并读取该偏移处的字节( 6 )。要为 myAnimal.name 分配新值,JVM将计算 12 + 0 ,并写入4个字节代表某些新的指针值,覆盖 1345

To read myAnimal.height, the JVM would calculate 12 + 4 = 16 and read the byte (6) at that offset. To assign a new value to myAnimal.name, the JVM would calculate 12 + 0, and write 4 bytes representing some the new pointer value, overwriting the 1345.

这篇关于单个引用变量如何访问所有对象字段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆