Java值类型和引用类型的区别

背景

  最近在学习Java的设计模式时候,总是经常遇到值类型和引用类型的传递问题。跟着视频和教程去听的时候总是感觉一知半解,所以总结下来。

定义

值类型:又称基本数据类型。值类型表示复制一个当前变量传给方法,当你在这个方法中改变这个变量的值时,最初生命的变量的值不会变。 值类型就是我们经常所说的4类8种:

  • 整型:byte,short,int,long
  • 浮点型:float,double
  • 字符型:char
  • 逻辑型:boolean

引用类型引用类型表示你操作的数据是同一个,也就是说当你传一个参数给另一个方法时,你在另一个方法中改变这个变量的值,那么调用这个方法是传入的变量的值也将改变。 除了值类型外就是引用值类型了,引用值类型主要有:

  • 类(class)
  • 数组
  • 接口类型(interface)
  • 字符串(String)

区别

1.值传递与引用传递的区别

 基本数据类型的赋值是值传递,当值类型变量a赋值给值类型变量b之后,再去改变b的值那么a不会随着b的改变而改变。即值传递传递的是实实在在的变量值,是传递原参数的拷贝,值传递后,实参传递给形参的值,形参发生改变而不影响实参。

int a=1;
int b=a;
b=2;

结果:a=1;b=2;

 引用值类型的赋值是引用传递,传递的是对象的引用地址。当引用值类型变量a赋值给引用值类型变量b之后,再去改变a的值那么b不会随着a的改变而改变。引用类型之间赋值属于引用传递。引用传递传递的是对象的引用地址,也就是它的本身,即将实参的地址传递给形参,形参改变了,实参也会改变了(因为他们指向相同的地址)。

class Message{
    private int num;
 
    public int getNum() { return num; }
    public void setNum(int num) { this.num = num; }
}
 
public class Main {
    public static void main(String[] args) {
        Message msg = new Message();
        //实参赋值
        msg.setNum(100);
        //调用形参的赋值方法
        fun(msg);
        //形参改变,使其实参也发生改变
        System.out.println(msg.getNum());   // 结果为 30
    }
 
    publicstatic  void fun(Message temp){
        temp.setNum(30);
    }
}
2.内存分配的区别

 值类型数据是直接存储在栈中,Java JVM直接在栈中给数据开辟了一块空间,直接存储数据的值

int a=1;  //JVM为变量a在栈中开辟了一块空间(假设为A),栈中存储的是 1;
int b=a;  //JVM为变量b在栈中开辟另了一块空间(假设为B),栈中存储的也是 1; 
a=2;      //为变量a重新赋值,栈空间A中存储的值改为2,栈空间B中存储的值不变为1

 引用类型数据并不是直接存储在栈中,Java JVM会在堆中给数据分配内存空间,堆存储数据。栈存储的是指向对应堆的地址。可以说是栈中的地址引用了堆中的数据
还拿上边的Message为例,以图示做说明
在这里插入图片描述

3.优缺点分析

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

4.垃圾回收机制的区别

值类型:内存中的变量随着方法的结束内存自然销毁了
引用类型:当方法结束的时候,这个对象可能被另一个引用类型所应用,不会销毁,只有当一个对象没有任何引用变量引用的时候,垃圾回收机制才会回收

Java中数据的存放有堆和栈之分

 当一个方法执行时,每个方法都会建立自己的内存栈,在这个方法内定义的变量将会逐个放入这块栈内存里,随着方法的执行结束,这个方法的内存栈也将自然销毁了。因此,所有在方法中定义的变量都是放在栈内存中的

 当我们在程序中创建一个对象时,这个对象将被保存到运行时数据区中,以便反复利用(因为对象的创建成本通常较大),这个运行时数据区就是堆内存。堆内存中的对象不会随方法的结束而销毁,即使方法结束后,这个对象还可能被另一个引用变量所引用(方法的参数传递时很常见),则这个对象依然不会被销毁,只有当一个对象没有任何引用变量引用它时,系统的垃圾回收机制才会在核实的时候回收它。

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值