• 浅谈一下Java String


      相信很多同学使用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的大小了。

     1 package com.hqs.stringlearning;
     2 
     3 public class StringTest {
     4     
     5     public static void main(String[] args) {
     6         String abc = new String("abc");
     7         String str = "abc";
     8         String str1 = "ab";
     9         String str2 = "c";
    10         String str3 = "ab" + "c";
    11         String abc1 = new String("abc");
    12         System.out.println(abc.equals(str));
    13         System.out.println(abc.intern() == str);
    14         System.out.println(abc == str);
    15         System.out.println(str == (str1+"c"));
    16         System.out.println(str == str1+str2);
    17         System.out.println(str == str3);
    18         System.out.println(abc == abc1);
    19         
    20     }
    21     
    22 }
    23 
    24 true
    25 true
    26 false
    27 false
    28 false
    29 true
    30 false

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

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

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

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

  • 相关阅读:
    UPC OJ 一道水题 STL
    POJ2387 Til the Cows Come Home(SPFA + dijkstra + BallemFord 模板)
    HD1385Minimum Transport Cost(Floyd + 输出路径)
    POJ1679The Unique MST(次小生成树)
    POJ 1789Truck History(pirme)
    POJ2309BST(树状数组)
    POJ2299Ultra-QuickSort(归并排序 + 树状数组求逆序对)
    POJ2531Network Saboteur(DFS+剪枝)
    Codeforce#331 (Div. 2) A. Wilbur and Swimming Pool(谨以此题来纪念我的愚蠢)
    POJ2485Highways(prime 水题)
  • 原文地址:https://www.cnblogs.com/huangqingshi/p/7521870.html
Copyright © 2020-2023  润新知