首页 > 试题广场 >

下面有关值类型和引用类型描述正确的是()?

[不定项选择题]
下面有关值类型和引用类型描述正确的是()?
  • 值类型的变量赋值只是进行数据复制,创建一个同值的新对象,而引用类型变量赋值,仅仅是把对象的引用的指针赋值给变量,使它们共用一个内存地址。
  • 值类型数据是在栈上分配内存空间,它的变量直接包含变量的实例,使用效率相对较高。而引用类型数据是分配在堆上,引用类型的变量通常包含一个指向实例的指针,变量通过指针来引用实例。
  • 引用类型一般都具有继承性,但是值类型一般都是封装的,因此值类型不能作为其他任何类型的基类。
  • 值类型变量的作用域主要是在栈上分配内存空间内,而引用类型变量作用域主要在分配的堆上。

我的理解(有错麻烦大家指正,谢谢!)

值类型:基本数据类型(int、double、boolean ...)
引用类型:reference类型,通过它可以直接或间接的查找到对象在java堆中数据存放的起始地址或索引(对象在java堆中的哪个位置)

先来两个例子,变量的赋值在内存中是怎么样的:
先上一张运行时数据区的网图
局部变量表、操作数栈在虚拟机栈中

一:基本变量的赋值

public void method() {
    int a = 1;
    int b = a;
}

该方法的字节码:
    0 iconst_1  // 将 int 型 1 推送至操作数栈栈顶
    1 istore_1  // 将操作数栈栈顶 int 型值存入第二个本地变量
    2 iload_1   // 将第二个int型本地变量推送至操作数栈顶
    3 istore_2  // 将操作数栈栈顶 int 型值存入第三个本地变量
    4 return    // 方法返回

图片说明

二:基本变量的赋值

public void method2() {
    Object a = new Object();
    Object b = a;
}

该方法的字节码:
    0 new #15 <java/lang/Object> // 创建一个对象,并将其引用压入栈顶
    3 dup  // 复制栈顶引用类型数据并将其值压入栈顶
    4 invokespecial #1 <java/lang/Object.<init>>  // 执行对象构造方法(使用了栈顶引用类型)
    7 astore_1  // 将操作数栈栈顶引用类型数据值存入第二个本地变量 a
    8 aload_1   // 将第二个引用类型本地变量推送至栈顶
    9 astore_2  // 将栈顶引用类型数值存入第三个本地变量b
    10 return   // 方法返回

图片说明

再看选项

  • A(✔)值类型的和引用类型的变量赋值就像上面一样,先把局部变量表中 a 的数值存入操作数栈,再取出来放入 b,不过区别在于:

    • 前者在局部变量表中存放的数值是真正意义上的 a 代表的数据,所以说赋值操作是“复制(iload_1、istore_2)”一份出来再给 b
    • 后者在局部变量表中存放的数值不是真正意义上 a 代表的数据,只是指向堆中对象的指针(指向 a 真正代表的数据)。赋值操作只是把 a 中数值即指针复制给 b ,堆中a代表正真的数据即对象(0x11)并没有被复制
  • B(✔)

    • "值类型数据是在栈(指虚拟机栈)上分配内存空间,它的变量直接包含变量的实例,使用效率相对较高。" :局部变量表(在虚拟机栈中)中存放数值的就是真正意义上的数据,不用访问堆,效率较高
    • “而引用类型数据是分配在上,引用类型的变量通常包含一个指向实例(指向堆中对象)的指针,变量通过指针来引用实例。” :局部变量表中存放的数值是指向中数据(对象)的指针
  • C(✔):类可以继承,基本数据类型不能继承

  • D(X):“值类型变量的作用域主要是在栈上分配内存空间内”:如果是跟上诉一致在方法内定义的基本变量,它的作用域就在栈中;如果是在类中定义的成员变量例如 Class A 中有成员变量 int val,这个类的实例在堆中,那么 val 作用域也在堆中


