java String类常量池分析及"equals"和"==”区别详细介绍_java

java "equals"和"==”异同

首先简单说一下“equal”和“==”

==操作对于基本数据类型比较的是两个变量的值是否相等,

对于引用型变量表示的是两个变量在堆中存储的地址是否相同,

即栈中的内容是否相同

equals操作表示的两个变量是否是对同一个对象的引用,

即堆中的内容是否相同。

综上,==比较的是2个对象的地址,而equals比较的是2个对象的内容。

再简单介绍一下String类

String类 又称作不可变字符序列

String使用private final char value[]来实现字符串的存储,也就是说String对象创建之后,就不能再修改此对象中存储的字符串内容。String类有一个特殊的创建方法,就是使用""双引号来创建。例如new String("123")实际创建了2个String对象,一个是"123"通过""双引号创建的,另一个是通过new创建的.只不过他们创建的时期不同,一个是编译期,一个是运行期。java对String类型重载了+操作符,可以直接使用+对两个字符串进行连接。运行期调用String类的intern()方法可以向String Pool中动态添加对象。

区分两种创建String对象的方法“”和new()

String是一个特殊的包装类数据。可以用:

String str1 = new String("123");
String str2 = "123";

两种的形式来创建

第一种是用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象。(实际是两个正如上文所说,但是在常量池中存在“123”后就不会再在常量池中创建新的“123”)
第二种是先在栈中创建一个对String类的对象引用变量str,然后通过符号引用去字符串常量池里找有没有"abc",如果没有,则将"abc"存放进字符串常量池,并令str指向”abc”,如果已经有”abc”则直接令str指向“abc”。

这时我们应该注意

一方面,第一种写法有利与节省内存空间.同时它可以在一定程度上提高程序的运行速度,因为JVM会自动根据栈中数据的实际情况来决定是否有必要创建新对象。而对于String str = new String("123");的代码,则一概在堆中创建新对象,而不管其字符串值是否相等,是否有必要创建新对象,从而加重了程序的负担。另一方面,我们在使用诸如String str = "123";的格式定义类时,总是想当然地认为,创建了String类的对象str。
对象可能并没有被创建!而可能只是指向一个先前已经创建的对象。只有通过new()方法才能保证每次都创建一个新的对象。

请看下列实例

package testString; 

public class testString
{
  public static void main(String[] args)
  {
    String a = "123";
    String b = "123";
    System.out.println(a==b);
    System.out.println(a.equals(b));
    System.out.println("------------------------------------------");
    /**
     * true
     * true
     * 此处创建一个字符串"123"储存在常量池中
     * 因为"123"储存在常量区,并且唯一,即两个String引用a和b所的地址相同所以a==b为true
     * 并且两个引用在所指对象在堆中的内容相同所以a.equals(b)为true
     */
    String c = new String("1234");
    String d = new String("1234");
    System.out.println(c==d);
    System.out.println(c.equals(d));
    System.out.println("------------------------------------------");
    /*
     * false
     * true
     * 此处创建三个字符串“1234”,一个在常量池中,两个通过new储存在堆中
     * 因为c和d此时指向的是堆中的两个String对象,所以地址不同 c==d为false
     * 但是c与d堆中内容相同所以c.equals(d)为true
     */
    String e = "a1";
    String f = "a"+1;
    System.out.println(e==f);
    System.out.println(e.equals(f));
    System.out.println("------------------------------------------");
    /**
     * true
     * true
     * 此处创建“a1”“a”2个字符串其中“a1”“a”他们两个均在常量池中,你可能会问+是个运算符重载么?
     * 是的,java自己有一定的运算符重载但是你没法使用定义自己的运算符重载,和c++不同,String f = "a"+1;
     * 这句会被编译器做成 String f=“a1”;这与我们讲到的第一种情况相同,不再赘述。
     * 编译器之所以这么做是因为他在编译时就能够确定
     */
    String g = "gh";
    String hh = "h";
    String h = "g" + hh ;
    System.out.println(g==h);
    System.out.println(g.equals(h));
    System.out.println("------------------------------------------");
    /**
     * false
     * true
     * 与上面不同的是这里的h在编译时不能确定(编译器是这样认为的),所以h所指的对象在运行时确定储存在堆中,
     * 所以g==h为true而g.equals(h)为false
     */
  } 

}

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
, equal
, equals
, 与
, ==
详解
equals 常量、string equals、java string equals、string的equals方法、c string equals,以便于您获取更多的相关知识。

时间: 2024-10-31 11:14:26

java String类常量池分析及"equals"和"==”区别详细介绍_java的相关文章

