博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
这篇文章上讲解的知识点你全搞明白了,Java中的字符串你就彻底理解了。
阅读量:2289 次
发布时间:2019-05-09

本文共 3079 字,大约阅读时间需要 10 分钟。

这篇文章上讲解的知识点你全搞明白了,Java中的字符串你就彻底理解了。

 

字符数组的存储方式

public static void main(String[] args) {    char[] arr = new char[]{'1', '2'};    while (true);}

image.png

image.png

 

字符串常量池

 

即String Pool,但是JVM中对应的类是StringTable,底层实现是一个hashtable,看代码

class StringTable : public Hashtable
{……

 

Key的生成方式

1、通过String的内容+长度生成hash值2、将hash值转为keyhashValue = hash_string(name, len);index = hash_to_index(hashValue);// Pick hashing algorithmunsigned int StringTable::hash_string(const jchar* s, int len) {  return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) :                                    java_lang_String::hash_code(s, len);}  // Bucket handling  int hash_to_index(unsigned int full_hash) {    int h = full_hash % _table_size;    assert(h >= 0 && h < _table_size, "Illegal hash value");    return h;  }

 

Value的生成方式

将Java的String类的实例instanceOopDesc封装成HashtableEntryHashtableEntry
* entry = new_entry(hashValue, string());add_entry(index, entry);template
HashtableEntry
* Hashtable
::new_entry(unsigned int hashValue, T obj) { HashtableEntry
* entry; entry = (HashtableEntry
*)BasicHashtable
::new_entry(hashValue); entry->set_literal(obj); return entry;}

String.hashcode()

 

String类重写了hashcode方法

public int hashCode() {    int h = this.hash;    if (h == 0 && this.value.length > 0) {        char[] val = this.value;        for(int i = 0; i < this.value.length; ++i) {            h = 31 * h + val[i];        }        this.hash = h;    }    return h;}

可以看出String的hashcode与String的内容是有关系的,因此下面的代码的hashcode是相等的

public class TestHashcode {    public static void main(String[] args) {        String s1 = "11";        String s2 = new String("11");        System.out.println(s1.hashCode());        System.out.println(s2.hashCode());    }}

 

不同方式创建字符串在JVM中的存在形式

 

双引号

image.png

 

new String

image.png

 

两个双引号

 

image.png

两个new String

 

image.png

拼接字符串底层是如何实现的

 

双引号 + 双引号

public class TestString_5 {    public static void main(String[] args) {    }    public static void test2() {        String s1 = "1";        String s2 = "1";        String s = s1 + s2;    }} 0 ldc #2 <1> 2 astore_0 3 ldc #2 <1> 5 astore_1 6 new #3 
9 dup10 invokespecial #4
>13 aload_014 invokevirtual #5
17 aload_118 invokevirtual #5
21 invokevirtual #6
24 astore_225 return

 

双引号 + new String

public class TestString_6 {    public static void main(String[] args) {    }    public static void test2() {        String s1 = "1";        String s2 = new String("1");        String s = s1 + s2;    }} 0 ldc #2 <1> 2 astore_0 3 new #3 
6 dup 7 ldc #2 <1> 9 invokespecial #4
>12 astore_113 new #5
16 dup17 invokespecial #6
>20 aload_021 invokevirtual #7
24 aload_125 invokevirtual #7
28 invokevirtual #8
31 astore_232 return

intern做了什么

 

常量池中有就直接返回

常量池中没有就创建一个,然后返回

 

image.png

练习

 

1、这句代码创建了几个对象?为什么?

String s1 = new String("子牙真帅");

 

2、这句代码创建了几个对象?为什么?

String s2 = "子牙" + "子牙";

 

3、这句代码创建了几个对象?为什么?

String s2 = "子牙" + new String("真帅");

 

4、将实例的intern代码的四个内存图画出来

转载地址:http://vfbnb.baihongyu.com/

你可能感兴趣的文章
独立安装LAMP时需要注意的几点
查看>>
socket
查看>>
判断远程url是否有效的几种方法
查看>>
javascript中编写类似in_array()的原型函数
查看>>
go 数据库操作
查看>>
php读取二进制流
查看>>
Golang热重启
查看>>
热重启golang服务器(graceful restart golang http server)
查看>>
echo框架使用:获取与配置
查看>>
PHP模拟多进程并发将内容写入文件
查看>>
nginx.conf配置说明
查看>>
Eclipse设定和修改文件字符编码格式和换行符
查看>>
git常用操作以及快速入门教程
查看>>
MongoDB 3.0 常见集群的搭建(主从复制,副本集,分片....)
查看>>
在notepad++中 “tab转为空格”、“按tab插入空格”、“文档格式转换”
查看>>
Zend Framework 常用组件概述
查看>>
Zend_Db -> Zend_Db_Adapter
查看>>
Zend_Db -> Zend_Db_Select
查看>>
Zend_Db -> Zend_Db_Table
查看>>
PHP漏洞全解(三)-客户端脚本植入
查看>>