Java:文字字符串 [英] Java:literal strings

查看:125
本文介绍了Java:文字字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  A类{

String s4 =abc;

static public void main(String [] args){

String s1 =abc;
String s2 =abc;
String s3 = new String(abc);
A o = new A();
String s5 = new String(def);

System.out.println(s1 == s2:+(s1 == s2));
System.out.println(s1 == s1.intern:+(s1 == s1.intern()));
System.out.println(s1 == s3:+(s1 == s3));
System.out.println(s1.intern == s3.intern:+(s1.intern()== s3.intern()));
System.out.println(s1 == s4:+(s1 == o.s4));
}
}

输出:

  s1 == s2:true 
s1 == s1.intern:true
s1 == s3:false
s1。 intern == s3.intern:true
s1 == s4:true

我的问题:



1. > String s1 =abc会发生什么?我想String对象被添加到class in class作为实习字符串?它放在哪里?永久生成或只是堆(作为String Class实例的数据成员)?



2. > String s2 =abc会发生什么?我想没有任何对象被创建。但这是否意味着Java Intepreter需要搜索所有被拦截的字符串?这会导致任何性能问题吗?



3.Seems String s3 = new String(abc)不使用interned string。为什么?



4.Will String s5 = new String(def) create new new实习字符串?

解决方案


1.String s1 =abc会发生什么?


在编译时,文字的表示形式被写入包含此代码的类的类文件的常量池部分。 / p>

当加载类时,将读取类文件常量池中字符串文字的表示形式,并从中创建一个新的String对象。然后,该字符串被实现,然后对代码字符串的引用嵌入在代码中。



在运行时,对先前创建的/实例化字符串的引用被分配给 s1 。(当此语句为exe时,不会创建字符串或实习cuted。)


我想String对象是作为实习字符串添加到类String中的池中的吗?


是的。但不是代码执行时。


它放在哪里? 永久代或只是堆(作为String Class实例的数据成员)?


它存储在permgen中堆的区域。 (String类没有静态字段.JVM的字符串池是用本机代码实现的。)


2.String s2会发生什么=abc?


在加载时没有任何事情发生。当编译器创建了类文件时,它重用了相同的常量池条目用于第一次使用文字的文字。因此,此语句使用的字符串引用与前一语句使用的字符串引用相同。


我想没有创建任何对象。


正确。



< blockquote>

但这是否意味着Java Intepreter需要搜索所有被拦截的字符串?这会导致任何性能问题吗?


否和否.Java解释器(或JIT编译代码)使用与前一语句创建/嵌入相同的引用。


3.Seems String s3 = new String(abc)不使用interned string。为什么?


它比这更复杂。构造函数调用使用实习字符串,然后创建一个新的String,并将实习字符串的字符复制到新String的表示形式。新创建的字符串分配给 s3



为什么?因为 new 指定的,因为总是创建一个新对象(请参阅JLS),以及 String 构造函数指定复制字符。


4.Will String s5 = new String(def )创建任何新的实习字符串?


在加载时创建一个新的实习字符串(对于def),然后是新的String对象在运行时创建,它是实习字符串的副本。 (有关详细信息,请参阅之前的文字。)


class A { 

String s4 = "abc";

 static public void main(String[]args ) {

        String s1 = "abc";
        String s2 = "abc";
        String s3 = new String("abc");
        A o = new A();
        String s5 = new String("def");

        System.out.println("s1==s2 : " + (s1==s2));
        System.out.println("s1==s1.intern : " + (s1==s1.intern()));
        System.out.println("s1==s3 : " + (s1==s3));
        System.out.println("s1.intern==s3.intern : " + (s1.intern()==s3.intern()));
        System.out.println("s1==s4 : " + (s1==o.s4));
 }
} 

The output:

s1==s2 : true
s1==s1.intern : true
s1==s3 : false
s1.intern==s3.intern : true
s1==s4 : true

My questions:

1.What happens for "String s1 = "abc"? I guess the String object is added to the pool in class String as an interned string? Where is it placed on? The "permanent generation" or just the heap(as the data member of the String Class instance)?

2.What happens for "String s2 = "abc"? I guess no any object is created.But does this mean that the Java Intepreter needs to search all the interned strings? will this cause any performance issue?

3.Seems String s3 = new String("abc") does not use interned string.Why?

4.Will String s5 = new String("def") create any new interned string?

解决方案

1.What happens for "String s1 = "abc"?

At compile time a representation of the literal is written to the "constant pool" part of the classfile for the class that contains this code.

When the class is loaded, the representation of the string literal in the classfile's constant pool is read, and a new String object is created from it. This string is then interned, and the reference to the interned string is then "embedded" in the code.

At runtime, the reference to the previously created / interned String is assigned to s1. (No string creation or interning happens when this statement is executed.)

I guess the String object is added to the pool in class String as an interned string?

Yes. But not when the code is executed.

Where is it placed on? The "permanent generation" or just the heap(as the data member of the String Class instance)?

It is stored in the permgen region of the heap. (The String class has no static fields. The JVM's string pool is implemented in native code.)

2.What happens for "String s2 = "abc"?

Nothing happens at load time. When the compiler created the classfile, it reused the same constant pool entry for the literal that was used for the first use of the literal. So the String reference uses by this statement is the same one as is used by the previous statement.

I guess no any object is created.

Correct.

But does this mean that the Java Intepreter needs to search all the interned strings? will this cause any performance issue?

No, and No. The Java interpretter (or JIT compiled code) uses the same reference as was created / embedded for the previous statement.

3.Seems String s3 = new String("abc") does not use interned string.Why?

It is more complicated than that. The constructor call uses the interned string, and then creates a new String, and copies the characters of the interned string to the new String's representation. The newly created string is assigned to s3.

Why? Because new is specified as always creating a new object (see JLS), and the String constructor is specified as copying the characters.

4.Will String s5 = new String("def") create any new interned string?

A new interned string is created at load time (for "def"), and then a new String object is created at runtime which is a copy of the interned string. (See previous text for more details.)

这篇关于Java:文字字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