StringBuffer类
String是所有项目开发都会用到的功能类,有如下特点:
- 每一个字符串常量都属于String类的匿名对象。
- String有两个常量池:静态常量池和运行时常量池。
- String类对象实例化建议使用直接赋值,可直接保存在对象池中方便下次使用
但是String弊端是,内容不允许修改。所以提供了StringBuffer类可用来修改字符串内容。
String和StringBuffer类的区别:
StringBuffer没有与String类一样的实例化方式,StringBuffer要像普通类对象一样先进性对象的实例化。
String:
package wzr.study04.classlibrary;
public class StrBufTest {
public static void main(String[] args) {
String str="Go To";
change(str);
System.out.println(str);
}
public static void change(String temp) {
temp+=" Study!";
}
}
OUT:Go To
StringBuffer类:
构造方法:public StringBuffer(String str);
数据追加:public StringBuffer append(type name);相当于“+”
package wzr.study04.classlibrary;
public class StrBufTest {
public static void main(String[] args) {
StringBuffer buf=new StringBuffer("Go To");
change(buf);
System.out.println(buf);
}
public static void change(StringBuffer temp) {
temp.append(" Study!");
}
}
大多时候,很少改变字符串内容,这种改变并不是针对静态常量池的改变。
String strA="www."+"Study."+"StringBuffer";
严格意义上讲,这并不是针对静态常量池的改变。
StringBuffer buf=new StringBuffer();
buf.append("www."+"Study."+"StringBuffer");
事实上,之前String内部操作都是用StringBuffer类这样操作的。
- String类对象变为StringBuffer类构造方法,或者使用append()方法。
- 所有的类对象都可以通过toString()方法将其变成String类型。
在StringBuffer类中提供了字符串修改,和一些String类没有的其他方法。
- 插入数据:public StringBuffer insert(int offset,type b);
buf.insert(0, "I ");
- 删除指定范围的数据:public StringBuffer delete(int start,int end);
buf.delete(1,4);//[start,end)
- 字符串内容反转:public StringBuffer reverse();
与StringBuffer类类似的类还有StringBuilder类,它是在jdk1.5时提供,该类与StringBuffer类功能相同。最大的区别在于,StringBuffer的方法属于线程安全的,全部使用了synchronized关键字进行标注,而StringBuilder属于非线程安全类。
总结:String,StringBuffer,StringBuilder的区别?
- String类是字符串的首选类型,最大特点是不允许修改。StringBuffer与StringBuilder类内容允许修改。
- StringBuffer是jdk1.0后提供的属于线程安全的,StringBuilder是jdk1.5后提供的,属于非线程安全的。
CharSequence接口
CharSequence是一个描述字符串结构的接口,一般有三种常用子集。
String:
public final class String
extends Object
implements Serializable,Comparable<String>,CharSequence;
StringBuffer:
public final class StringBuffer
extends Object
implements Serializable,CharSequence;
StringBuilder:
public final class StringBuilder
extends Object
implements Serializable,CharSequence
所以只要有字符串都可以通过CharSequence接收,作为CharSequence接口的实例化。
CharSequence cs="哇";
此接口在java.lang包中,jdk1.4中才抽象出来。有如下操作方法:
- 获取指定索引字符:public char charAt(int index);
- 获取字符串的长度:public int length();
- 截取部分字符串:public CharSequence subSequence(int start,int end);
public class StrBufTest {
public static void main(String[] args) {
CharSequence cs="哇,真棒";
CharSequence sub=cs.subSequence(2,4);
System.out.println(sub);
}
}
所以,CharSequence描述的就是一个字符串。
AutoCloseable接口
AutoClosealbe主要用于日后进行资源开发的处理上,以实现资源的自动关闭(释放资源),比如网络,数据库,服务器开发中由于服务器的资源有限,所以使用之后一定要关闭资源,这样才可以被更多人使用。
手工实现资源处理:
package wzr.study04.classlibrary;
public class CloseTest {
public static void main(String[] args) {
Message msg=new Message("www.study.test!");
msg.send();
msg.close();
}
}
interface IMessage{
public void send();
}
class Message implements IMessage{
private String msg;
public Message(String str) {
msg=str;
}
public void send() {
if(open()) {
System.out.println("[发送消息]:"+this.msg);
}
}
public boolean open() {
System.out.println("[OPEN]发送连接资源");
return true;
}
public void close() {
System.out.println("[CLOSE]关闭通道");
}
}
问题:所有资源处理后都要执行关闭操作,能否实现自动的关闭功能?
回答:用AutoCloseable接口(jdk1.7)。
- 关闭方法:public void close()throws Exception;
实现关闭处理时,需要使用AutoCloseable接口的close,和异常处理语句完成:
package wzr.study04.classlibrary;
public class CloseTest {
public static void main(String[] args)throws Exception {
// Message msg=new Message("www.study.test!");
// msg.send();
// msg.close();
try(IMessage msg=new Message("www.study.test")){
msg.send();
}catch(Exception e) {}
}
}
interface IMessage extends AutoCloseable{//?implement
public void send();
}
class Message implements IMessage{
private String msg;
public Message(String str) {
msg=str;
}
public void send() {
if(open()) {
System.out.println("[发送消息]:"+this.msg);
}
}
public boolean open() {
System.out.println("[OPEN]发送连接资源");
return true;
}
public void close() throws Exception{
System.out.println("[CLOSE]关闭通道");
}
}
接触到资源关闭问题,做好使用AutoCloseable接口。
AutoCloseable接口要和异常捆绑在一起。
Runtime类
Runtime描述的是运行时状态,在JVM中,Runtime类是唯一一个与JVM运行状态有关的类,并且都会默认提供一个该类的实例化对象。
由于每个JVM进程中只允许提供有一个Runtime类的对象,所以这个类的构造方法被默认私有化,并且使用单例设计模式,并且单例设计模式一定会提供有一个static方法获取本类实例。
由于Runtime类属于单例设计模式,如果想要获取实例化对象,就可以依靠getRuntime()完成。
- 获取实例化对象:public static Runtime getRuntime();
- 获取本机的内核数(并发访问量的最佳状态—多少人):availableProcessors()
范例:获取Runtime类对象
package wzr.study04.classlibrary;
public class RuntimeTest {
public static void main(String[] args) {
Runtime run=Runtime.getRuntime();
System.out.println(run.availableProcessors());
}
}
除以上方法,Runtime中还提供有四个重要操作方法:
- 获取最大可用内存空间:public long maxMemory();默认的配置为本机系统内存的四分之一。
- 获取可用内存空间:public long totalMemory();默认的配置为本机系统内存的64分之1
- 获取空闲内存空间:public long freeMemory();
- 手工进行GC处理:public void gc();
package wzr.study04.classlibrary;
public class RuntimeTest {
public static void main(String[] args) {
Runtime run=Runtime.getRuntime();
System.out.println(run.availableProcessors());
System.out.println(run.maxMemory());
System.out.println(run.totalMemory());
System.out.println(run.freeMemory());
run.gc();
System.out.println(run.maxMemory());
System.out.println(run.totalMemory());
System.out.println(run.freeMemory());
}
}
GC是什么?如何处理?
GC垃圾收集器,是可以由系统自动调用的垃圾释放功能,或者使用Runtime类中的gc()手工调用。
System类
- 数组拷贝:public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length);
- 获取当前的日期时间数值:public static long currentTimeMills();
- 进行垃圾回收:public static void gc();(Runtime.getRuntime().gc();)
gc()方法继续执行了Runtime中的gc()。
操作耗时的统计:
package wzr.study04.classlibrary;
public class SysTest {
public static void main(String args[]) {
long start=System.currentTimeMillis();
Runtime run=Runtime.getRuntime();
String str="";
for(int i=0;i<10000;i++) {
str+=i;
}
long end=System.currentTimeMillis();
System.out.println("耗时操作:"+(end-start));
}
}
Cleaner类
jdk1.9后提供的一个对象清理操作,其主要功能是进行finialize()方法的代替。
Java没有提供类似于析构函数的操作支持,不过依然提供了给用户收尾的操作。每一个实例化对象回收之前至少提供一个行为机会。最初是Object中的finalize()方法,此方法定义:
@Deprecated(since="9")
protected void finalize() throws Throwable
但是子类可以使用,它的不同在于抛出一个Throwable异常类型。它分为两个子类型:Error,Exception。
范例:传统回收
package wzr.study04.classlibrary;
public class ClearTest {
public static void main(String args[]) {
Man man=new Man();
man=null;
System.gc();
}
}
class Man{
public Man() {
System.out.println("[构造]");
}
protected void finalize() throws Throwable{
System.out.println("[回收]");
throw new Exception("[还在]");
}
}
对于对象的回收释放,建议AutoCloseable,Cleaner,PhantomReference。从jdk1.9开始,建议使用AutoCloseable或者java.lang.ref.Cleaner类进行回收处理(Cleaner也有AutoCloseable的处理)。
package wzr.study04.classlibrary;
import java.lang.ref.Cleaner;
public class ClearTest {
public static void main(String args[]) {
try(ManCleaning mc=new ManCleaning()){
}catch(Exception e) {}
}
}
class ManCleaning implements AutoCloseable{
private static final Cleaner cleaner = Cleaner.create();
private Man man;
private Cleaner.Cleanable cleanable;
public ManCleaning() {
this.man=new Man();
this.cleanable=this.cleaner.register(this, this.man);
}
@Override
public void close() throws Exception {
this.cleanable.clean();//启动多线程
}
}
class Man implements Runnable{
public Man() {
System.out.println("[构造]");
}
public void run() {
System.out.println("[回收]");
//throw new Exception("[还在]");
}
}
在新一代的取出回收处理的过程中,更多考虑多线程的使用。为了防止有可能造成的延迟处理,许多对象回收前的处理都是单独通过一个线程完成的。
对象克隆
Object类提供了clone()方法:protected Object clone() throws CloneNotSupportedException;
并不是所有对象都想被克隆。如果想实现克隆,对象需要一个接口。Cloneable接口,它没有任何方法提供,它描述的是一种能力。
范例:实现对象克隆:
package wzr.study04.classlibrary;
public class CloneTest {
public static void main(String[] args) throws CloneNotSupportedException {
Mans mana=new Mans("aaa",18);
Mans manb=(Mans)mana.clone();
System.out.println(mana.toString());
System.out.println(manb.toString());
}
}
class Mans implements Cloneable{
private String name;
private int age;
public Mans(String name,int age) {
this.name=name;
this.age=age;
}
public String toString(){
return super.toString()+"---"+name+"---"+age;
}
protected Object clone() throws CloneNotSupportedException{
return super.clone();
}
}
如果不是特殊情况,很少有对象克隆的需求。