对于这个问题想必已经被无数面试者问烂了...而绝大多数人都会人云亦云的回答创建了2个。我们首先不来纠结这个答案到底是对是错。上代码:
/** * * @author Sonicery_D */ public class HelloString { public static void main(String[] args){ String str = "ab"; String str1 = new String("abc"); String str2 = "abc"; System.out.println("str1==str2:"+(str1 == str2));//false } }
上面这段简单的代码按理来说应该是true才对,为什么会是false呢?
其实我们知道在JVM中有一个方法区的存在(Hotspot VM 用永久代来实现方法区),在方法区中就包括了一个常量池,当JVM遇到String str = “ab”;时它会首先在常量池中查找,看看是否有一个值为“ab”的对象,如果有就直接返回这个对象的引用;如果没有找到,就创建一个这个对象,然后把它放到常量池中,并返回它的引用。当然这个“ab”在编译期就放进了常量池,我们再待会儿会解释。
当JVM遇到String str1 = new String("abc");时,JVM会首先去常量池中查找是否存在值为“abc”的对象,如果找到不做任何处理,如果找不到就会先创建一个值为“abc”的对象然后把它放进常量池中,接着JVM又遇到了new,因此JVM又会在堆上创建一个存储“abc”的String对象,然后返回这个对象的引用。故而出现了上述代码中str1==str2 会是false的情况。
下面我们稍加看看它的字节码解释:
上面在main方法中的第一条指令是ldc,我们都知道ldc系列的命令是负责将数值常量或字符串常量值从常量池中推送到栈顶。由此可见String str = "ab";在编译期之后类加载时就将“ab”放入了常量池。
通new指令我们可以看到jvm在堆上创建了一个对象,并在随后又invokespecial了String的构造方法初始化对象。
对于回答会创建2个对象的,想必是:
String str = new String("abc");JVM首先在常量池中查找是否存在“abc”如果存在就啥也不做,如果不存在,就创建一个对象,并将它放入常量池,那么这就算了一个;当JVM遇到new时,又会在堆上创建一个String对象,并将其引用返回给str,这又是一个,加起来就是2个了。
但是如果是在String str3 = “abc”的前提下的String str = new String("abc"); 它还是会创建出两个对象吗?
相关推荐
然而,`str1` 使用了 `new String("abc")` 的形式创建,这意味着它是在堆内存中创建的新对象,而非字符串池中的对象。同理,`str2` 由于包含了一个 `new String("bc")` 的部分,同样是在堆内存中创建的新对象。因此...
这行代码创建了一个 String 对象,并将其引用赋值给 str 变量。 2. 使用引号包含的文本创建 String 对象 Java 代码:String str = "abc"; 这行代码创建了一个 String 对象,并将其引用赋值给 str 变量。 3. 使用...
第二种形式是先在栈中创建一个对 String 类的对象引用变量 str,然后查找栈中有没有存放"abc",如果没有,则将"abc"存放进栈,并令 str 指向"abc",如果已经有"abc",则直接令 str 指向"abc"。 那么,为什么 String...
因此,即使两个通过`new String()`创建的`String`对象具有相同的值,它们也会有不同的对象引用。 #### 三、String 比较 Java中有两种主要的方式来比较`String`对象: 1. **使用“==”运算符**:这种方法比较的是...
使用new关键字创建的字符串会在堆内存中创建一个新的对象,即使常量池中已有相同的字符串,也会生成新的实例。 3. **StringBuilder/StringBuffer**:`StringBuilder sb = new StringBuilder().append("Hello")....
- `str3`和`str4`分别通过`new String()`创建,它们在堆中,因此`str3==str4`为`false`,创建了三个对象。 - `i`和`j`都是基本类型`int`,它们在栈中直接存储,所以`i==j`为`true`,只创建了一个对象。 - `l1`和`k1`...
String str1 = new String("abc"); String str2 = "abc"; System.out.println(str1==str2);//false String str1 = new String("abc"); String str2 = new String("abc"); System.out.println(str1==str2);//false ...
String str = new String("abc"); ``` **1.2 字符串比较** - **使用`==`操作符**: - 当两个字符串通过字面量创建时,它们共享同一内存区域(字符串常量池),因此使用`==`比较时结果为`true`。 - 如果至少有...
即使 `str2` 使用了 `"abc"` 作为构造参数,但由于是通过 `new` 关键字创建的新对象,所以与 `str1` 不是指向同一个对象。 #### 四、总结 通过以上的分析可以得出以下结论: 1. **直接赋值方式**:这种创建方式...
string str = "AbC"; string lowerStr = str.ToLower(); // "abc" string upperStr = str.ToUpper(); // "ABC" ``` 2. `.Trim()` `.Trim()` 方法用于移除字符串两端的空白字符,如空格、制表符等。 ```csharp...
使用new创建String对象时,JVM不会去检查常量池中是否已有相同的字符串,而是直接在堆内存中创建一个新的String对象。这意味着即使两个使用new关键字创建的字符串内容完全相同,它们也是不同的对象,拥有不同的内存...
然而,如果使用`new`关键字创建`String`,则会在堆中创建新对象,即使值相同: ```java String s3 = new String("abc"); String s4 = new String("abc"); System.out.println(s3 == s4); // 输出false,因为s3和s4...
2. 使用 `new String()` 关键字创建 `String` 对象时,会在堆中创建一个新对象,并且如果是通过字符串常量初始化,还会在常量池中创建一个相同的字符串对象。 3. 当比较两个由 `new String()` 创建的对象时,即使...
利用影射,通过查询数据库里的方法名称,来调用方法 SqlConnection conn = new ... asac.abc c = new asac.abc(); TextBox1.Text = c.abcd(dr); conn.Close(); // str1 = str1.Substring(0, str1.Length - 1);
在C#编程中,字符串处理是常见的操作,尤其是在软件开发中。本文主要介绍了C#中常用的几种字符...在实际应用中,还需要注意字符串是不可变的,每次操作都会创建新的字符串对象,因此在处理大量字符串时要考虑性能影响。
2. 使用`new`关键字创建新对象:`String str = new String("abc");` 当使用"=="来比较字符串时,它实际上是在检查两个字符串是否指向内存中的同一个引用,而不是比较它们的内容。这意味着,如果两个字符串变量都...
string str = "abc"; char r = str[0]; // r的值是'a' ``` 可以使用foreach循环来遍历字符串中的每个字符。例如: ```csharp string str = "abc"; foreach (char item in str) { Console.WriteLine($"输出的字符:{...
string str1 = "abc"; string str2 = "abd"; if (str1 < str2) { cout << "str1 is less than str2" ; } ``` 3. **显式比较** - `int compare(const string &s) const:` 显式比较两个字符串,返回值为正表示...
但是,如果使用`new`创建String对象,如`String str1 = new String("abc"); String str2 = new String("abc");`,则它们在堆中是独立的对象,`str1 == str2`会返回`false`。 在编写Java代码时,理解堆和栈的区别...