值类型和引用类型的区别

本文深入解析Java中的值类型与引用类型的区别,详细解释值传递与引用传递的概念,包括基本数据类型与引用类型之间的差异,以及它们在内存分配、垃圾回收机制、装箱与拆箱等方面的应用。通过实例阐述Java中值类型与引用类型如何影响程序行为,帮助开发者掌握Java内存管理的核心知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

[定义]

引用类型表示你操作的数据是同一个,也就是说当你传一个参数给另一个方法时,你在另一个方法中改变这个变量的值,那么调用这个方法是传入的变量的值也将改变.
值类型表示复制一个当前变量传给方法,当你在这个方法中改变这个变量的值时,最初生命的变量的值不会变.
    通俗说法: 值类型就是现金,要用直接用;引用类型是存折,要用还得先去银行取现。----(摘自网上)
[值类型]:à也就是基本数据类型

    基本数据类型常被称为四类八种

四类:   1,整型 2,浮点型 3,字符型 4,逻辑型

八种:   1,整型3种 byte,short,int,long

         2,浮点型2种 float,double

         3,字符型1种 char

         4,逻辑型1种 boolean

[引用类型]

除了四类八种基本类型外,所有的类型都称为引用类型

在弄清楚值类型与引用类型之后,最后一点就是值传递与引用传递,这才是关键
[值传递]
    基本数据类型赋值都属于值传递,值传递传递的是实实在在的变量值,是传递原参数的拷贝,值传递后,实参传递给形参的值,形参发生改变而不影响实参。
[引用传递]
引用类型之间赋值属于引用传递。引用传递传递的是对象的引用地址,也就是它的本身(自己最通俗的理解)。引用传递:传的是地址,就是将实参的地址传递给形参,形参改变了,实参当然被改变了,因为他们指向相同的地址。

引用和我们的指针差不多,但是它不又不需要我们去具体的操作

 [内存分配]

一个具有值类型(value type)的数据存放在内的一个变量中。即是在栈中分配内存空间,直接存储所包含的值,其值就代表数据本身。值类型的数据具有较快的存取速度。

一个具有引用类型(reference type)的数据并不驻留在栈中,而是存储于中。即是在堆中分配内存空间,不直接存储所包含的值,而是指向所要存储的值,其值代表的是所指向的地址。当访问一个具有引用类型的数据时,需要到栈中检查变量的内容,该变量引用堆中的一个实际数据。引用类型的数据比值类型的数据具有更大的存储规模和较低的访问速度。

[java 中的垃圾回收机制]

       当一个堆内存中的对象没有被栈内存中表示地址的值“引用”时,这个对象就被称为垃圾对象,它无法被使用但却占据着内存中的区域,好比这样:

String s = new String(“person”); s = new String(“man”); s本来是指向堆内存中值为person的对象的,但是s突然讨厌person了,它指向了堆内存中的man对象了,person就像一个孤儿一样被s遗弃了,但是person比孤儿还要惨,因为没有什么能找的到它,除了位高权重的‘垃圾回收器’,不过被当官的找到往往没什么好事,尤其是这个‘垃圾回收器’,它会豪不留情把‘垃圾’们清理走,并且无情的销毁,以便释放内存。

[装箱与拆箱]

其实装箱就是值类型到引用类型的转化过程。将一个值类型变量装箱成一个引用类型变量,首先会在托管堆上为新的引用类型变量分配内存空间,然后将值类型变量拷贝到托管堆上新分配的对象内存中,最后返回新分配的对象内存地址。装箱操作是可逆的,所以还有拆箱操作。拆箱操作获取只想对象中包含值类型部分的指针,然后由程序员手动将其对应的值拷贝给值类型变量。

### C# 中值类型引用类型的概述 在C#编程语言里,数据类型分为两大类:值类型引用类型值类型直接保存它们的实际数据,而引用类型存储指向实际对象的引用[^1]。 #### 值类型的特征 - **内存位置**:通常情况下,值类型的数据会被分配到栈(stack)上,这意味着创建速度较快且销毁也迅速。 - **复制行为**:每当传递或赋值一个值类型的变量时,实际上是拷贝了一份完整的数据副本给新的变量。因此修改新变量中的数据不会影响原始变量的内容。 - **不可为空性**:默认状态下,值类型不允许为`null`,除非使用可空(`Nullable`)修饰符来定义该字段可以接受`null`作为合法状态之一。 ```csharp int number = 5; // 下面这条语句会报错因为 int 不允许为 null // int? nullableNumber = null; // 正确写法应加上 ? Console.WriteLine(number); // 输出: 5 ``` #### 引用类型的属性 - **内存管理**:对于引用类型而言,其本身仅包含了一个指针(即地址),真正的对象存在于堆(heap)之中。当声明一个新的引用类型实例化之后,在栈上的部分只记录着通往堆里的具体路径而已。 - **共享特性**:多个不同的引用可能指向同一个对象,所以改变其中一个引用所指向的对象内部成员会影响到通过其它任何相同引用访问的结果。 - **支持 `null`** :不同于值类型,默认情况下所有的引用类型都可以设置成`null`表示未初始化的状态。 ```csharp string strA = "hello"; string strB = strA; strB += " world!"; Console.WriteLine(strA); // 输出: hello Console.WriteLine(strB); // 输出: hello world! ``` 上述代码片段展示了字符串拼接过程中产生的不同结果,尽管最初两个字符串引用相同的常量池条目,但在执行加号运算后产生了全新的字符串并更新了`strB`指向的位置,而原`strA`保持不变[^4]。 #### 性能考量 考虑到性能因素,《CLR via C#》提到过如果开发人员未能充分认识到这两者之间的差异,则可能导致难以察觉的问题以及不必要的资源浪费。例如频繁地将大尺寸结构体当作参数传递可能会带来显著的成本增长;同样地,不当处理大型数组或其他复杂对象也会造成垃圾回收器负担加重等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值