相信很多同学使用Java String, Java中的String方法,但是对其中的原理可能有些模糊,那么咱们就针对这块内容进行展开,让更多的同学理解和知道。

  

  public final class String
implements java.io.Serializable, Comparable<String>, CharSequence

  首先我们打开String的源码,看到String是一个final的,也就是不可变的,不能修改的,不能被继承的。为什么是final的,这其中的原因有很多种:

  1. 假设如果一个String是可变的,那么像如下代码,如果执行了str的重新赋值,那么str1把内容"Test1"改为"Test2"了,则str2也会跟着变化,因为他们指向的是同一块区域(指向安全)。
       String str = "Test1";
   String str1 = "Test1";

  2. 正式因为String是不可变的,所以多线程访问比可变对象不用额外的写一个synchronized或锁机制(线程安全)。

   3. 在网络传输过程中,很多经常传输的是字符串,那么传输的内容也不会被别的内容改变,这样传输字符串的时候更加安全(网络安全)。

4. 同理,classloader加载一个类的时候,例如:java.util.HashMap,在加载的过程中不会被改成“com.hqs.xxx”,更多请详细参考JVM家在机制(加载安全)。

5. String中也会有hashCode,所以再HashMap用到key为String的时候,那么它的hashCode会被缓存起来,这样每次去找key的时候效率提高了(性能)。

     在String中,还有一个比较重要的方法intern(),返回这个string对象的规范表示形式,也就是在String pool里边的表示。

  

 //Returns a canonical representation for the string object.
    public native String intern();