题外话:操作数栈深度在编译期就已经决定
编辑于 2021-04-12 16:27:12 回复(53)
引用类型的变量也在栈区,只是其引用的对象在堆区
发表于 2021-03-24 12:51:36 回复(7)
按我的理解D为啥错的吧,基本数据类型分配在栈中。引用变量分配在栈中,引用指向堆区,类似指针变量在栈中它指向堆。
发表于 2021-03-27 23:41:56 回复(1)
还能有谁?”机智“如我🙄
发表于 2021-11-24 20:49:56 回复(5)
A(✔):值类型的和引用类型的变量赋值就像上面一样,先把局部变量表中 a 的数值存入操作数栈,再取出来放入 b,不过区别在于: 前者在局部变量表中存放的数值是真正意义上的 a 代表的数据,所以说赋值操作是“复制(iload_1、istore_2)”一份出来再给 b 后者在局部变量表中存放的数值不是真正意义上 a 代表的数据,只是指向堆中对象的指针(指向 a 真正代表的数据)。赋值操作只是把 a 中数值即指针复制给 b ,堆中a代表正真的数据即对象(0x11)并没有被复制 B(✔): "值类型数据是在栈(指虚拟机栈)上分配内存空间,它的变量直接包含变量的实例,使用效率相对较高。" :局部变量表(在虚拟机栈中)中存放数值的就是真正意义上的数据,不用访问堆,效率较高 “而引用类型数据是分配在堆上,引用类型的变量通常包含一个指向实例(指向堆中对象)的指针,变量通过指针来引用实例。” :局部变量表中存放的数值是指向堆中数据(对象)的指针 C(✔):类可以继承,基本数据类型不能继承 D(X):“值类型变量的作用域主要是在栈上分配内存空间内”:如果是跟上诉一致在方法内定义的基本变量,它的作用域就在栈中;如果是在类中定义的成员变量例如 Class A 中有成员变量 int val,这个类的实例在堆中,那么 val 作用域也在堆中
发表于 2021-11-02 23:07:41 回复(0)
看不懂,等一个大佬来解析
发表于 2021-03-25 16:38:14 回复(0)
按他的答案分析,目测这是Java.不是cpp
发表于 2020-08-18 12:12:27 回复(0)
京东面试题答案:下面有关值类型和引用类型描述正确的是()?
A 值类型的变量赋值只是进行数据复制,创建一个同值的新对象,而引用类型变量赋值,仅仅是把对象的引用的指针赋值给变量,使它们共用一个内存地址。
B 值类型数据是在栈上分配内存空间,它的变量直接包含变量的实例,使用效率相对较高。而引用类型数据是分配在堆上,引用类型的变量通常包含一个指向实例的指针,变量通过指针来引用实例。
C 引用类型一般都具有继承性,但是值类型一般都是封装的,因此值类型不能作为其他任何类型的基类。
D 值类型变量的作用域主要是在栈上分配内存空间内,而引用类型变量作用域主要在分配的堆上。
解析:
B错在,值类型变量不包含实例,实例是针对于对象的概念,当类实例化为对象的时候,这个时候可以称为是类的一个实例。同时,效率比较高这个概念比较模糊。
C错在,封装的概念也是针对类而言的,值类型数据不存在封装概念。
D错在,值类型变量可以作为成员变量存储在堆里,例如一个Class A中包含一个int value,那么value是作为成员变量存储在堆中的。D选项表述有漏洞。
发表于 2023-02-27 11:36:59 回复(1)
如果是成员变量,也在栈中?这不对吧
发表于 2021-04-24 19:03:12 回复(1)
狗东 java题目,选A。
发表于 2020-10-26 23:17:51 回复(0)
局部变量才在虚拟栈中,成员变量在堆中
发表于 2022-10-18 01:36:46 回复(0)
我觉得ABCD才是正确答案。
值类型主要在栈上分配内存空间,
引用类型变量也在栈中、引用的对象在堆中。
发表于 2021-08-12 15:17:14 回复(0)
引用类型变量保存的是对象的引用,及对象的地址,保存在栈中。
发表于 2021-03-29 15:56:35 回复(0)
区分 引用类型数据 和 引用类型变量
发表于 2021-12-20 05:44:12 回复(0)
引用变量在栈区,只是引用的对象在堆区
发表于 2021-08-27 09:50:44 回复(0)
引用传递不会在堆分配空间。
发表于 2021-03-26 10:11:53 回复(0)
感觉bd都不对吧,变量的位置要看在类哪个位置决定的
发表于 2021-03-24 10:11:19 回复(1)
有分析吗兄弟们
发表于 2020-12-24 16:13:20 回复(0)
局部变量存放在虚拟机栈中,而非静态成员变量存放在堆中,静态成员变量存放在方法区。值类型变量(基本数据类型)存放真实的数值,引用数据类型变量存放堆地址。
发表于 2023-09-13 16:06:27 回复(0)
引用类型的对象是存储在堆中,但引用它的变量是在栈中
发表于 2023-07-16 16:46:33 回复(0)