java 线程中start方法与run方法的区别详细介绍_java

线程中start方法与run方法的区别 在线程中,如果start方法依次调用run方法,为什么我们会选择去调用start方法?或者在java线程中调用start方法与run方法的区别在哪里?  这两个问题是两个非常流行的初学者级别的多线程面试问题.当一个Java程序员开始学习线程的时候,他们首先会学着去继承Thread类,重载run方法或者实现Runnable接口,实现run方法,然后调用Thread实例的start方法.但是当他拥有一些经验之后,他通过查看API文档或者其他途径会发现start

java中 String类常量池

java中 String类常量池 String常量池详解: 1.String使用private final char value[]来实现字符串的存储,也就是说String对象创建之后,就不能再修改此对象中存储的字符串内容,就是因为如此,才说String类型是不可变的(immutable).String类有一个特殊的创建方法,就是使用""双引号来创建.例如new String("i am")实际创建了2个 String对象,一个是"i am"通过

Java的string类常量池及不可变性

1.String常量池     当使用new String("hello")时,JVM会先使用常量池来管理"hello"直接量,再调用String类的构造器来创建一个新的String对象,新创建的对象被保存在堆内存中.即new String("hello")一共产生了两个字符串对象. [常量池constant pool]管理在编译时被确定并保存在已编译的.class文件中的一些数据,包括关于类.方法.接口中的常量,和字符串常量.  [字符串常量池

java equals和=,==的区别详细介绍_java

Java中equals和==的区别 java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型.byte,short,char,int,long,float,double,boolean    他们之间的比较,应用双等号(==),比较的是他们的值. 2.复合数据类型(类)    当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false. JAVA当中所有的类都是继承于Object这个基

Java 常量与变量的区别详细介绍_java

       常量:其值不变即为常量. 语法: 数据类型 常量名 = 值; double PI = 3.14; 备注: 一般默认常量名大写. 变量与常量之间关系(量间关系) 先来一个简单的实例,好了解 Java 里变量与常量之间的关系. 下面的程序里声明了两种 Java 经常使用到的变量,分别为整型变量 num 与字符变量 ch.为它们赋值后,再把它们的值分别显示在控制台上: 下面的程序声明了两个变量,一个是整型,一个是字符型 public class TestJava{ public stat

java中静态变量和实例变量的区别详细介绍_java

运行效果: 控制台效果: ================================================== 代码部分 ================================================== /hello_test/src/com/b510/test/StaticTest.java 复制代码 代码如下: /**  *   */ package com.b510.test;  /**  * 在程序运行时的区别:实例变量属于某个对象的属性,必须创建了实

java向多线程中传递参数的三种方法详细介绍_java

在传统的同步开发模式下,当我们调用一个函数时,通过这个函数的参数将数据传入,并通过这个函数的返回值来返回最终的计算结果.但在多线程的异步开发模式下,数据的传递和返回和同步开发模式有很大的区别.由于线程的运行和结束是不可预料的,因此,在传递和返回数据时就无法象函数一样通过函数参数和return语句来返回数据.本文就以上原因介绍了几种用于向线程传递数据的方法,在下一篇文章中将介绍从线程中返回数据的方法. 欲先取之,必先予之.一般在使用线程时都需要有一些初始化数据,然后线程利用这些数据进行加工处理,并

Java线程中sleep和wait的区别详细介绍_java

Java中的多线程是一种抢占式的机制,而不是分时机制.抢占式的机制是有多个线程处于可运行状态,但是只有一个线程在运行. 共同点: 1. 他们都是在多线程的环境下,都可以在程序的调用处阻塞指定的毫秒数,并返回. 2. wait()和sleep()都可以通过interrupt()方法 打断线程的暂停状态 ,从而使线程立刻抛出InterruptedException. 如果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法.如果此刻线程B正在wait/sleep/

JAVA加密算法- 非对称加密算法(DH,RSA)的详细介绍_java

非对称密码概念 1.与对称加密算法的主要差别在于,加密和解密的密钥不相同,一个公开(公钥),一个保密(私钥).主要解决了对称加密算法密钥分配管理的问题,提高了算法安全性. 2.非对称加密算法的加密.解密的效率比较低.在算法设计上,非对称加密算法对待加密的数据长度有着苛刻的要求.例如RSA算法要求待加密的数据不得大于53个字节. 3.非对称加密算法主要用于 交换对称加密算法的密钥,而非数据交换 4.java6提供实现了DH和RSA两种算法.Bouncy Castle提供了E1Gamal算法支持.除