Java面试官:堆栈、堆栈、字符串常量池。 您的位置:知道> >思维字符串存储在哪里?-必威体育下载_betway官网_betway官网手机版

关于有些开发多年的程序员来说,他们码字的速度非常快,结构了解建立的也非常好。可是假如问一些比较细的java问题的话你确认他们能答复得出来吗乡村致富?

java的字符串存储在哪?

关于堆、栈和字符串常量池以及他们之间的联系,我是这样了解的。

首要介绍一下堆、栈、常量池中寄存的数据类型吧。

JAVA的JVM的内存可分为3个区:堆(heap)、栈(stack)和办法区(method)

  • 堆:寄存一切new出来的目标,存储的全部是目标,每个目标都包括一个与之对应的class的信息。(class的意图是得到操作指令)
  • 栈:寄存根本数据变量和目标的引证,目标(new出来的目标)自身不存在在栈中,而是寄存在堆中或许常量池中(字符串目标寄存在常量池中);
  • 常量池:寄存根本类型常量和字符串常量。
  • 每个线程包括一个栈区,栈中只保存根底数据类型的目标和自界说目标的引证(不是目标),目标都寄存在堆区中 。栈中的数据巨细和生命周期是能够确认的,当没有引证指向数据时,数据就会主动消失。堆中的目标由废物收回器担任收回,因而巨细和生命周期不需求数九确认,具有很大的灵活性。

每个栈中的数据(原始类型和目标引证)都是 私有的,其他栈不能拜访。

  • 24.3.栈分为3个部分:根本类型变量区、履行环境上下文、操作指令区(寄存操作指令)。

办法区:

又名静态区,跟堆清明假日相同,被一切的线程同享。办法区包括一切的class和static变量。

办法区中包括的都是在整个程序中永久仅有的元素,如class,static变量。

关于字符串来说(String是类):其目标的引证都是存储在栈中的,假如是编译期现已创立好(用双引号界说的)就存储在常量池中,假如是运行期(new出来的)才干确认的就存储在堆中。关于equals持平的字符串,在常量池中只要一份,而在堆中有多份。Equals办法看的两个目标在常量池里边的值是否持平,“= =”办法看的是目标的引证是否持平,比方s1,s2,s3都指向常量池的“china”,那么“= =”办法回来true,ss1,ss2,ss3指向堆中不同的new目标,所以==办法回来false。关于equals持平的字符串,在常量池中永久只要常量池中永久只要一份,在堆中有多份。

java中特别的String类型


Java中String是一个特别的包装类数据有两种创立办法:

String s = "abc";

String s = new String("abc");

1.第一种先在栈中创立一个对String类的目标引证变量s,然后去查找"abc"是否被保存在字符串常量池中,假如没有则在栈中创立三个char型的值'a'、'b'、'c',然后在堆中创立一个String目标object,它的值是刚才在栈中创立的三个char型值组成的数组{'a'、'b'、'c'},接着这个String目标object被寄存进字符串常量池,终究将s指向这个目标的地址,假如"abc"现已被保存在字符串常量池中,则在字符串常量池中找到值为"abc"的目标object,然后将s指向这个目标的地址。

第一种特色:JVM会主动依据栈中数据的实际情况来决议是否有必要创立新目标。

2.第二种能够分解成两步1、String object = "abc";2、String s = new String(object);第一步参阅第一种创立办法,而第二步因为"abc"现已被创立并保存到字符串常量池中,因而jvm只会在堆中新创立一个String目标,它的值同享栈中已有的三个ch主highlightar型值。

第二种特色:一概在堆中创立新目标,而不论其字符串值是否持平,是否有必要创立新目标。

举个比如:

String s1 = "china";

String s2 = "china";

String s3 = "china";

String ss1 = new String("china");

String ss2 = new String("china");

String ss3 = new String("china");

解释一下堆指向常量池这3个箭头,关于经过new发生一个字符串(假设为”china”)时,先去常量池中查找是否现已有了”china”目标,假如没有则在常量池中创立一个此字符串目标,然后堆中再创立一个常量池中此“china”目标的复制目标。这也便是有道面试题:String s = new String(“xyz”);发生几个目标?一个或两个,假如常量池中本来没有”xyz”,便是两个。指针是ss1先指向堆里边new的引证变量,堆里边new的引证变量再指向常量池里边的“china”

1)关于根本数据类型的变量和常量:变量和引证存储在栈中,常量存储在常量池中。

int i1 = 9;

