Java·基础类库

CharSequence接口

在这里插入图片描述

在这里插入图片描述
现在只要有字符串就可以为CharSequence实例化,CharSequence本身是一个接口,在该接口中有如下方法:

获取指定索引的字符:public char charAt​(int index);
获取字符串长度:public int length​();
截取部分字符串:public CharSequence subSequence​(int start, int end);

AutoCloseable接口

AutoCloseable接口主要是用于日后进行资源开发的处理上,以实现资源的自动关闭(释放)。例如以后文件,网络,数据库开发之中,由于服务器资源有限,所以使用之后一定要释放资源,资源才可以被更多的使用者使用。
这个接口是JDK1.7提供的,并且只有一个方法:close。

java public void close() throws Exception

AutoCloseable接口位于java.lang包下,从JDK1.7开始引入。

1.在1.7之前,我们通过try{} finally{} 在finally中释放资源。

在finally中关闭资源存在以下问题:
1、自己要手动写代码做关闭的逻辑;
2、有时候还会忘记关闭一些资源;
3、关闭代码的逻辑比较冗长,不应该是正常的业务逻辑需要关注的;

2.对于实现AutoCloseable接口的类的实例,将其放到try后面(我们称之为:带资源的try语句),在try结束的时候,会自动将这些资源关闭(调用close方法)。

带资源的try语句的3个关键点:
1、由带资源的try语句管理的资源必须是实现了AutoCloseable接口的类的对象。
2、在try代码中声明的资源被隐式声明为final。**
3、通过使用分号分隔每个声明可以管理多个资源。

没实现该接口,要手动close:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package demo08;
interface IMessage{
public void send();
}
class Message implements IMessage{
private String msg;
public boolean open(){
System.out.println("[OPEN]连接成功");
return true;
}
public Message(String msg) {
if(this.open()) {
this.msg = msg;
}
}
public void close(){
System.out.println("[CLOSE]关闭资源");
}
@Override
public void send() {
System.out.println("发送消息:"+msg);
}
}
public class JavaAPIDemo {
public static void main(String[] args) {
Message m = new Message("Hello");
m.send();
m.close();
}
}

在这里插入图片描述
实现了该接口,就不用手动关闭了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package demo08;
interface IMessage extends AutoCloseable{
public void send();
}
class Message implements IMessage{
private String msg;
public boolean open(){
System.out.println("[OPEN]连接成功");
return true;
}
public Message(String msg) {
if(this.open()) {
this.msg = msg;
}
}
public void close(){
System.out.println("[CLOSE]关闭资源");
}
@Override
public void send() {
System.out.println("发送消息:"+msg);
}
}
public class JavaAPIDemo {
public static void main(String[] args) {
try(IMessage m = new Message("Hello")){
m.send();
}catch (Exception e){}
}
}

在这里插入图片描述

1
2
3
try(IMessage m = new Message("Hello")){
m.send();
}catch (Exception e){}

这里try-with-resources是jdk1.7引入的语法糖,使得关闭资源操作无需层层嵌套在finally。
由带资源的try语句管理的资源必须是实现了AutoCloseable接口的类的对象,而且实现了AutoCloseable的对象要想自动关闭,必须try-with-resources

Runtime类

Runtime描述的是运行时得到状态,也就是说在整个的JVM之中,Runtime类是唯一一个与JVM运行状态有关的类,并且都会more恩提供一个该类的实例化对象。
由于在每一个JVM进程里只允许有一个Runtime类对象,所以这个类的构造方法为private,则为单例设计模式,则一定有一个static的get方法获得本类实例。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1
2
3
4
5
6
7
8
9
10
11
12
package demo08;
import java.io.IOException;

public class JavaAPIDemo {
public static void main(String[] args) throws IOException {
Runtime runtime = Runtime.getRuntime();
System.out.println("Java虚拟机中的空闲内存量(G):"+runtime.freeMemory()/Math.pow(1024,3));
System.out.println("Java 虚拟机试图使用的最大内存量(G):"+ runtime.maxMemory()/Math.pow(1024,3));
System.out.println("Java 虚拟机中的内存总量(G):"+ runtime.totalMemory()/Math.pow(1024,3));
}
}

Java虚拟机中的空闲内存量(G):0.24523233622312546
Java 虚拟机试图使用的最大内存量(G):3.953125
Java 虚拟机中的内存总量(G):0.248046875

max默认大致为本机内存的四分之一。total默认为六十四分之一。

我们用一个String产生一些垃圾,再进行gc回收看看效果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package demo08;


import java.io.IOException;

