两个对象的对比 a == b 如果a跟b指向同一个对象返回true,否则返回false
Object的equals方法:
public boolean equals(Object obj) { return (this == obj); }
可见是等同于“==”的对比。
但是String重写了equals方法
public boolean equals(Object anObject) { if (this == anObject) { return true; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { char v1[] = value; char v2[] = anotherString.value; int i = 0; while (n-- != 0) { if (v1[i] != v2[i]) return false; i++; } return true; } } return false; }
就是如果两个String对象内部维护的字符数组值是一样的也返回true
有代码
public class TestString { public static void main(String[] args) { String a = "abc"; String b = "ab"+"c"; String c = new String("abc"); System.out.println(a==b); //true System.out.println(a==c); //false System.out.println(a.equals(c)); //true } }
编译后得到
public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=3, locals=4, args_size=1 0: ldc #2 // String abc 2: astore_1 3: ldc #2 // String abc 5: astore_2 6: new #3 // class java/lang/String 9: dup 10: ldc #2 // String abc 12: invokespecial #4 // Method java/lang/String."<init> ":(Ljava/lang/String;)V 15: astore_3 16: getstatic #5 // Field java/lang/System.out:Ljav a/io/PrintStream; 19: aload_1 20: aload_2 21: if_acmpne 28 24: iconst_1 25: goto 29 28: iconst_0 29: invokevirtual #6 // Method java/io/PrintStream.prin tln:(Z)V 32: getstatic #5 // Field java/lang/System.out:Ljav a/io/PrintStream; 35: aload_1 36: aload_3 37: if_acmpne 44 40: iconst_1 41: goto 45 44: iconst_0 45: invokevirtual #6 // Method java/io/PrintStream.prin tln:(Z)V 48: getstatic #5 // Field java/lang/System.out:Ljav a/io/PrintStream; 51: aload_1 52: aload_3 53: invokevirtual #7 // Method java/lang/String.equals: (Ljava/lang/Object;)Z 56: invokevirtual #6 // Method java/io/PrintStream.prin tln:(Z)V 59: return LineNumberTable:
ldc:将int、float或String型常量值从常量池中推送至栈顶,String是不可变对象也就是说它的值是不能变的,String a = "a"; a = "b";是指向新对象而不是将“a”改成“b”
下面解释下代码中三个比较的结果
第一:String a = "abc"跟String b = “ab”+“c”分别是将常量池中的“abc”的引用地址存入第二和第三变量,a跟b指向常量池中同一个对象所以返回true
第二:String c = new String(“abc”)是在堆中生成一个值为“abc”的对象,再把引用地址存入第四变量,由于a跟c指向的不是同一个变量所以返回false
第三:a跟c指向不同变量,但是内部值相等所以返回true
相关推荐
String 类型是不可变的对象,每次对 String 对象进行改变时都会生成一个新的 String 对象,然后将指针指向新的 String 对象。这意味着,如果经常改变字符串内容,最好不要使用 String 类型,因为每次生成对象都会对...
这意味着当你对String对象进行任何修改(如拼接、替换字符等)时,都会创建一个新的String对象,而不是在原对象基础上进行修改。 - **内存效率**:由于不可变性,String对象常驻在常量池中,这使得它们在常量表达式...
每次对`String`对象进行操作(如拼接、替换字符等),都会创建一个新的`String`对象。这种特性使得`String`在多线程环境下更安全,因为不用担心其内容被意外修改。 2. **可变性**: 相反,`StringBuffer`(或`...
1. **创建String对象**: - 字面量方式:`String str = "Hello, World!";` - 构造器方式:`String str = new String("Hello, World!");` 2. **String的常量池**: - 当使用字面量创建字符串时,Java会检查常量池...
在Java编程语言中,String类是一个非常基础且重要的部分,它是不可变的,也就是说一旦创建了一个String对象,就不能更改它的内容。然而,许多初学者在学习过程中可能会尝试自己创建一个类似的字符串类,以便更好地...
- **String**:在进行字符串拼接时会产生多个 String 对象,如果频繁进行这样的操作,将会消耗大量的内存资源。 #### 四、使用场景分析 1. **单线程环境**:在这种情况下,推荐使用 **StringBuilder**,因为它不...
// 实际上创建了新的String对象 ``` 在这个例子中,虽然看起来我们是在原有字符串的基础上添加了"World",但实际上,Java创建了一个新的`String`对象,并将`str`指向这个新对象。这种行为在字符串频繁修改时可能...
测试代码通常会通过计时来对比`String`和`StringBuilder`在相同操作下的执行时间。例如,可以创建一个包含大量字符串连接的操作,然后分别用`String`的`+`操作和`StringBuilder`的`append`方法执行,最后记录并比较...
这意味着如果尝试改变一个 `String` 对象的值,将会创建一个新的 `String` 对象。 ```java String str = "hello"; str += " world"; // 实际上是创建了一个新的 String 对象 ``` 2. **性能**:由于 `String` ...
每次对`String`对象进行修改(如连接、替换字符等),都会生成一个新的`String`对象。这是因为`String`对象存在于常量池中,修改操作实际上是在常量池中创建新的引用,而不是修改原有的对象。 - `StringBuffer`(或...
在Java编程中,比较对象属性的数据变化是一项常见的需求,特别是在数据跟踪、日志记录或版本控制等场景。本文将深入探讨如何实现这个功能,并基于给定的文件`PriceCheckDetail.java`和`ObjectCompareUtil.java`来...
`String`对象是不可变的(immutable),这意味着一旦一个`String`对象创建后,其内容不能被修改。这带来了几个关键的优势: 1. **线程安全**:由于`String`对象不可变,多个线程可以安全地共享同一个`String`对象,...
静态空间与对象空间的对比 class TalkPlace { static String talkArea=""; //类变量 } public class User { static int count=0; //类变量 String username; int age; //实例变量 public User(String name,...
**JSP 内置对象** JavaServer Pages (JSP) 提供了九个内置对象,这些对象在 JSP 页面执行时自动创建并可用,无需显式声明。它们为开发人员提供了方便,使得与用户交互、处理请求数据以及管理页面生命周期变得简单。...
- 创建一个 `std::stringstream` 对象 `stringBuffer`。 - 使用 `操作符将整型变量 `numberValue` 插入到 `stringBuffer` 中。 - 将 `stringBuffer` 中的内容转换为 `std::string` 类型,并与另一个字符串 `"-"` ...
在C++中,可以通过以下方式声明和初始化一个`std::string`对象: ```cpp #include <string> std::string myString = "Hello, world!"; ``` 或者使用不同的构造函数: - **空字符串**:`std::string s;` - **复制...
String类使用(创建字符串对象、比较、长度、连接、截取、查找和替换、切割和拆分、和其他类型的转换、格式化、判断、手动入池、其他操作) StringBuffer类 StringBuilder类 String、StringBuffer和StringBuilder的...
public static string resultSerialnumber(string[] IOserialnumber, string[] OutSerialnumber, string type) { string serialNumberEdit = ""; IEnumerable<string> cs = null; switch (type) { case "1": ...
然而,对于初学者来说,理解`std::string`的内部工作原理以及如何自定义一个类似的`string`类可以加深对C++对象模型和内存管理的理解。以下是一个基于C++实现的`string`类的详细知识讲解。 1. **构造函数**: - **...
这意味着每当对`String`对象进行修改(如拼接、替换等操作)时,都会在内存中创建一个新的字符串对象,这不仅涉及到额外的内存分配,也可能导致性能下降。例如,以下代码演示了`String`拼接的低效: ```csharp ...