博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
源码学习-String类
阅读量:4942 次
发布时间:2019-06-11

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

最近在扫描CodeDex时报了一个不能使用String.intern()的字符串来做锁对象的告警,对这个问题有疑问查了些资料,顺便学习一下String类的源码。

1.类定义 String 被final修饰,是叶子类,不能不继承。实现了Serializable,Comparable,CharSequence 接口

public final class String    implements java.io.Serializable, Comparable
, CharSequence {...}

Serializable:实现此接口来支持序列化和反序列化,Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的

Comparable:实现此接口的对象列表(和数组)可以通过 Collections.sort (和 Arrays.sort )进行自动排序

CharSequence:字符序列,String本质是通过字符数组实现的

 

2.属性

2.1 value final的数组,用来储存String对象的字符

2.2 hash String对象的HashCode

2.3 serialPersistentFields ?在序列化流协议中String类会被特别包装,String对象会被写入到一个ObjectOutputStream...

3.构造方法

3.1 无参数构造方法默认返回空的字符串,因为String是不可变的,所有没有必要使用此构造函数

1 public String() {2         this.value = "".value; 3 }

3.2

1 public String(String original) {2         this.value = original.value; 3 this.hash = original.hash; 4 }

3.3

1 public String(char value[]) {2         this.value = Arrays.copyOf(value, value.length); 3 }

3.4

public String(byte bytes[]) {//用默认的charset进行decode         this(bytes, 0, bytes.length);     } public String(byte bytes[], int offset, int length) { checkBounds(bytes, offset, length); this.value = StringCoding.decode(bytes, offset, length); } public String(byte bytes[], int offset, int length, Charset charset) { if (charset == null) throw new NullPointerException("charset"); checkBounds(bytes, offset, length); this.value = StringCoding.decode(charset, bytes, offset, length); }

3.5 把此String对象的字符copy到dst数组,dst数组中从dstBegin的位置开始放置,此方法不进行任何边界校验

void getChars(char dst[], int dstBegin) {        System.arraycopy(value, 0, dst, dstBegin, value.length);    }

3.6 比较此对象从toffset位置的len长度字符数组是否和other对象的ooffset位置的len长度字符数组是同一个数组

/**比较本对象从toffset位置开始的len长度的char数组是否和other对象的ooffset位置开始的len长度的char数组是同一个数组*/public boolean regionMatches(int toffset, String other, int ooffset, int len) {...} /* *带boolean参数的表示是否忽略大小写 */ public boolean regionMatches(boolean ignoreCase, int toffset, String other, int ooffset, int len) {...} /* *在equalsIgnoreCase方法中调用了带boolean参数的regionMatches */ public boolean equalsIgnoreCase(String anotherString) { ... }

3.7 是否以特定的字符串开头和结尾

public boolean startsWith(String prefix, int toffset) {...}public boolean endsWith(String suffix) {...}//endsWith调用的startsWith

3.8 indexOf系列

View Code

3.9

public String substring(int beginIndex) {...}

3.10 concat() 本对象之后连接字符串,返回新生成新的字符串

public String concat(String str) {        int otherLen = str.length();        if (otherLen == 0) { return this; } int len = value.length; char buf[] = Arrays.copyOf(value, len + otherLen); str.getChars(buf, len); return new String(buf, true); }

3.11 校验字符串是否符合正则表达式

public boolean matches(String regex) {...}

3.12 delimiter做连接符连接字符串列表或数组

public static String join(CharSequence delimiter, CharSequence... elements) {        Objects.requireNonNull(delimiter);        Objects.requireNonNull(elements);        // Number of elements not likely worth Arrays.stream overhead.        StringJoiner joiner = new StringJoiner(delimiter); for (CharSequence cs: elements) { joiner.add(cs); } return joiner.toString(); }

e.g.

public static void main(String[] args)    {        List
names=new ArrayList
(); names.add("1"); names.add("2"); names.add("3"); System.out.println(String.join("-", names)); String[] arrStr=new String[]{"a","b","c"}; System.out.println(String.join("-", arrStr)); }

输出:

3.13 去除字符串前后空格返回生成的新的子字符串

public String trim() {...}

3.14 格式化字符串

3.14.1 方法签名

public static String format(String format, Object... args) {...}

3.14.2 转换符

 

说    明 

示    例

%s

字符串类型

"mingrisoft"

%c

字符类型

'm'

%b

布尔类型

true

%d

整数类型(十进制)

99

%x

整数类型(十六进制)

FF

%o

整数类型(八进制)

77

%f

浮点类型

99.99

%a

十六进制浮点类型

FF.35AE

%e

指数类型

9.38e+5

%g

通用浮点类型(f和e类型中较短的)

 

%h

散列码

 

%%

百分比类型

%n

换行符

 

%tx

日期与时间类型(x代表不同的日期与时间转换符

3.14.3 e.g.

System.out.println(String.format("现在的时间是:%d-%d-%d %d:%d:%d",2011,1,2,15,29,30));

输出结果:

3.15 valueOf

public static String valueOf(Object obj) {        return (obj == null) ? "null" : obj.toString(); }

3.16 String类私有维护的String pool 初始化时是空的,当对象s调用intern方法时,如果pool中已存在与之equals为true的t对象,那么池中存在的t对象会被返回,否则新的String对象会被加入到pool中,然后返回这个String对象的引用。

此得出结论:只要s.equals(t),s.intern() == t.intern() 为true

public native String intern();

当使用String s = "abc"方式创建字符串时,字符串会自动加入常量池,而当使用String s = new String("abc")方式创建时,只有调用了s.intern()方法才会把s加入常量池

String pool default size:

7u40之前:1009,

7u40+ to 8:60013

java6的时候存在PermGen区,容易造成oom,java7之后改为存在Heap区

7u02之后可以用-XX:StringTableSize=100003 设置JVM参数

(参考http://java-performance.info/string-intern-in-java-6-7-8/)

 

转载于:https://www.cnblogs.com/cici20166/p/6298489.html

你可能感兴趣的文章
数据清空js清空div里的数据问题
查看>>
Fortran中的指针使用
查看>>
移动终端app测试点总结
查看>>
14-6-27&28自学内容小结
查看>>
JSP
查看>>
---
查看>>
(第一组_GNS3)自反ACl
查看>>
hdu--1258--Sum It Up(Map水过)
查看>>
Spring @DeclareParents 的扩展应用实例
查看>>
VS2012更新Update1后帮助查看器无法打开
查看>>
Android 文件的读取和写入
查看>>
高校表白APP-冲刺第四天
查看>>
outlook 设置163邮箱
查看>>
mysql优化——show processlist命令详解
查看>>
Solr服务器搭建
查看>>
画世界怎么用光影_世界绘画经典教程:水彩光影魔法教程
查看>>
win+rsync+php,跨平台的fswatch+rsync同步备份
查看>>
vue2 cdn 加载html,vue项目中使用CDN加载
查看>>
数组转集合踩坑
查看>>
node.js的异步I/O、事件驱动、单线程
查看>>