1.String对象不属于8中基本数据类型,String是一个对象
String对象的默认初始值为null;String为一个特殊的对象,有一些其他对象没有的特点;
2.new String()与new String(" ")都是申请一个新的空字符串,是空字符串而不是null;
3.String str = ”a“ 与 String str = new String("a")的区别;
此处需明白常量池的意义(constant pool),常量池是指在编译器被确定的并被保存在编译完成的.class文件中。包括了类、方法、接口等中的常量,也包括字符串常量;
public class Test01 {
public static void main(String[] args){
String str1 = "abcd";
String str2 = "abcd";
String str3 = "ab"+"cd";
System.out.println(str1 == str2);
System.out.println(str1 == str3);
}
}
输出结果为:
true
true
程序中的str1与str2均为字符串常量,在编译过程中即被保存在.class文件中;str3是被两个字符串连接而成,并且他也是一个字符串常量,所以str3在编译期也会被解析为一个字符串常量,它也是常量池中"abcd”的一个引用;因此str1==str2==str3;
但是用new String()创建的字符串不是字符串常量不能被保存在常量池中,他们有自己的地址空间;
public class Test02 {
public static void main(String[] args){
String str1 = "abcd";
String str2 = new String("abcd");
String str3 = "ab"+new String("cd");
System.out.println(str1 == str2);
System.out.println(str1 == str3);
System.out.println(str2 == str3);
}
}
输出结果:
false
false
false
在程序Test02中str1还是一个字符串常量,但是str2与str3均不再是字符串常量;str1被保存在常量池中,str2与str3均在运行时创建了新的对象(具有新的地址空间,且str2与str3的地址是不同的)
4.String.intern()方法扩充常量池
当一个String实例调用intern()方法时会查找常量池中是否具有相同的Unicode字符串常量,如果有则返回其的引用;如果没有则在常量池中增加一个与其相同的Unicode字符串并返回其引用;
public class Test03 {
public static void main(String[] args){
String str1 = "abcd";
String str2 = new String("abcd");
String str3 = new String("abcd");
System.out.println(str1 == str2);
System.out.println("**************");
//str2虽然调用了intern()方法但是并未返回给其引用
str2.intern();
//str2调用了intern()方法并返回其引用
str3 = str3.intern();
System.out.println(str1 == str2);
System.out.println(str1 == str3);
}
}
输出结果:
false
**************
false
true
5.String实例是不可变的
String str3 = "ab"+"cd"
存在ab cd 以及abcd三个字符串常量;会造成内存的浪费所以对字符串一般采用StringBuffer
6.附加
public class Test {
public static void main(String[] args){
String str1 = "abcd";
String str2 = "cd";
//str2由于+号后存在str2的引用无法在编译期进行确定与str1地址是不同的
String str3 = "abcd"+str2;
System.out.println(str1 == str3);
}
}
输出结果:
false
邪恶的面试题
public class Test{
public static void main(String[] args){
String a = "a1";
String b = "a"+ 1;
System.out.println("------>"+a==b);
}
}
分享到:
相关推荐
【Java面试题】对String常量池的理解
Java String 源码和 String 常量池的全面解析 Java String 源码和 String 常量池是 Java 语言中非常重要的两个概念,它们之间存在着紧密的联系。在 Java 语言中,String 类是不可变的,finalize 方法被禁用,以确保...
在Java中,有两种创建字符串对象的方式:直接使用双引号声明出来的String对象会直接存储在常量池中。如果不是用双引号声明的String对象,可以使用String提供的intern方法。intern方法会从字符串常量池中查询当前字符...
`String`类还提供了`intern()`方法,它可以将一个`String`对象与常量池中的字符串进行比较。如果常量池中已经存在一个与当前对象内容相同的字符串,`intern()`会返回常量池中的那个字符串的引用。如果常量池中没有,...
Java String 字符串常量池解析 Java 中的字符串常量池是一种为了提高性能和减少内存开销的机制。它是 JVM 实例化字符串常量时进行的一些优化,主要是为了减少字符串对象的创建和存储。 字符串常量池的设计思想是...
在Java内存管理中,堆(Heap)、栈(Stack)、常量池(Constant Pool)和方法区(Method Area)是四个核心概念,它们在Java程序运行时扮演着不同的角色。 首先,方法区是用来存放类的信息、常量、静态变量等数据的...
### 字符串常量池与堆内存的区别 字符串常量池中的字符串是不可变的,而堆内存中的字符串对象可以被修改。例如,`String str3 = new String("hello"); str3 += "world";`,这里`str3`最初指向的是堆内存的一个字符...
### Java堆、栈和常量池详解 #### Java内存模型概览 在深入探讨Java中的堆、栈以及常量池之前,我们先来简要回顾一下Java内存模型的基本概念。Java程序运行时会使用到不同的内存区域来存储各种类型的数据,这些...
在Java中,内存主要分为四个区域:寄存器、栈、堆和方法区(包括常量池)。以下是这四个区域的详细说明: 1. **寄存器**: 这是计算机硬件的一部分,用于存储非常快速访问的数据。在Java中,寄存器主要由JVM直接管理...
### Java堆、栈和常量池——内存剖析 #### 寄存器 寄存器作为最快的存储区域之一,由编译器自动管理分配与回收,它位于CPU内,用于存储临时变量,例如局部变量和一些操作数。由于寄存器的数量有限且由编译器自动...
与Class常量池不同,运行时常量池是动态的,这意味着它可以随着程序执行过程中的需求变化而扩展。例如,在运行时通过反射机制调用类的方法时,可能会向运行时常量池中添加新的符号引用。 运行时常量池位于方法区,...
`new`指令用于在堆上创建一个新的`String`对象,`dup`指令复制栈顶的引用,`ldc`指令再次从常量池获取"haha"的引用,`invokespecial`调用`String`构造器来初始化新对象,最后`astore_1`将新对象的引用存储到变量`s`...
对于`String`类,它是Java中最常用的类之一,其字符串字面量(如"hello")在编译时就会放入常量池。在创建`String`对象时,如果使用字面量的方式(如`String s1="hello";`),那么相同的字面量将会引用常量池中的...
在Java编程语言中,字符串常量池(String Constant Pool)是一个重要的概念,它与程序的内存管理和性能优化密切相关。理解这个概念对于任何Java开发者来说都至关重要。字符串常量池是Java虚拟机(JVM)在运行时为...
常量池专门用来用来存放常量的内存区域,常量池分为:静态常量池和运行时常量池; 静态常量池:*.class文件中的常量池,class文件中的常量池不仅仅包含字符串,数值字面量,还包含类、方法的信息,占用class...
5. 字符串常量与new的String对象相加:这会混合使用堆和常量池,创建新的对象并可能修改常量池。例如: ```java String s9 = "mn" + new String("op"); String s10 = "mnop"; System.out.println(s9 == s10); //...
当我们使用`new String("Hello")`创建字符串时,即使字符串字面量已经存在于常量池中,也会创建一个新的String对象。这是因为`new`关键字总是创建一个新的对象实例。 #### 示例代码解析 考虑下面这段示例代码: `...
String int 字符串常量池 包装类型 函数参数 值传递引用传递 的 内存分配例子——源码 public static void fun_ref (Ref_test ref_out){ Ref_test ref_in=new Ref_test(); ref_in.s1="in"; //ref_out.s1=...
当`new`与字面量一起使用时,尽管字面量可能在常量池中,但`new`操作会创建一个新的String对象实例。例如: ```java String s1 = new String("11"); String s2 = "11"; System.out.println(s1 == s2); // 输出...
例如,在String类中,intern()方法可以将字符串常量池中的对象返回,而不是创建新的字符串对象。在Integer类中,valueOf方法可以从常量池中获取对象,而不是创建新的Integer对象。 Java常量池是Java虚拟机中一个...