zoukankan      html  css  js  c++  java
  • 基础知识:Java中的String

    String对象的两种创建方式

       

    关于String有很多问题,首先关于String的创建,有两种创建方式

       

    String x = "abc";

    String z = new String("abc");

       

    那么这两种方式有什么不同呢

       

    两者的不同

       

    其实这两种方式创建的"abc"并不在一个地方,第一句的真正含义是在String池中创建一个对象"abc",然后在栈内创建一个引用x指向池中的对象"abc";第二句实在堆中创建一个对象"abc",然后在栈内创建一个引用z指向堆中的对象"abc"

       

    首先我们都知道Java中有堆和栈两个重要的内存区域,栈里面放着基本数据类型和对象的引用,而堆里面放着实实在在的对象,由new操作创建的对象肯定是放在堆里的,但是由双引号创建的对象则是放在String池里的,这个String池是常量池的一部分,它不属于堆和栈,它属于方法区(其实Java内存区域除了堆,栈之外还有程序计数器,本地方法栈,方法区这几部分)

       

    双引号创建方式

       

    双引号创建方式创建的内容相同的字符串是同一个字符串

       

    String x = "abc";

    String y = "abc";

       

    Java虚拟机在运行时维护一个String池,池中的String对象是单例的,首先String x = "abc"想创建字符串对象"abc"的时候首先会查看字符串池中是否已经存在,存在就直接返回池中的该String对象,这里不存在,那么就会创建一个新的String对象,并将该对象放进字符串池中,然后再栈中创建引用x,指向它

       

    在String y = "abc"想创建字符串对象"abc"的时候它首先也会查看字符串池中是否已经存在,由于已经存在,那么就直接返回池中的该String对象,然后再栈中创建引用y,指向它,由于是已经存在的,所以它们俩指向的是同一个对象

       

    字符串常量池的作用

       

    字符串池是为了解决字符串重复的问题,生命周期长,它存在于 permgen 中。而且放入字符串常量池实在编译的时候完成的,源文件中出现的双引号内的字符串都被收纳到常量池中。

       

    几个测试

       

    有了之前的知识基础我们看看常见的一些测试

       

    首先x==y肯定是对的

    然后x=="abc"肯定也是对的,这里的"abc"也在常量池中

    然后z=="abc"是不对的,因为"abc"在常量池中,z在堆中,==判断的是地址

    然后x.equals(z)这个是对的,因为String重写了equal方法,会去判断字符串的内容是否相等

    但是x==z就是不对的

       

    String的intern方法

       

    下面说一下intern()方法,该方法先在String池中查找是否存在一个对象,存在了就返回String池中对象的引用,如果不存在就在池中创建该对象。

    那么这样说起来,本来x==z是不对的,但是x==z.intern()就是对的,大家可以测试一下

       

    String的hashCode方法

       

    下面再说一下hashCode()方法,这个方法是返回字符串内容的哈希码,那么这样说来,虽然x==z是错的,但x.hashCode==z.hashCode就是对的,因为hashCode是根据字符串内容算出来的,既然内容相同,哈希码必然相同

       

    String的连接

       

    String重载了+运算符用于实现字符串的连接,但是由于String是不可更改的,所以+其实是新创建了一个字符串对象

       

    由于使用+连接字符串每次都生成新的对象,而且是在堆内存上进行,而堆内存速度比较慢(相对而言),那么大量连接字符串时使用+的效率就会比较低。Java提供了StringBufferStringBuilder来解决这个问题。

       

    区别是前者是线程安全的而后者是非线程安全的,StringBuilderJDK1.5之后才有。不保证安全的StringBuilder有比StringBuffer更高的效率。

       

    另外有种说法是JDK1.5之后,Java虚拟机执行字符串的+操作时,内部实现也是StringBuilder,之前采用StringBuffer实现,但是每次相加后其实还是都在堆区再新创建了一个对象,只是省去了中间大量连续连接字符串所创建的消耗

  • 相关阅读:
    适配器模式
    注册模式
    工厂模式
    策略模式和注入控制反转
    验签
    php中加密和解密
    asp.net textbox keyup事件触发后台的textchange事件
    jquery $.post 返回json数据
    网页播放音频、视频文件——基于web的html 5的音乐播放器(转载)
    c# 柱状图(转载)
  • 原文地址:https://www.cnblogs.com/keedor/p/4482379.html
Copyright © 2011-2022 走看看