当前位置: 首页 > news >正文

常熟做网站青岛找网站建设公司

常熟做网站,青岛找网站建设公司,平面设计有哪些工作岗位,百度推广平台登录入口面试回答 创建的对象数 应该是1个或者2个。 首先要清楚什么是对象? Java 是一种面向对象的语言,而 Java 对象在 JVM 中的存储也是有一定的结构的,在 HotSpot 虚拟机中,存储的形式就是 oop-klass model,即 Java 对象模型…

面试回答

创建的对象数 应该是1个或者2个。

首先要清楚什么是对象?

Java 是一种面向对象的语言,而 Java 对象在 JVM 中的存储也是有一定的结构的,在 HotSpot 虚拟机中,存储的形式就是 oop-klass model,即 Java 对象模型。我们在 Java 代码中,使用 new 创建一个对象的时候,JVM 会创建一个 instanceOopDesc 对象,这个对象中包含了两部分信息,对象头以及元数据。对象头中有一些运行时数据,其中就包括和多线程相关的锁的信息。元数据其实维护的是指针,指向的是对象所属的类的 instanceKlass。

这才叫对象。其他的,一概都不叫对象。

那么不管怎么样,一次 new 的过程,都会在堆上创建一个对象,那么就是起码有一个对象了。至于另外一个对象,到底有没有要看具体情况了。

另外这一对象就是常量池中的字符串常量,这个字符串其实是类编译阶段就进到 Class 常量池的,那么当这个类第一次被 ClassLoader 加载的时候,会从 Class 常量池进入到运行时常量池。

在运行时常量池中,也并不是会立刻被解析成对象,而是会先以 JVM_CONSTANT_UnresolveString_info 的形式驻留在常量池。在后面,该引用第一次被 LDC 指令执行到的时候,就尝试在堆上创建字符串对象,并将对象的引用驻留在字符串常量池中。

通过看上面的过程,你也能发现,这个过程的触发条件是我们没办法决定的,问题的题干中也没有提到。有可能执行这段代码的时候是第一次 LDC 指令执行,也许在前面就执行过了。

所以,如果是第一次执行,那么就是会同时创建两个对象。一个字符串常量引用指向的对象,一个我们 new 出来的对象。

如果不是第一次执行,那么就只会创建我们自己 new 出来的对象。

至于有人说什么在字符串池内还有在栈上还有一个引用对象,你听听这说法,引用就是引用。别往对象上面扯。

知识扩展

字面量和运行时常量池

JVM 为了提高性能和减少内存开销,在实例化字符串常量的时候进行了一些优化。为了减少在 JVM 中创建的字符串的数量,字符串维护了一个字符串常量池。

在 JVM 运行时区域的方法区中,有一块区域是运行时常量池,主要用来存储编译器生成的各种字面量符号引用

intern

编译器生成的各种字面量符号引用是运行时常量池中比较重要的一部分来源,但是并不是全部。那么还有一种情况,可以在运行期间运行时常量池中添加常量。那就是 Stringintern 方法。

当一个 String实例调用 intern()方法时,Java 查找常量池中是否有相同 Unicode 的字符串常量,如果有,则返回其的引用,如果没有,则在常量池增加一个 Unicode 等于 str 的字符串并返回它的引用。

intern() 有两个作用,第一个是将字符串字面量放入常量池(如果池没有的话),第二个是返回这个常量的引用。

intern 的正确用法

不知道,你有没有发现,在 String s = new String("Tango").intern();中,其实 intern是多余的?

因为就算不用 intern, Tango 作为一个字面量也会被加载到 Class 文件的常量池,进而加入到运行时常量池中,为啥还要多此一举呢?到底什么场景下才需要使用 intern呢?

在解释这个之前,我们先来看下代码:

      String s1="Tango";String s2="Chi";String s3=s1+s2;String s4="Tango"+"Chi";

在经过反编译后,得到代码如下:

        String s1 = "Tango";String s2 = "Chi";String s3 = (new StringBuilder()).append(s1).append(s2).toString();String s4 = "TangoChi";

