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

企业网站做开放apiwordpress 用户信息

企业网站做开放api,wordpress 用户信息,营销广告语,wex5 wordpress面试回答 创建的对象数 应该是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/633196/

相关文章:

  • wordpress网站维护页面本地搭建网站网站后台
  • 长沙网站建设费用北京软件开发培训学校
  • 移动端网站建设的方案企业logo设计网站
  • 福州如何做百度的网站推广拉新任务的平台
  • 网站seo怎么优化个人建网站成本
  • 淮安做网站的有多少贵州灵溪seo整站优化
  • 做互联网的网站长沙网站关键词seo
  • 网站域名使用期花钱制作网站有什么好处
  • 做网站用的腾讯云服务器前端开发师
  • 济南历山北路网站建设卖护肤在哪个网站做宣传好
  • 网站运营管理龙岩58同城
  • 哈尔滨门户网站制作哪家好软件开发文档清单
  • 网站建设哪里好点永久免费自助建站系统
  • 网站建设 数据分析网站建设思路方法
  • 淘宝客网站建设儿童教育自适应网站模板
  • 加强网站微信信息编辑队伍建设专门做库存的网站
  • 沈阳建站模板展示网络营销技巧和营销方法
  • 网站开发的完整流程图wordpress3万篇文章优化
  • 云阳网站制作网站建设工作计划表
  • 深圳建设外贸网站wordpress文章提交
  • 上海高端网站制作哈尔滨响应式网站建设公司
  • 巩义郑州网站建设创意网名女
  • 网站快速收录平台青岛网站排名公司
  • 无锡公司网站建设电话高性价比网站建设
  • 门户网站建设的重要性服务器主机搭建网站
  • 上海网站设计找哪家陕西省建设监理协会证书查询网站
  • 张家港市规划建设网站wordpress优酷视频插件下载
  • 哪些网站是动态的网页设计公司有什么部门
  • 网站如何做监测链接三分钟做网站
  • 包头网站开发公司做棋牌游戏网站