java.lang.String
特性
- 不可变
- 两种根据字面量构建字符串的方法
String str = "foo";
直接指向字符串常量池中的 "foo"
,至多创建一个对象(常量池中的字符串)
String str = new String("foo");
每个不同的字符串都会在“字符串常量池”中创建对象,也就是至多创建两个对象(String
对象 + 常量池中的字符串)
String.intern()
方法
- 字符串字面量会保存在字符串常量池中
new String(...)
无论如何会在堆里创建对象
- 其他类(例如
StringBuilder
和 Integer
)的 toString
方法,实际调用的是 new String(...)
String.intern()
方法可以手动把一个字符串加入常量池
String.split()
方法
- 返回类型是
String[]
- 按照正则表达式拆分
- 可选的第二个参数
"abcba".split("b", 1)
- 如果是正数,那么至多切成这么多段(
[abcba]
)
- 如果是 0,那么尽量多切,并且删除最后的那些空段
- 如果是任何负数,那么尽量多切,并且不删除最后的空段
- 还可以用
Pattern
类 + Matcher
类进行拆分
static Pattern pattern = Pattern.compile("some_regex")
Matcher matcher = pattern.matcher(str)
- 必须先调用
matcher.matches()
进行匹配
System.out.println(matcher.group(1))
,从 1 开始编号
编码
- 两种编码:latin-1(一个字节)或者 utf-16(2 或 4 个字节),由 coder 属性决定,用 byte 数组存储
- charAt 返回 char(两个字节)
- codePointAt 返回 int,表示那个字符(若干字节),可以用
Character.toString(int codePoint)
转换为字符串
面向对象
Object 类的方法
- 对象比较
hashCode()
native
函数,实现取决于 JVM 实现
- 如果两个对象通过
equals
方法比较为 true
,那么 hashCode()
应该相等
- 但是如果为
false
,不要求 hashCode
一定不同
equals(Object obj)
:默认实现为 return (this == obj);
即比较地址
- 对象拷贝
clone()
:默认实现为浅拷贝,但要求必须实现接口 Cloneable
才行
- 对象转字符串
toString()
:默认实现由类名加上 hashCode()
组成
- 多线程调度
wait(long timeout)
native
函数
- 让当前线程等待被
notify
或者 interrupt(Java 中断机制)
wait(long timeout, int nanos)
:额外指定微秒数,更加精确
notify()
:native
函数,唤醒单个正在 wait
同一个对象的线程
notifyAll()
:native
函数,唤醒所有正在 wait
同一个对象的线程
getClass()
:native
函数,获取当前对象的运行时 Class
对象,用于反射相关
finalize()
:从 Java 9 开始已弃用
访问权限
- 方法
public
方法:可以被任何类访问
private
方法:只能被当前类访问
protect
方法:可以被当前包中的任何类,或者其他包中自己的子类访问
default
方法(默认):只能被当前包中的任何类访问
构造方法
- 不能是
final
,abstract
,static
,synchronized
- 拷贝对象
- 三种方法:构造函数,对应字段赋值,
Object.clone
方法
Object.clone
方法
- 默认实现是
native
函数,进行浅拷贝(即引用类型的字段的引用被复制)
- 要想使用,必须实现
Cloneable
接口,Object
类没有实现 Cloneable
接口
- 初始化块
- 初始化块被 Java 编译器放在构造方法的开头执行
- 执行顺序:父类静态初始化块 → 子类静态初始化块 → 进入
main
方法 → 父类构造方法 → 子类初始化块 → 子类构造方法
抽象类与接口
- 抽象类可以有抽象方法和普通方法
- 抽象方法不能是
static
的
- 抽象方法在子类中必须实现
- 抽象类可以继承抽象类,并且继承它的普通类仍然需要实现每一级抽象类的抽象方法
- 接口可以有常量成员、抽象方法、默认方法、静态方法
- 接口默认是
abstract
的
- 接口的方法默认是
public abstract
的
- 接口的常量成员默认是
public static final
的,也必须是这样的
- 默认方法需要用
default
关键字修饰
- 一个类可以实现多个接口
内部类
- 内部类可以是抽象类,或者是接口
- 成员内部类
- 类似成员,可以有各种访问权限
- 可以访问外部类的任何成员(包括
private
成员,就好比一个类的成员函数也可以访问这个类的 private
成员)
- 通过
foo.new Bar()
语法进行实例化
- 局部内部类
- 匿名内部类
new
的时候临时定义的,不能有构造方法
- 用
new Temp() { ... }
语法进行声明与实例化
- 静态内部类
- 类似静态成员,可以有各种访问权限
- 可以访问外部类的任何
static
成员
- 用
new Foo.Bar()
语法进行实例化