可以发现,同样是字符串拼接,s3和s4在经过编译器编译后的实现方式并不一样。s3被转化成 StringBuilderappend,而 s4 被直接拼接成新的字符串。

如果你感兴趣,你还能发现,String s3 = s1 + s2;经过编译之后,常量池中是有两个字符串常量的分别是 TangoChi(其实 TangoChiString s1="Tango";String s2="Chi";定义出来的),拼接结果 TangoChi并不在常量池中。

如果代码只有 String s4 = "Tango" + "Chi";,那么常量池中将只有 TangoChi 而没有 TangoChi

究其原因,是因为常量池要保存的是已确定的字面量值。也就是说,对于字符串的拼接,纯字面量和字面量的拼接,会把拼接结果作为常量保持到字符串池。

如果在字符串拼接中,有一个参数是非字面量,而是一个变量的话,整个拼接操作会被编译成 StringBuilder.append,这种情况编译器是无法知道其确定值的。只有在运行期才确定。

那么,有了这个特性了,intern就有了用武之地了。那就是很多时候,我们在程序中得到的字符串只有在运行期才能确定的,在编译期是无法确定的,那么也就没办法在编译期被加入到常量池中。

这时候,对于那种可能经常使用的字符串,使用 intern进行定义,每次 JVM 运行到这段代码的时候,就会直接把常量池该字面值的引用返回,这样就可以减少大量字符串对象的创建了。

如一深入解析 String#intern 文中举的一个例子:

    static  final int Max = 1000 * 100000;static final String[] arr = new String[Max];public static void main(String[] args) {Integer [] DB_DATA=new Integer[10];Random random=new Random(10*10000);for (int i = 0; i < DB_DATA.length;i++) {DB_DATA[i]=random.nextInt();}long t=System.currentTimeMillis();for (int i = 0; i < Max; i++) {arr[i]=new String(String.valueOf(DB_DATA[i%DB_DATA.length])).intern();}System.out.println(System.currentTimeMillis()-t+"ms");System.gc();}

在以上代码中,我们明确的知道,会有很多重复的相同的字符串产生,但是这些字符串的值都是只有在运行期才能确定的。所以,只能我们通过 intern显示的将其加入常量池,这样可以减少很多字符串的重复创建。

http://www.yayakq.cn/news/161413/

相关文章:

  • 电子商务网站主要面向做农村网站多少钱
  • thinkphp企业网站开发杭州网站建设优化推广
  • 生态旅游网站的建设网页设计高清素材
  • 长沙品牌网站制作服务报价企业安全文化建设的核心内容
  • 织梦 网站地图网站下载链接怎么做
  • 浅灰色做网站背景好的营销网站
  • 模板网站定制亚马逊雨林地图
  • 大连建设局网站地址手机论坛网站
  • 景安做网站教程连云港优化网站团队
  • 服务器做jsp网站教程视频有没有做面粉美食的网站
  • 仓山网站建设项目从立项到结束的流程图
  • 简洁大气的公司网站现在网站建设尺寸一般多少
  • 网站开发的教学视频网站怎么建立支付平台
  • 做网站运营经理的要求宁波荣胜网络科技有限公司
  • 安防网站建设自己做公众号和小说网站推广
  • 安康网站设计辽宁省住房和城乡建设部网站
  • 网站规划与网页设计总结网站支付端口
  • 做分析图超牛的地图网站建设工程合同印花税
  • 2023营业执照年检入口官网淮南网站seo
  • 营销推广网站推广方案住房城乡建设行业从业人员
  • 大连网站开发哪儿好薇有做网站需求的客户
  • 德州公司做网站做黑网站赚钱
  • 佛山网站推广免费简历模板下载word可编辑
  • 织梦网站如何做地区分站网站数据不变重新安装wordpress
  • 电商加盟网站建设yanderedev wordpress
  • 涟水网站建设中国500强企业
  • 企业网站功能介绍ps如何做网站轮播图
  • 网站建设项目心得体会户县住房和城乡建设局官方网站
  • 制作企业网站要花多少钱海口创建公司
  • 查企业营业执照的网站随州网站建设