`
237253995
  • 浏览: 24067 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

[转]了解String类的intern()方法

    博客分类:
  • java
 
阅读更多

   相信绝大多数的人不会去用String类的intern方法,打开String类的源码发现这是一个本地方法,定义如下: 
   public native String intern(); 
   
   文档告诉我们该方法返回一个字符串对象的内部化引用。
众所周知:String类维护一个初始为空的字符串的对象池,当intern方法被调用时,如果对象池中已经包含这一个相等的字符串对象则返回对象池中的实例,否则添加字符串到对象池并返回该字符串的引用。 
   
   从程序的角度上怎么来看这个方法呢,我们假设有两个字符串s1,s2,当s1.equals(s2)时,s1.intern()==s2.intern(),也就是说这两个字符串在内存中使用的是同一个实例。 
   
   Java语言规范中定义了字符串文字以及更一般的常量表达式的值的字符串是被内部化的,以便它们共享同一个实例。我们试验一下下面代码:  


   String s1="你好,Java"; 
   String s2="你好,"+"Java"; 
   System.out.println(s1==s2); 
   System.out.println(s1.intern()==s2.intern()); 
   
   这段代码将打印两个true,也就是说字符串s1和s2是共享同一个实例。不过前提是尽管使用了表达式,但是表达式中必须都是常量。 
   
  了解这个处理机制也可以让我们在用到字符串常量的时候了解如何节省这些字符串所占用的内存。 

下面两个例子可以帮你:
其一:

  import   javax.swing.*;   
    
  public   class   StringIntern   {   
          public   static   void   main(String   args[])   
          {   
String s1, s2, s3, s4, output;
		s1 = new String("hello");
		s2 = new String("hello");

		if (s1 == s2)
			output = "s1   and   s2   are   the   same   object   in   memory";
		else
			output = "s1   and   s2   are   not   the   same   object   in   memory";

		if (s1.equals(s2))
			output += "\ns1   and   s2   are   equal";
		else
			output += "\ns1   and   s2   are   not   equal";

		s3 = s1.intern();
		s4 = s2.intern();

		if (s3 == s4)
			output += "\ns3   and   s4   are   the   same   object   in   memory";
		else
			output += "\ns3   and   s4   are   not   the   same   object   in   memory";

		if (s1 == s3)
			output += "\ns1   and   s3   are   the   same   object   in   memory";
		else
			output += "\ns1   and   s3   are   not   the   same   object   in   memory";

		if (s2 == s4)
			output += "\ns2   and   s4   are   the   same   object   in   memory";
		else
			output += "\ns2   and   s4   are   not   the   same   object   in   memory";

		if (s1 == s4)
			output += "\ns1   and   s4   are   the   same   object   in   memory";
		else
			output += "\ns1   and   s4   are   not   the   same   object   in   memory";

		JOptionPane.showMessageDialog(null, output,
				"Demonstrating   String   Method   intern",
				JOptionPane.INFORMATION_MESSAGE);

		System.exit(0);   
          }   
  }   

运行结果:

其二:
  假定要加载许多数据库数据到内存,这些数据有很多是重复的。在反复测试之后,发现intern() 省了好多内存。
以下是表信息:
mysql> select count(*) from t1;
+------------+
| count(*)   |
+------------+
| 8000       |
+------------+
1 row in set (0.01 sec)
mysql> select name From t1 limit 0,1;
+--------------------------------------+
| name                                 |
+--------------------------------------+
| 123456789123456789123456789          |
+--------------------------------------+
1 row in set (0.00 sec)
总共8000行 ,每行的数据都是 "123456789123456789123456789"
下面是类 (连接异常忽略)
public static void a1() throws SQLException {
  List list = new ArrayList();
  Connection con = DB.getCon();
  Statement stmt = con.createStatement();
  ResultSet rs = stmt.executeQuery("SELECT name FROM t1");
  while (rs.next()) {
    String s = rs.getString(1); 
    Po o = new Po();
   //o.setName(s); //注释掉
   o.setName(s.intern()); 
   list.add(o);
   s=null;
    o = null;
  }
  rs.close();
  stmt.close();
  con.close();
 }
public static void a2() throws SQLException {
  List list = new ArrayList();
  Connection con = DB.getCon();
  Statement stmt = con.createStatement();
  ResultSet rs = stmt.executeQuery("SELECT name FROM t1");
  while (rs.next()) {
   String s = rs.getString(1); 
   Po o = new Po();
   o.setName(s);
   list.add(o);
   s=null;
    o = null;
  }
  rs.close();
  stmt.close();
  con.close();
 }
注意: 
 a1 方法测试 使用内存: 2046544
 a2 方法测试 使用内存: 3475000
如果在函数的结尾加上 System.gc();  去除connection 的影响
 a1 方法测试 使用内存:   668856
 a2 方法测试 使用内存:2262232
然后再把 写函数 a3() ,把rs.getString(1) 换为 get()
static String get() {
  return "123456789123456789123456789123456789123456789";
 }
public static void a3() throws SQLException {
  List list = new ArrayList();
  Connection con = DB.getCon();
  Statement stmt = con.createStatement();
  ResultSet rs = stmt.executeQuery("SELECT name FROM t1");
  while (rs.next()) {
    String s = get(); 
    Po o = new Po();
    o.setName(s);
    list.add(o);
    s=null;
    o = null;
  }
  rs.close();
  stmt.close();
  con.close();
 }
a3 方法测试 使用内存:666536    
a2 (668856)比a3 的内存使用量多了一点点,这个估计就是常量池那一点内存
8000条数据 差别这么大, 数据量再大的话,优势更加明显.建议大家在连接数据库查询出来的数据,用intern();
注:内存使用 用 Runtime.getRuntime().totalMemory()-Runtime.getRuntime().freeMemory() 计算



转自: http://www.java3z.com/cwbwebhome/article/article2/21063.html?id=1833 谢谢原作者。
分享到:
评论

相关推荐

    String类的intern、split方法

    String类的intern、split方法 String 类的 intern 方法是一个本地方法,定义如下:public native String intern();该方法返回一个字符串对象的内部化引用,由 String 类维护一个初始为空的字符串的对象池,当 ...

    关于java String中intern的深入讲解

    intern 方法是 Java String 类中的一个native 方法,它的主要作用是将字符串对象存储在字符串常量池中,以便重复使用相同的字符串对象。intern 方法会检查字符串常量池中是否已经存在一个与当前字符串对象相同的字符...

    Java String的intern用法解析

    Java String的intern方法是Java中一个非常重要的方法,它可以将字符串常量池中的字符串对象返回给我们。今天,我们将深入探究Java String的intern用法解析,了解它的工作原理和应用场景。 Java String的intern方法 ...

    深入了解java 中的String

    `String` 类提供了一个 `intern()` 方法,该方法的作用是将当前字符串放入字符串池中,并返回字符串池中的引用。如果字符串池中已经有相同的字符串,则返回池中字符串的引用,否则会在池中创建一个新的字符串对象,...

    String类简介

    了解并熟练掌握`String`类的这些知识,对于编写高效、安全的Java代码至关重要。在实际开发中,我们常常需要结合其他数据结构和算法来优化字符串处理,以满足性能需求。因此,不断实践和探索是提升Java编程技能的关键...

    string常量池和intern_韩雅茹Java系列2021.pdf

    如果不是用双引号声明的String对象,可以使用String提供的intern方法。intern方法会从字符串常量池中查询当前字符串是否存在,若不存在就会将当前字符串放入常量池中。 在Java中,字符串常量池存在于方法区中。方法...

    Java String对象使用方法详解

    Java String对象使用方法详解是Java编程中一个非常重要的知识点,了解String对象的使用方法可以帮助开发者更好地编写Java程序。在Java中,String对象是不可变的,它的值一旦创建便不能改变。下面我们来详细地解释...

    Java基础复习(内附String中equals与==区别的分析)

    本篇复习将重点讨论String类中的`equals()`方法和`==`运算符的区别,这对于理解对象比较和字符串操作至关重要。 首先,`==`运算符在Java中用于比较基本类型(如int、char)的值,而在比较对象时,它实际上是检查两...

    String字符串比较1

    Java中的字符串操作是一个...了解字符串的存储位置(常量池或堆),以及如何通过`==`和`.equals()`比较字符串,以及`intern()`方法的作用,可以帮助开发者避免不必要的性能开销,并写出更符合Java内存管理原则的代码。

    Java基础教程之String深度分析

    本节课主要讲解了Java基础教程之String的相关知识点,包括String类的不可变性、字符串常量池、String对象的创建、String.intern()方法和String类的实现逻辑等。这些知识点对大家的学习和工作具有一定的参考学习价值...

    String_raw-源码.rar

    在Java编程语言中,`String`类是使用最频繁的类之一,它...通过分析`String_raw-源码.zip`文件中的源代码,开发者可以更深入地了解这些方法的实现细节,有助于优化代码性能,解决特定问题,或者进行自定义字符串操作。

    10个Java经典的String面试题!.zip

    在Java编程语言中,String类是使用最广泛的类之一,特别是在面试中,String相关的知识点往往是考察程序员基础功底的重要部分。下面将详细讲解这10个经典的Java String面试题,帮助你深入理解String的本质和使用技巧...

    详解Java的String类型程序

    `: 这里先使用`new`创建了一个新的`String`对象,然后调用`intern()`方法将其放入常量池。 比较结果: - `if (a == e)`: 结果为真。因为`e`和`a`最终都指向了字符串常量池中的同一个`"hehe"`实例。 - `if (e == ...

    String对象的内存分析

    例如,使用`String`的`intern()`方法可以确保重复的字符串引用同一个常量池中的实例,从而减少内存占用。同时,合理使用`StringBuilder`或`StringBuffer`进行字符串拼接,而非多次创建`String`对象,也能提高效率。

    MLDN魔乐JAVA_07作业讲解、String.rar

    这份资料可能是为学习者提供了关于String类的使用方法、特性以及相关编程作业的解答,旨在帮助他们深入理解和应用这一关键概念。 【描述】"魔乐JAVA" 暗示这是一个由魔乐教育机构推出的Java编程系列课程,可能包含...

    【JDK】分析 String str=““ 与 new String()(csdn)————程序.pdf

    在Java编程语言中,String是最常用的类之一,用于处理文本数据。本文主要分析两种创建String对象的...在实际编程中,推荐使用字符串字面量或`String.intern()`方法来优化内存使用,特别是对于大量重复字符串的情况。

    String 优化

    3. **复用`String`对象**:如果可能,使用`intern()`方法将字符串放入常量池,避免重复的`String`对象。 4. **使用`Pattern`和`Matcher`**:对于复杂的字符串处理任务,使用`Pattern.compile()`和`Matcher`可以更...

    java源码分析

    5. String类的intern()方法用于获取字符串对象的规范表示形式。如果常量池中已经存在与该字符串内容相同的字符串,则返回引用;否则,将字符串添加到常量池,并返回该字符串的引用。 在深入分析Java源码时,不仅要...

    java String的深入理解

    Java String 是 Java 语言中最基本的数据类型之一,然而,许多开发者对 String 的理解仅停留在表面,今天我们将深入了解 Java String 的内部机理和使用方法。 Java 字符串池 Java 字符串池是 JVM 中的一个特殊区域...

    Java中关于String的全面解析

    构造方法接下来我们通过一句代码来了解一下字符串创建的过程,`String c = new String("abc");`我们知道使用new关键字就会使用到构造方法,所以如下。 `public String(String original) {this.value = original....

Global site tag (gtag.js) - Google Analytics