牛课题记录:下面有关值类型和引用类型描述正确的是()?

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

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值