int i2 = 9;

int i3 = 9;

public static final int INT1 = 9;

pJava面试官:仓库、仓库、字符串常量池。 您的方位:知道> >思想字符串存储在哪里?-必威体育下载_betway官网_betway官网手机版 ublic static final int INT2 = 9;

public static final int INT3 = 9;

栈里只要一个9 ,i1,i2,i3 都指向9 。

假如i2=7会在栈里生成7 ,再令i2指向7。

别的,局部变量(办法参数)的数据存储在栈中,而且它随办法的消失而消失

2)关于成员变量和局部变量:局部变量有必要初始化。办法参数是局部变量,局部变量的数据存在于栈内存中。栈内存中的局部变量跟着办法的消失而消失。成员变量存储在堆中的目标里边,由废物收回器担任收回。

==,equals和hashCode()差异

= =: 比较的是内存中的地址。关于根本类型:相当于比较的便是值是否相同;关于引证类型:比较的便是地址值是否相同

Equals:用来判别两个目标的值是否持平。假如一个类没有界说自己的equals()办法,那么它默许的equals()办法便是从Object类承继的相当于==运算符,即比较两个变量指向的目标内存是否持平。假如一个类希望能比较两个实例目标的值是否持平,那么就能够掩盖Object类的equals()办法。例如String类的equals()办法便是用于比较两个独立目标的内容是否持平(即堆中的内容是否持平)。

hashCode():Obejct类的 hashCode() 的作用是获取哈希码,也称为散列码;它实际上是回来一个int整数,其实便是目标的内存地址值十进制表明。这个哈希码的作用是确认该目标在哈希表中的索引方位。在Java中任何一个目标都具有equals(Object obj)和hashCode()这两个办法,因为他们是在Object类中界说的。假如重写了一个目标的equals办法,那么它的hashcode办法也重写。

equal和==的代码运用

例1.字符串常量池的运用String s0 = "abc";String s1 = "abc";System.out.println(s0==s1); //true 能够看出s0和s1是指向同一个目标的。

例2.String中= =和equals的差异

String s0 =new String Java面试官:仓库、仓库、字符串常量池。 您的方位:知道> >思想字符串存储在哪里?-必威体育下载_betway官网_betway官网手机版 ("abc");

String s1 =new String ("abc");

System.out.println(s0==s1); //false 能够看出用ne烧麦w的Java面试官:仓库、仓库、字符串常量池。 您的方位:知道> >思想字符串存储在哪里?-必威体育下载_betway官网_betway官网手机版 办法是生成不同的目标

System.out.println(s0.equals(s1)); //true 能够看出equals比较的是两个String目标的内容(值)

例3.编译期确认

String s0="helloworld";

String s1="helloworld";

String s2="hello" + "word";

System.out.println( s0= =s1 ); //true 能够看出s0跟s1是同一个目标

System.out.println( s0= =s2 ); //true 能够看出s0跟s2是同一个目标

剖析:因为比如中的 s0和s1中的"helloworld”都是字符串常量,它们在编译深圳科略教育集团期就被确认了,所以s0= =s1为true;而"hello”和"world”也都是字符串常量,当一个字符串由多个字符串常量衔接而成时,它自己必定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所公主恋人以s2也是常量池中"helloworld”的一个引证。所以咱们得出s0=Java面试官:仓库、仓库、字符串常量池。 您的方位:知道> >思想字符串存储在哪里?-必威体育下载_betway官网_betway官网手机版 =s1==s2;

例4.编译期无法确认

String s0="helloworld";

String s1=new String("helloworld");

String s2="hello" + new String("world");

System.out.println( s0==s1 ); //false

System.out.println( s0==s2 ); //false

System.out.println( s1==s2 ); //false

剖析:用new String() 创立的字符串不是常量,不能在编译期就确认,所以new String() 创立的字符串不放入常量池中步卒,它们有自己的地址空间。

s0仍是常量池中"helloworld”的引证,s1因为无法在编译期确认,所以是运行时创立的新目标"helloworld”的引证,s2因为有后半部分new String(”world”)所以也无法在编译期确认,所以也是一个新创立目标"helloworld”的引证;

例5.编译期优化

String s0 = "a1人民币对日元汇率";

String s1 = "a" + 1;

System.out.println((s0 == s1)); //result = true

String s2 = "atrue";

String s3= "a" + "true";

System.out.println((s2 == s3)); //result = true

String s4 = "a3.4";

String s5 = "a" + 3.4;