public class JavaAPIDemo {
public static void main(String[] args) throws IOException {
Runtime runtime = Runtime.getRuntime();
System.out.println("Java虚拟机中的空闲内存量(G):"+runtime.freeMemory()/Math.pow(1024,3));
System.out.println("Java 虚拟机试图使用的最大内存量(G):"+ runtime.maxMemory()/Math.pow(1024,3));
System.out.println("Java 虚拟机中的内存总量(G):"+ runtime.totalMemory()/Math.pow(1024,3));
String s = "";
for (int i = 0; i < 10000; i++) {
s += "i";
}
System.out.println("=========================================");
System.out.println("Java虚拟机中的空闲内存量(G):"+runtime.freeMemory()/Math.pow(1024,3));
System.out.println("Java 虚拟机试图使用的最大内存量(G):"+ runtime.maxMemory()/Math.pow(1024,3));
System.out.println("Java 虚拟机中的内存总量(G):"+ runtime.totalMemory()/Math.pow(1024,3));
runtime.gc();
System.out.println("=========================================");
System.out.println("Java虚拟机中的空闲内存量(G):"+runtime.freeMemory()/Math.pow(1024,3));
System.out.println("Java 虚拟机试图使用的最大内存量(G):"+ runtime.maxMemory()/Math.pow(1024,3));
System.out.println("Java 虚拟机中的内存总量(G):"+ runtime.totalMemory()/Math.pow(1024,3));
}


}

在这里插入图片描述
GC垃圾收集器,是可以系统自动调用的垃圾释放功能,或者使用Runtime中的gc手动调用。

System类

currentTimeMillis和gc方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package demo08;

public class JavaAPIDemo {
public static void main(String[] args) {
String s = "";
long start = System.currentTimeMillis();
for (int i = 0; i < 300000; i++) {
s+=" ";
}
long end = System.currentTimeMillis();
System.out.println((end - start)/1000.0);
}

}

4.115

产生这些垃圾 耗时4.115s。

而System中的gc方法,实际上就是调用Runtime.getRuntime().gc()java.lang.System.gc()只是java.lang.Runtime.getRuntime().gc()的简写,两者的行为没有任何不同。

Cleaner类

Cleaner是JDK1.9后提供的对象清理操作,主要功能是方法finalize()的替代。
Java没有析构函数,垃圾自动回收。但是Java还是提供了给用户收尾的过程。每一个实例化对象在回收之前做一些处理。最初实现这些的方法,是Object类中的finalize方法。但是已经从1.9 deprecated了,不建议继续使用这个方法了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package demo08;

class Test{
public Test(){
System.out.println("【构造】对象创建");
}

@Override
protected void finalize() throws Throwable {
System.out.println("【回收】对象一定要死");
throw new Exception("还要再活五百年");
}
}
public class JavaAPIDemo {
public static void main(String[] args) {
Test t = new Test();//诞生
t = null;//成为垃圾
System.gc();
}

}

在这里插入图片描述
抛出的异常,并没有用。
从JDK1.9开始,已经不建议使用了,对象的释放。建议使用AutoCloseablejava.lang.ref.Cleaner
java.lang.ref.Cleaner也支持有AutoCloseable处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package demo08;

import java.lang.ref.Cleaner;

class Test implements Runnable{
public Test(){
System.out.println("【构造】对象创建");
}

@Override
public void run() {
System.out.println("【回收】对象一定要死");
}
}
class Clean implements AutoCloseable{//实现清除
private static final Cleaner CLEANER = Cleaner.create();//创建清除处理
private Test t;
private Cleaner.Cleanable cleanable;
public Clean(){
this.t = new Test();//创建对象
this.cleanable = this.CLEANER.register(this,this.t);//注册使用的对象
}
@Override
public void close() throws Exception {
this.cleanable.clean();//启动多线程
}
}
public class JavaAPIDemo {
public static void main(String[] args) {
try(Clean c = new Clean()){

}catch (Exception e){}
}

}

可以成为新时代的finalize。新一代的清除回收,更多情况下考虑多线程的使用。为了防止有可能造成的延迟处理(如果第一个程序没有System.gc();则处理会有延迟,不会输出【回收】一句),所以许多对象回收前的处理,都是单独通过一个线程完成的,保证执行性能的提高。
创建一个实现Runnable的类A->创建一个实现AutoCloseable接口的清除类B->利用create静态方法声明一个Cleaner对象c,声明一个A的对象引用a,声明一个Cleaner.Cleanable对象d,B的构造器中对A的对象a赋值实例,同时用c的register方法把a注册进去->重写的close方法执行d的clean方法。

对象克隆

Object类:在这里插入图片描述
所以所有的类都有clone方法,但不是所有类都希望被克隆。所以要想实现对象克隆,就要实现一个接口Cloneable,此接口并没有任何方法是因为它描述一种能力。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package demo08;
class Member implements Cloneable{
private String name;
private int age;

public Member(String name, int age) {
this.name = name;
this.age = age;
}

@Override
public String toString() {
return super.toString()+"Member{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}

@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class JavaAPIDemo {
public static void main(String[] args) throws CloneNotSupportedException {
Member A = new Member("hawkeye",20);
Member B = (Member)A.clone();
System.out.println(A);
System.out.println(B);

}

}

在这里插入图片描述
注意clone方法是protected,要覆写才能用。实际上开发中很少用对象克隆,注意要克隆就要实现Cloneable能力接口就好,以及clone方法返回Object类型,注意类型转换,还有覆写clone方法。


Java·基础类库
http://example.com/2021/05/27/Java%C2%B7%E5%9F%BA%E7%A1%80%E7%B1%BB%E5%BA%93%C2%B7%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/
作者
AHawkeye
发布于
2021年5月27日
许可协议