java中string 类型的对象间比较的学习笔记

简介: 在JAVA 中String 有两种不同的赋值方式 ,"="和new一个新的对象,虽然在输出时显示的内容是一样的,但数据存储的原理是不同的. String a="ab"; String b="ab"; System.out.println(a==b);//true 三句话的执行时这样的:        当把"ab"赋值给a变量时,因为是用"="直接赋值,此时"ab"作为字面量存在栈

在JAVA 中String 有两种不同的赋值方式 ,"="和new一个新的对象,虽然在输出时显示的内容是一样的,但数据存储的原理是不同的.

String a="ab";

String b="ab";

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

三句话的执行时这样的:

       当把"ab"赋值给a变量时,因为是用"="直接赋值,此时"ab"作为字面量存在栈中,然后a的引用指向字面量"ab",在编程语言中,字面量是一种表示值的记法.

       给  b 赋值ab时,系统会自动查找字面量中是否已经存在 ab,当检测到存在ab时,就会将b的引用指向 ab , 也就是说现在a和b 指向相同的字面量 ,那这时候a = = b作比较时,就会很容易的知道结果为 true;

       String a=new String("abc");

       String b=new String("abc");

       System.out.println(a==b);//false

       System.out.println(a);//abc

       System.out.println(b);//abc

再看这种赋值方式, a 和 b 都是通过new 出新的对象的方式赋值,对象的产生是动态的,当一个对象产生时,系统会在堆中为每个对象分配不同的内存空间来存放数据,也就是说这里的a 和 b 在堆内存中的地址是不同的.

       而 a 和 b都是String类的实例对象,当两个对象通过双等号(“a = = b”)比较时,比较的是两个对象在内存中的地址,如果两个对象内存地址是相同的,得到的结果为true,很显然在上面的例子中,a 和 b的地址是不同的,所以返回结果为 false;

       如果要比较a和b 值得大小,需要使用a.equals(b);

       在后两句输出语句中,根据常识认为直接输出对象实例名,得到的结果是该实例的内存地址,但是在对字符串输出时,却是输出的内容;其实在其他的普通类中,当打印实例名时,

MyString mString=new MyString();

System.out.println(mString);

打印输出时,系统会自动调用对象的toString()方法,输出的地址:  com.neoft.hello.MyString@18a992f;

这是在java源码中就已经写好的,而源码中 String 类的toString()方法中的返回值指定的就是字符串内容.这是String类与其他类的区别.

       String  a="ab";

       String  c=new String("ab");

       System.out.println(a==c);//false

这三行代码中 a 是指向的字面量,也就是在栈中的值,而c指向的是堆中分配的实例对象空间,因此当 a和c的地址比较时,当然因为地址不同返回false值.

       Stringa="ab";

       Stringc=new String("ab");

       a=c;

       System.out.println(a==c);//true

在这四行代码中,因为有 a = c;存在, a不再指向字面量,而是和c一样,将引用指向c的实例在堆中的地址.此时,返回值为true;

       String  a=new String("ab");

       String  c=a;

       a="ab";

       System.out.println(a==c);//false

这四句代码一出,想必能难倒一些刚刚入门的java爱好者.首先前两句, a和b在堆内存中会指向相同的内存地址,此时a 和c的值都是 ab ; 但是 在第三句话或许有许多人不理解,在 a=”ab”;这句话中,对象a 的引用已经指向了栈中的ab 字面量,此时c的值是 堆中的”ab”, a的值是字面量ab ,所以在 a==c 比较时,两个对象指向的内存地址已经发生了变化,返回结果当然为false;

相关文章
|
1月前
|
安全 Java 编译器
Java对象一定分配在堆上吗?
本文探讨了Java对象的内存分配问题,重点介绍了JVM的逃逸分析技术及其优化策略。逃逸分析能判断对象是否会在作用域外被访问,从而决定对象是否需要分配到堆上。文章详细讲解了栈上分配、标量替换和同步消除三种优化策略,并通过示例代码说明了这些技术的应用场景。
Java对象一定分配在堆上吗?
|
2月前
|
Java API
Java 对象释放与 finalize 方法
关于 Java 对象释放的疑惑解答,以及 finalize 方法的相关知识。
54 17
|
1月前
|
存储 安全 Java
Java编程中的对象序列化与反序列化
【10月更文挑战第22天】在Java的世界里,对象序列化和反序列化是数据持久化和网络传输的关键技术。本文将带你了解如何在Java中实现对象的序列化与反序列化,并探讨其背后的原理。通过实际代码示例,我们将一步步展示如何将复杂数据结构转换为字节流,以及如何将这些字节流还原为Java对象。文章还将讨论在使用序列化时应注意的安全性问题,以确保你的应用程序既高效又安全。
|
2月前
|
存储 Java 数据管理
Java零基础-Java对象详解
【10月更文挑战第7天】Java零基础教学篇,手把手实践教学!
37 6
|
1月前
|
存储 缓存 NoSQL
一篇搞懂!Java对象序列化与反序列化的底层逻辑
本文介绍了Java中的序列化与反序列化,包括基本概念、应用场景、实现方式及注意事项。序列化是将对象转换为字节流,便于存储和传输;反序列化则是将字节流还原为对象。文中详细讲解了实现序列化的步骤,以及常见的反序列化失败原因和最佳实践。通过实例和代码示例,帮助读者更好地理解和应用这一重要技术。
49 0
|
7月前
|
安全 Java
Java StringBuffer 和 StringBuilder 类
Java StringBuffer 和 StringBuilder 类
50 0
|
4月前
|
安全 Java
【Java基础面试二十七】、说一说StringBuffer和StringBuilder有什么区别
这篇文章介绍了Java中StringBuffer和StringBuilder的区别:StringBuffer是线程安全的,而StringBuilder是非线程安全的,因此在单线程环境下优先推荐使用StringBuilder以获得更好的性能。
|
4月前
|
安全 Java API
Java系类 之 String、StringBuffer和StringBuilder类的区别
这篇文章讨论了Java中`String`、`StringBuffer`和`StringBuilder`三个类的区别,其中`String`是不可变的,而`StringBuffer`是线程安全的可变字符串类,`StringBuilder`是非线程安全的可变字符串类,通常在单线程环境下性能更优。
Java系类 之 String、StringBuffer和StringBuilder类的区别
|
4月前
|
API C# 开发者
WPF图形绘制大师指南:GDI+与Direct2D完美融合,带你玩转高性能图形处理秘籍!
【8月更文挑战第31天】GDI+与Direct2D的结合为WPF图形绘制提供了强大的工具集。通过合理地使用这两种技术,开发者可以创造出性能优异且视觉效果丰富的WPF应用程序。在实际应用中,开发者应根据项目需求和技术背景,权衡利弊,选择最合适的技术方案。
230 0
|
7月前
|
存储 Java
Java基础复习(DayThree):字符串基础与StringBuffer、StringBuilder源码研究
Java基础复习(DayThree):字符串基础与StringBuffer、StringBuilder源码研究
Java基础复习(DayThree):字符串基础与StringBuffer、StringBuilder源码研究