首页 > 其他分享 >Strng创建对象

Strng创建对象

时间:2023-05-13 20:35:14浏览次数:65  
标签:String 对象 创建对象 池中 Strng 内存 new 常量

下面说的常量池都是指字符串常量池,字符串常量池存在运行时常量池之中(在JDK7之前存在运行时常量池之中,在JDK7已经将其转移到堆中),运行时常量池从永久代移到了元空间中。

String a = new String("ab");

此时创建了两个对象,常量池中创建了ab对象,堆内存中也创建了ab对象,此时引用指向堆内存中的对象。

String a = "ab";

此时先去常量池中寻找有没有ab这个值,如果有就直接将引用指向它,如果没有,则在常量池中创建这个ab对象,引用指向它。

intern()方法调用,如果字符串常量池中已经存在一个等于String对象的字符串,就直接返回这个字符串对象的引用。如果字符串常量池中不存在该对象,则将此对象放到常量池中,返回新建字符串对象的引用。

String c = new String("b") + new String("a");

会创建六个对象

1.new StringBuilder对象用来做拼接

2.堆内存中创建new String("b")

3.常量池中创建b对象

4.堆内存创建new String("a")

5.常量池中创建a对象

6.最终需要调用StringBuilder中的toString()方法,而toString方法底层调用的是new String来实现的因此又创建了一个对象ab,但是注意点是这里调用toString()方法只会在堆内存创建对象,不会在常量池中创建对象

intern的难点案例;

String s = new String(1);
s.intern();
String s2 = "1";
System.out.println(s==s2);

1.6至1.8都会返回false

此处和下面的对应起来作比较,这里的intern没有将常量池中引用指向堆内存的new是因为在调用intern方法之前,常量池中已经有对象了,下面调用的是toString(),这里直接new的

分析:第一步在堆内存和常量池中都会创建一个1的对象,此时s指向堆内存1。第二步调用Intern方法,但是此时常量池中已经存在1这个对象,而且并没有让s指向这个intern,所以此时s还是指向的堆内存中的1。第三步,以为常量池中已经存在1这个对象,因此直接将说引用指向这常量池中地对象。第四步判断为false,一个指的堆内存,一个指的常量池中的对象。

String c = new String("b") + new String("a");
c.intern();
String d = "ab";
System.out.println(c==d);

1.6版本返回false,1.7和1.8返回的是true

和刚刚的区别就是第一步用了拼接最后调用的toString(),常量池中没有创建对象,通过第二步的intern方法才在常量池中创建了ab对象。1.6返回false的理论同上,因为一个指向的堆内存,一个指向的常量池。

1.7和1.8相对于1.6区别在于,字符串常量池移到了堆内存中,为了节省常量池的空间,在调用intern()方法时,如果堆内存中此时1通过new创建了ab对象,那么就直接引用指向这个new出来的对象,也就是说此时常量池中保存的是new出来的那个对象的地址,并没有创建一个新的对象。

标签:String,对象,创建对象,池中,Strng,内存,new,常量
From: https://www.cnblogs.com/liu-jin/p/17398127.html

相关文章

  • 4.Spring中IOC创建对象的两种方式和创建时机
    https://blog.csdn.net/jike11231/article/details/116357864 创建时机1:默认的在Spring容器启动的时候2:在getBean的时候创建对象(就是拿到配置文件中的标识符的时候创建对象)在Spring的配置文件bean中有一个属性lazy-init=“default/true/false”(1)如果lazy-init为"default/f......
  • C++创建对象时,有哪些内容?
    数据成员在类的作用域中,数据成员类似全局变量,而成员函数是操作数据成员的函数成员函数内联函数介绍目的:为了提高运行时的效率注意:在内联函数体中不要有复杂结构(如循环语句和switch语句)在类中声明内敛函数的方式:将函数体放在类的声明中使用inline关键词举例classPoin......
  • java创建对象的几种方法
    Java一共有5种方法可以来创建对象例如对象User;使用new的方式来创建对象,newUser(),这种方法使用了构造器2.使用class的newInstance()例如:Useruser=User.class.newInstance();这种方法也使用了构造器3.使用Constructor类的newInstance()方法创建对象,例如:Useruser=......
  • kubectl apply -f --record 是否将当前创建对象创建命令保存到Annotation注解中中。
    kubectlcreate-ftomcat-app1.yaml--save-config--recordkubectlapply-ftomcat-app1.yaml--record#推荐命令 --record  #是否将当前对象创建命令保存至Annotation中,布尔型数据(true或false) --save-config  #是否将当前对象配置信息保存至......
  • 面向对象编程 -- 创建对象3
    面向对象编程 --创建对象3一、对象迭代//ECMAScript2017新增了两个静态方法,用于将对象内容转换为序列化的--更重要的是可迭代--格式//这两个静态方法Object.values()和Object.entries()接收一个对象,返回它们内容的数组。consto={ foo:'bar', baz:1, qux......
  • 面向对象编程 -- 创建对象1
    面向对象编程 --创建对象1//虽然使用Object构造函数或对象字面量可以方便地创建对象,但这些方式也有明显不足:创建具有同样接口的多个对象需要编写很多代码。一、概述//纵观ECMAScript规范的历次发布,每个版本的特性似乎都出人意料。//ECMAScript6开始正式支持类和继......
  • IOC创建对象的方式
    使用无参构造创建对象,默认!有参会在beans.xml中报错假设我们使用有参构造创建对象下标赋值<beanid="user"class="com.gy.pojo.User"><constructor-argindex="0"value="alice"/></bean>通过参数类型string创建,不建议使用直接通过参数名创建<beanid......
  • 动态创建对象执行方法
    packageedu.wtbu;importjava.lang.reflect.Constructor;importjava.lang.reflect.Field;importjava.lang.reflect.InvocationTargetException;importjava.lang.refle......
  • 创建对象的底层分析
    Java是一门面向对象的编程语言,Java程序运行过程中无时无刻都有对象被创建出来。在语言层面上,创建对象通常(例外:复制、反序列化)仅仅是一个new关键字而已,而在虚拟机中,对象(文中......
  • c++ 创建对象
    1.定义类一般写在.h文件中#include<string>#include<iostream>usingnamespacestd;voidprint(charcontent[]);voidTestString1();voidTestString2();voidTe......