System.out.println((a == b)); //result = true

剖析:在程序编译期,JVM就将常量字符串的"+“衔接优化为衔接后的值,拿"a” + 1来说,经编译器优化后在class中就现已是雅安a1。在编译期其字符串常量的值就确认下来,故上面程序终究的成果都为true。

例6.编译期无法确认

String s0 = "ab";

String s1 = "b";

String s2 = "a" + s1;

System.out.println((s0 == s2)); //result = false

剖析:JVM关于字符串引证,因为在字符串的"+“衔接中,有字符串引证存在,而引证的值在程序编译期是无法确认的,即"a” + s1无法被编译器优化,只要在程序运行期来动态分配并将衔接后的新地址赋给s2。所以上面程序的成果也就为false。

例7.编译期费雯・丽确认

String s0 = "ab";

final String s1 = "b";

String s2 = "a" + s1;

System.out.println((s0 == s2)); //result = true

剖析:和[6]中仅有不同的是s1字符串加了final润饰,关于final润饰的变量,它在编译时被解析为常量值的一个本地复制存储到自己的常量 池中或嵌入到它的字节码流中。所以此刻的"a" + s1和"a" + "b"作用是相同的。故上面程序的成果为true。

例8.编译期无法确认

String s0 = "ab";

final String s1 = getS1();

String s2 = "a" + s1;

System.out.println((s0 == s2)); //result = false

private static String getS1() { return "b"; }

剖析:JVM关于字符串引证s1,它的值在编译期无法确认,只要在程序运行期调用办法后,将办法的回来值和"a"来动态衔接并分配地址为s2,故上面 程序的成果为false。

关于String的不行变规划

String是不行改动类(记:根本类型的包装类都是不行改动的)的典型代表,也是Immutable规划形式的典Java面试官:仓库、仓库、字符串常量池。 您的方位:知道> >思想字符串存储在哪里?-必威体育下载_betway官网_betway官网手机版 型运用,String变量一旦初始化后就不能更改,制止改动目标的状况,然后添加同享目标的巩固性、削减目标拜访的过错,一起还避免了在多线程同享时进行同步的需求。

Immutable形式的完成主要有以下两个关键:

1.除了结构函数之外,不该该有其它任何函数(至少是任何public函数)修正任何成员变量。

2.任何使成员变量取得新值的函数都应该将新的值保存在新的目标中,而坚持本来的目标不被修正。

String的不行变性导致字符串变量运用+号的价值:

例9:

String s = "a" + "b" + "c";

String s1 = "a";

String s2 = "b";

String s3 = "c";

String s4 = s1 + s2 + s3;

剖析:变量s的创立等价于 String s = “abc”; 由上面比如可知编译器进行了优化,这儿只创立了一个目标。由上面的比如也能够知道s4不能在编译期进行优化,其目标创立相当于:

StringBuffer temp = new StringBuffer();

temp.append(s1).append(s2).append(s3);

String s = temp.toString();

由上面的剖析成果,可就不难推断出String 选用衔接运算符(+)功率低下原因剖析,形如这样的代码:

每做一次西门烤翅 + 就发生个StringBuffer目标,然后append后就丢掉。下次循环再抵达时从头发生个StringBuffer目标,然后append 字符串,如此循环直至完毕。假如咱们直接选用StringBuffer目标进行append的话,咱们能够节约N - 1次创立和毁掉目标的时刻。所以关于在循环中要进行字符串衔接的运用,一般都是用StringBuffer或StringBuliderJava面试官:仓库、仓库、字符串常量池。 您的方位:知道> >思想字符串存储在哪里?-必威体育下载_betway官网_betway官网手机版 目标来进行append操作。

你们公司运用OpenJDK仍是Oracle JDK

你们公司运用OpenJDK仍是Oracle JDK (单选)
性感女神 众里寻他千百度 忽然之间
0
0%
i黑大
OpenJDK
武昌
0
0%
Oracle JDK
一个米一个参

对JAVA编程言语自身来讲,OpenJDK与OracleJDK的区分或许是一件功德。商业化能让JAVA走的更高更远,一起也不失掉开源精力,各位看官怎样看待OpenJDK与Oracle JDK的不同呢?欢迎沟通!

码字不易!喜爱请重视Java面试官:仓库、仓库、字符串常量池。 您的方位:知道> >思想字符串存储在哪里?-必威体育下载_betway官网_betway官网手机版 !

终究你知道OpenJDK与OracleJDK的差异吗?

评论(0)