JDK源码学习(2)-String.intern()方法详解

1.方法intern()为java内部方法,如下

 public native String intern();

native方法为通过jvm进行运行,jdk8中隐藏了该方法的具体处理方法。

2.作用:该方法注释为

“如果常量池中存在当前字符串, 就会直接返回当前字符串. 如果常量池中没有此字符串, 会将此字符串放入常量池中后, 再返回”。

3.测试代码一

public static void main(String[] args) {
		String s1 = new String("1");
		s1.intern();
		String s2 = "1";

		System.out.println(s1 == s2);

		String s3 = new String("1") + new String("1");
		s3.intern();
		String s4 = "11";

		System.out.println(s3 == s4);
	}

结果:

jdk6环境下:

false false

jdk8环境下:

false true

原因分析:

1)jdk6的虚拟机结构中常量池主要是在Perm中,即内存模型为对象存放到java堆区(heap)中,而常量池主要是在java方法区。属于不同的两个区域。

字符串的初始化中,new时会创建一个对象放在java堆中,而通过引号创建则会在常量池中创建常量,两个区域是隔绝的,因此即使intern之后比较引用的话也不会是相同的。

2)jdk7之后由于之前Perm的大小只有4M,已经无法满足项目的发展,因此取消了Perm的限制,而是移动到了堆区,jdk8更是取消了Perm区。

对于上面代码,s1创建的时候,生成了一个对象和一个对象的值,因此s1对应的是对象的引用,s2是对应的常量的引用。

s3初始化的时候对于“11”来说只有一个对象,当调用intern的时候,由于没有该常量,因此jdk7之后会生成一个指向对象的引用存放到常量中。而当s4初始化之后,s4也直接为常量中的对象的引用,因此引用值比较之后为true。

时间: 2024-08-05 06:30:41

JDK源码学习(2)-String.intern()方法详解的相关文章

String intern()方法详解

执行以下代码 String a1=new String("abc");       String a2=new String("abc");       System.out.println(a1==a2);       System.out.println(a1==a2.intern());       System.out.println("abc"==a2.intern());       System.out.println(a1.int

jquery源码解析:jQuery工具方法详解2

jQuery的工具方法,其实就是静态方法,源码里面就是通过extend方法,把这些工具方法添加给jQuery构造函数的. jQuery.extend({ ...... type: function( obj ) {    //$.type(),判断类型 if ( obj == null ) {   //null,undefined return String( obj );    //返回null,undefined字符串 }     //core_toString = {}.toString 

jquery源码解析:jQuery工具方法详解3

jQuery的工具方法,其实就是静态方法,源码里面就是通过extend方法,把这些工具方法添加给jQuery构造函数的. jQuery.extend({ ...... each: function( obj, callback, args ) {   //$.each(arr , function(i,value){}),第三个参数用于内部调用.此方法就是来遍历数组的,然后取数组中的值进行显示.不能改变原数组arr,跟map一样,但是map返回新数组,而each返回原数组.这里跟原生的forEa

jquery源码解析:jQuery工具方法详解4

jQuery的工具方法,其实就是静态方法,源码里面就是通过extend方法,把这些工具方法添加给jQuery构造函数的. jQuery.extend({ ...... guid: 1, //唯一标识符,跟事件有关.举个例子:function show(){alert(this);}, $("#input1").click(show),$("#input2").click(function(){$("#input1").off()}),这里的sho

jquery源码解析:jQuery工具方法详解1

jQuery的工具方法,其实就是静态方法,源码里面就是通过extend方法,把这些工具方法添加给jQuery构造函数的. jQuery.extend({       //当只有一个对象时,就把这个对象中的属性和方法扩展到this对象中,这里的this指向jQuery expando: "jQuery" + ( core_version + Math.random() ).replace( /\D/g, "" ), //唯一性,core_version 为jQuery

JDK源码学习--String篇(二) 关于String采用final修饰的思考

JDK源码学习String篇中,有一处错误,String类用final[不能被改变的]修饰,而我却写成静态的,感谢CTO-淼淼的指正. 风一样的码农提出的String为何采用final的设计,阅读JDK源码的时候,有粗略的思考过,今天下班后又把<Thinking in Java>中关于final的内容重新看了一遍,对此写下一些关于自己的理解和想法. String类中final关键字的使用 final关键字,用来描述一块数据不能被改变,两种可能理由:设计.效率 final使用的三种情况:数据.方

JDK源码学习系列08----HashMap

                                                          JDK源码学习系列08----HashMap 1.HashMap简介 HashMap 是一个散列表,它存储的内容是键值对(key-value)映射. HashMap 继承于AbstractMap,实现了Map.Cloneable.java.io.Serializable接口. HashMap 的实现不是同步的,这意味着它不是线程安全的.它的key.value都可以为null.此外,

JDK源码学习LinkedList

LinkedList是List接口的子类,它底层数据结构是双向循环链表.LinkedList还实现了Deque接口(double-end-queue双端队列,线性collection,支持在两端插入和移除元素).所以LinkedList既可以被当作双向链表,还可以当做栈.队列或双端队列进行操作.文章目录如下: 1.LinkedList的存储实现(jdk 1.7.0_51) 2.LinkedList的读取实现 3.LinkedList的性能分析 下面我们进入正题,开始学习LinkedList. L

JDK源码学习系列06----Vector

                                            JDK源码学习系列06----Vector 1.Vector简介 Vector的内部是数组实现的,它和ArrayList非常相似,最大的不同就是 Vector 是线程安全(同步)的. public class Vector<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.S