在java 1.6中,String pool存放在perm space永久区中,可以用过直接string赋值的方式(7#)将字符串放到string pool里边,如果用new String(6#)的方式则不然,需要创建一个对象放到内存中,如果池子里边存在的话,那么直接指向,如果没有的话,需要再次创建一个对象。
因为在perm space中,最大的内存是96M,稍有不慎可能会出现OOM,所以在java 1.7及后续版本中,Java进行了改进,将string pool放到了heap中,这样可以多用一些空间了,并且可以设置String pool的大小了。

 package com.hqs.stringlearning;

 public class StringTest {

     public static void main(String[] args) {
String abc = new String("abc");
String str = "abc";
String str1 = "ab";
String str2 = "c";
String str3 = "ab" + "c";
String abc1 = new String("abc");
System.out.println(abc.equals(str));
System.out.println(abc.intern() == str);
System.out.println(abc == str);
System.out.println(str == (str1+"c"));
System.out.println(str == str1+str2);
System.out.println(str == str3);
System.out.println(abc == abc1); } } true
true
false
false
false
true
false

这个是我针对此代码画的截图,针对java 1.6的。

  那么为什么用这个intern()方法呢,是因为如果字符串过大的时候,可能需要在池子里边存放一个,这样节省空间和提高性能。什么时候使用呢,当需要很大的String并且重复使用时建议使用这个方式。

如果所有父引用都没有了,那么GC会把这个对象回收掉。

    如果有问题或写的不对的地方,请告知,谢谢。68344150@qq.com

浅谈一下Java String的更多相关文章

  1. 20190608_浅谈go&java差异(三)

    20190608_浅谈go&java差异(三) 转载请注明出处https://www.cnblogs.com/funnyzpc/p/10990703.html 第三节内容概览 多线程通讯(线程 ...

  2. 浅谈C++ STL string容器

    浅谈C++ STL string容器 本篇随笔简单讲解一下\(C++STL\)中\(string\)容器的使用方法及技巧. string容器的概念 其实\(string\)并不是\(STL\)的一种容 ...

  3. 浅谈:java泛型与dao重用

    在进入今天的主题之前,我们先理解一下什么是泛型: 泛型是java中一种类型,泛型是被参数化的类型. 类型-->class 参数化-->class类型可以是任意参数 泛型存在的意义:泛型可以 ...

  4. 浅谈用java解析xml文档(四)

    继续接上一文,这一阵子因为公司项目加紧,导致最后一个解析xml文档的方式,还没有总结,下面总结使用dom4J解析xml. DOM4J(Document Object Model for Java) 使 ...

  5. 浅谈用java解析xml文档(三)

    接上一篇,本文介绍使用JDOM解析xml文档, 首先我们还是应该知道JDOM从何而来,是Breet Mclaughlin和Jason Hunter两大Java高手的创作成果,2000年初, JDOM作 ...

  6. 浅谈对java中锁的理解

    在并发编程中,经常遇到多个线程访问同一个 共享资源 ,这时候作为开发者必须考虑如何维护数据一致性,在java中synchronized关键字被常用于维护数据一致性.synchronized机制是给共享 ...

  7. 浅谈对java中传参问题的理解

    之前用的c/c++比较多,在c/c++中对于传参类型,无外乎就是传值.传引用.传指针这几种.但在java中,由于没有指针类型,其传参的方式也发生了相应的变化.在网上找了找,按我之前的理解,java中传 ...

  8. 20190312_浅谈go&java差异(一)

    多线程 java java中对于大量的比较耗时的任务多采用多线程对方式对任务进行处理,同时由于进程和线程 本身是通过宿主机OS进行管理的,当在cpu核数较少或线程分配不当 会导致多线程的效果不佳的事常 ...

  9. 浅谈在java中list集合的排序问题

    定义实体类: public class Person { private Integer id; private String name; private Integer age; public In ...

随机推荐

  1. 深度学习:Keras入门(二)之卷积神经网络(CNN)

    说明:这篇文章需要有一些相关的基础知识,否则看起来可能比较吃力. 1.卷积与神经元 1.1 什么是卷积? 简单来说,卷积(或内积)就是一种先把对应位置相乘然后再把结果相加的运算.(具体含义或者数学公式 ...

  2. 使用我的编译器,下面的代码 int i=7; printf("%d\n", i++ * i++); 返回 49?不管按什么顺序计算, 难道不该打印出56吗?

    尽管后缀自加和后缀自减操作符 ++ 和 -- 在输出其旧值之后才会执行运算, 但这里的"之后"常常被误解.没有任何保证确保自增或自减会在输出变量原值之 后和对表达式的其它部分进行计 ...

  3. ida和idr机制分析(盘符分配机制)

    # ida和idr机制分析 ida和idr的机制在我个人看来,是内核管理整数资源的一种方法.在内核中,许多地方都用到了该结构(例如class的id,disk的id),更直观的说,硬盘的sda到sdz的 ...

  4. C#使用Xamarin开发可移植移动应用目录

    Xamarin.Android系列 C#开发移动应用系列(1.环境搭建) C#开发移动应用系列(2.使用WebView搭建WebApp应用) C#开发移动应用系列(3.使用照相机扫描二维码+各种基础知 ...

  5. 蓝桥杯算法训练_2的次幂表示+前缀表达式+Anagrams问题+出现次数最多的整数

    今天做了4个简单的题,题目虽然是简单,但是对于我这样的小白,还是有很多东西需要学习的. 2的次幂表示 上面就是题目,题目说的也很清晰了,接下来就是递归的实现: #include<iostream ...

  6. 线程池ThreadPoolExecutor与阻塞队列BlockingQueue应用

    1.线程池介绍 JDK5.0以上: java.util.concurrent.ThreadPoolExecutor  构造函数签名: public ThreadPoolExecutor( int co ...

  7. 【.net 深呼吸】获取日期的干支纪年

    其实,中国的农历是用干支纪年法的,“干支”即,十天干与十二地支. 十天干为:甲.乙.丙.丁.戊.己.庚.辛.壬.癸. 十二地支为:子.丑.寅.卯.辰.巳.午.未.申.酉.戌.亥. 十天干的含义如下: ...

  8. vTPM环境部署(ubuntu)

    注:1.系统:ubuntu16.04LTS2.ISO镜像:/home/huanghaoxiang/ubuntu-server.iso3.IMG路径:/home/TPM-Machine4.Login: ...

  9. iOS app 的 ASLR

    这两天逆向一个程序,发现每次image list -o -f 之后,它的基地址都是0x00000,也就是偏移地址是0.  想到这个应该是载入内存时有没有启用偏移有关,于是找了下答案:aslr 百度百科 ...

  10. yum和apt-get的区别

    一般来说著名的linux系统基本上分两大类: 1.RedHat系列:Redhat.Centos.Fedora等  2.Debian系列:Debian.Ubuntu等  RedHat 系列  1 常见的 ...