java创建对象时,new 出一个对象 和 = null的区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java创建对象时,new 出一个对象 和 = null的区别相关的知识,希望对你有一定的参考价值。

new 一个对象需要相应开辟一个物理空间,而null不需要
如果是null,后续需要使用时必须先对其进行赋值,例如String b = null, 后续就不能是用b.indexof(",")等对象的方法进行操作,必须对b赋值后才能
而new一个对象则可以,例如String b = "asdga"; 可以直接使用b.indexof(",")
一般是在对象作用域里面才会用null这个创建;
例如User user = null;
try

user = userservice.find();

catch


类似这种需要情况就可以使用null而不是是new 一个对象,这个可以节省一个空间
参考技术A new对象之后则有这个实体,有这个东西了,而=null表示只是有一个名字,没有实质的东西。
new 出来的就已经是实体了,这个实体会占用内存的,并且是一个对象的形式存在。
null并不会占用内存,只是一个空的指向。本回答被提问者采纳

Java 对象创建过程

对象创建

在语言层面,创建一个对象通常仅一个new关键字就可以解决了,但是在虚拟机中,对象的创建要经过一个复杂的过程。

方法区中的常量池

当虚拟机遇到一个new关键字时,首先去方法区中的常量池中找有没有这个类的符号引用,并检查这个符号代表的类是否已经被加载、解析和初始化过,如果没有先执行类的加载过程。

堆内存

类加载完成后,接下来在虚拟机中的堆上划分出一块内存,存储类的对象(大小在类加载完成后,根据其内部的变量类型与引用就可以确定类需要的空间大小)。由于GC的机制不同,所以在分配时可能存在两种机制。

空闲列表法

如果垃圾回收机制为标记清除法那么虚拟机必须维护一个列表,记录着哪一块内存可用,再分配时找到一块足够大的空间,划分给类对象实例。

指针碰撞法

如果垃圾回收机制为复制算法标记整理法,那么在分配内存时,直接将指针向空闲区域移动一段与对象大小相等的距离即可。

在内存分配时,解决多线程同步的问题,有两种方案:一种是对分配内从空间的动作做同步处理;另一种是吧内存分配按照线程划分,即每个线程在Java堆中预先分配一小块内存,成为本地线程分配缓冲。

内存分配完成后,虚拟机将分配到的内存空间都初始化为零,这一步操作保证了对象中成员对象的初始化。

对象在内存中的存储结构

对象在内存中的存储结构可以分为对象头,实例数据,对齐填充。

对象头

对象头中存储了两部分信息,一部分存储对象自身运行时数据,如HashCode,GC分代年龄,锁状态标志等。对象头的另外一部分存储着类型指针,指向对象类元数据,虚拟机通过这部分信息确定对象是哪一个类的实例。

如果对象为数组,对象头中还应该记录数组的长度。因为不同对象可以通过类的元数据确定对象的大小,但是通过数组的元数据无法得知数组的长度。

实例数据

实例数据部分存储着对象的有效信息,主要是成员变量。无论是从父类继承的,还是在子类中定义的都要记录下来。存储的顺序主要受虚拟机分配策略的影响。

HotSpot中的分配策略为:long/double,int,short/char,byte/boolean,opps(Ordinary Object Pointers)。相同宽度的字段总是被放到一起,在满足这个条件的情况下,父类中定义的变量总是放到子类之前。

对齐填充

主要因为HotSpot自动内存管理系统要求对象起始地址必须是8字节的整数倍。

以上是关于java创建对象时,new 出一个对象 和 = null的区别的主要内容,如果未能解决你的问题,请参考以下文章

java创建对象时,new 出一个对象 和 = null的区别

Java 对象创建过程

Java内存区域与内存溢出异常---对象的创建

java每次都new出个对象干嘛

java-匿名对象

string创建了多少个对象 Java