Java高级编程

Java基础类库

2019-07-23  本文已影响57人  江湖非良人

StringBuffer

  String类时在所有项目开发之中一定会使用的功能类,这个类拥有如下的特点:

范例:观察String和StringBuffer对比
String类对象引用传递

public class JavaApiDemo {
    public static void main(String[] args) {
        String str = "hello";
        change(str);
        System.out.println(str);
    }
    public static void change(String temp) {
        temp += "world !";//内容并没有发生改变
    }
}

StringBuffer类对象引用传递

public class JavaApiDemo {
    public static void main(String[] args) {
        StringBuffer buf = new StringBuffer("hello");
        change(buf);
        System.out.println(buf.toString());
    }
    public static void change(StringBuffer temp) {
        temp.append(" world !");//内容已改变
    }
}

  实际上大部分的情况下,很少会出现有字符串内容的改变,这种改变并不是针对静态常量池的改变。
范例:分析一下已有问题

public class JavaApiDemo {
    public static void main(String[] args) {
        String strA = "www.baidu.com";
        String strB = "www." + "baidu" + ".com";
        System.out.println(strA == strB);
        System.out.println(strA.equals(strB));
    }
}

  这时的strB对象的内容并不是改变,从更加严格的意义上说,对于现在的strB当程序编译后会变成如下的形式:

public class JavaApiDemo {
    public static void main(String[] args) {
//        String strB = "www." + "baidu" + ".com";
        //等同于
        StringBuffer strB=new StringBuffer();
        strB.append("www.").append("baidu").append(".com");
    }
}

  所有的“+” 在编译后都变为了StringBuffer中的append()方法,并且在程序中StringBuffer和String类对象之间本就可以直接互相转换。

public class JavaApiDemo {
    public static void main(String[] args) {
        StringBuffer buf=new StringBuffer();
        buf.append(".com").insert(0,"www.").insert(4,"baidu");
        System.out.println(buf.toString());
    }
}

  2、删除指定范围的数据:public StringBuffer delete​(int start, int end);

public class JavaApiDemo {
    public static void main(String[] args) {
        StringBuffer buf=new StringBuffer();
        buf.append("hello xxx world !").delete(5,9);
        System.out.println(buf.toString());
    }
}

  3、字符串内容反转:public StringBuffer reverse​();

public class JavaApiDemo {
    public static void main(String[] args) {
        StringBuffer buf=new StringBuffer();
        buf.append("hello world !").reverse();
        System.out.println(buf.toString());
    }
}

  实际上与StringBuffer类还有一个类似的功能类:StringBuilder类,这个类时在JDK1.5的时候提供的,该类中提供的方法与StringBuffer功能相同,最大区别在于StringBuffer类中的方法属于线程安全的,全部用了synchronized关键字进行标注,而StringBuilder类属于非线程安全的,

CharSequence接口

  CharSequence是一个描述字符串结构的接口,在这个接口中有三种常用子类:

public class JavaApiDemo {
    public static void main(String[] args) {
        CharSequence str="www.baidu.com";//子类实例向父接口转型
    }
}

  CharSequence是一个接口,在该接口中定义了如下操作方法:

public class JavaApiDemo {
    public static void main(String[] args) {
        CharSequence str="www.baidu.com";//子类实例向父接口转型
        CharSequence sub=str.subSequence(4,9);
        System.out.println(sub.toString());
    }
}

  以后只要看见CharSequence描述的就是一个字符串。

AutoCloseable接口

  AutoCloseable主要用于日后进行资源开发的处理上,以实现资源的自动关闭(释放资源),例如:在以后进行文件、网络、数据库开发的过程中,由于服务器的资源有限,所以在使用之后一定要关闭资源,这样才可以被更多的使用者所使用。
  下面为了更好的说明资源的问题,将通过一个消息的发送来处理完成。
范例:手工实现资源处理

interface IMessage {
    void send();//消息发送
}
class NetMessage implements IMessage {//实现消息的处理机制
    private String msg;
    public NetMessage(String msg) {
        this.msg = msg;
    }
    @Override
    public void send() {
        if (this.open()) {
            System.out.println("【*** 发送消息 ***】" + this.msg);
        }
    }
    public boolean open() {//获取资源连接
        System.out.println("【OPEN】获取消息发送连接资源");
        return true;
    }
    public void close() {
        System.out.println("【CLOSE】关闭消息发送通道");
    }
}
public class JavaApiDemo {
    public static void main(String[] args) {
        NetMessage nm = new NetMessage("www.baidu.com");//定义要发送的处理
        nm.send();//消息发送
        nm.close();//关闭连接
    }
}

  可以发现,所有的资源完成处理之后都必须进行关闭操作,那能否实现一种自动关闭的功能呢?由此退出了AutoCloseable访问接口,这个接口是在JDK1.7的时候提供的,并且该接口只提供有一个方法:

  要想实现自动关闭处理,除了要使用AutoCloseable外,还需要结合异常处理语句才可以正常调用。
范例:实现自动关闭处理

public class JavaApiDemo {
    public static void main(String[] args) throws Exception{
        try (IMessage nm = new NetMessage("www.baidu.com")){
            nm.send();//消息发送
        }catch (Exception e){}

    }
}
interface IMessage extends AutoCloseable{
    void send();//消息发送
}
class NetMessage implements IMessage {//实现消息的处理机制
    private String msg;
    public NetMessage(String msg) {
        this.msg = msg;
    }
    @Override
    public void send() {
        if (this.open()) {
            System.out.println("【*** 发送消息 ***】" + this.msg);
        }
    }
    public boolean open() {//获取资源连接
        System.out.println("【OPEN】获取消息发送连接资源");
        return true;
    }
    @Override
    public void close() throws Exception{
        System.out.println("【CLOSE】关闭消息发送通道");
    }
}

  在以后的章节中会接触到资源的关闭问题,往往都会见到AutoCloseable接口的使用。

Runtime

  Runtime描述的是运行时的状态,在整个JVM中,Runtime类时唯一一个与JVM运行状态有关的类,并且都会默认提供一个该类的实例化对象。
  由于在每一个JVM进程中只允许提供一个Runtime类的对象,所以这个类的构造方法被默认私有化了,标明该类使用的是单例设计模式,并且单例设计模式一定会提供一个static方法获取本类实例。


Runtime

  由于Runtime类属于单例设计模式,如果想要获取实例化对象,那么就可以依靠类中的getRuntime()方法完成:

public class JavaApiDemo {
    public static void main(String[] args) throws Exception{
        Runtime runtime=Runtime.getRuntime();//获取实例化对象
        System.out.println(runtime.availableProcessors());
    }
}

  但是除了以上的方法之外,在Runtime类中还提供了以下四个重要的操作方法:

public class JavaApiDemo {
    public static void main(String[] args) throws Exception{
        Runtime runtime=Runtime.getRuntime();//获取实例对象
        System.out.println("1、MAX_MEMORY:"+runtime.maxMemory());
        System.out.println("1、TOTAL_MEMORY:"+runtime.totalMemory());
        System.out.println("1、FREE_MEMORY:"+runtime.freeMemory());
        String str="";
        for (int i = 0; i < 30000; i++) {
            str+=i;//产生大量的垃圾空间
        }
        System.out.println("2、MAX_MEMORY:"+runtime.maxMemory());
        System.out.println("2、TOTAL_MEMORY:"+runtime.totalMemory());
        System.out.println("2、FREE_MEMORY:"+runtime.freeMemory());
        runtime.gc();
        System.out.println("3、MAX_MEMORY:"+runtime.maxMemory());
        System.out.println("3、TOTAL_MEMORY:"+runtime.totalMemory());
        System.out.println("3、FREE_MEMORY:"+runtime.freeMemory());
    }
}

System

  System类贯穿我们开发的程序类,之前使用的系统输出采用的就是System类中的方法,System中还定义了一些其他的处理方法:

public class JavaApiDemo {
    public static void main(String[] args) throws Exception{
        long start=System.currentTimeMillis();
        String str="";
        for (int i = 0; i < 30000; i++) {
            str+=i;//产生大量的垃圾空间
        }
        System.out.println("操作耗时:"+(System.currentTimeMillis()-start));
    }
}

  在System类中也提供了一个gc()方法,实际上调用的是Runtime.getRuntime().gc();

Cleaner

  Cleaner是在JDK1.9之后才提供的一个对象清理操作,其主要的功能是进行finalize()方法的替代。在C++语言中有两种特殊的函数:构造函数、析构函数(对象手工回收),在Java中所有的垃圾空间都是通过GC自动回收的,很多情况下是不需要析构函数的,因此所以Java并没有提供这方面支持。
  但是Java本身依然提供了给用户收尾的操作,每一个实例化对象在回收之前保留一个被处理的机会,最初实现对象收尾处理的方法时Object类中所提供的finalize()方法,这个方法的定义如下:

@Deprecated(since="9")
protected void finalize​()  throws Throwable

  该替换指的是不建议继续使用这个方法了,而是说子类可以继续使用这个方法名称。 但这个方法上最大的特点就是抛出了一个Throwable异常类型,而这个异常类型分为两个子类型:Error、Exception,平产所处理的都是Exception。
范例:观察传统回收

class Member{
    public Member() {
        System.out.println("【构造】创建了一个Member对象");
    }
    @Override
    protected void finalize() throws Throwable {
        System.out.println("【回收】回收了一个Member对象");
        throw new Exception("回收发生异常");
    }
}
public class JavaApiDemo {
    public static void main(String[] args) throws Exception{
        Member member=new Member();
        member=null;
        System.gc();
        System.out.println("回收异常并不会抛出");
    }
}

  从JDK1.9开始,这一操作已经不建议使用了,而对于对象回收释放。从JDK1.9开始建议开发者使用AutoCloseable或者使用java.lang.ref.Cleaner类进行回收处理(Cleaner也支持有AutoCloseable处理);

//一定要使用JDK1.9+版本
class Member implements Runnable{
    public Member() {
        System.out.println("【构造】创建了一个Member对象");
    }
    @Override
    public void run() {//执行清除时执行的是此操作
        System.out.println("【回收】回收了一个Member对象");
    }
}
class MemberCleaning implements AutoCloseable{//实现清除的处理
    private static final Cleaner cleaner=Cleaner.create();//创建一个清除处理
    private Member member;
    private Cleaner.Cleanable cleanable;
    public MemberCleaning() {
        this.member=new Member();//创建新对象
        this.cleanable=this.cleaner.register(this,this.member);//注册使用的对象
    }
    @Override
    public void close() throws Exception {
        this.cleanable.clean();//启动多线程
    }
}
public class JavaApiDemo {
    public static void main(String[] args) throws Exception{
        try(MemberCleaning mc=new MemberCleaning()) {
            //中间可以执行一些相关的代码
        }catch (Exception e){}
    }
}

  在新一代的清除回收处理的过程之中,更多的情况下考虑的是多线程的使用,即:为了防止有可能造成的延迟处理,所以许多对象回收前的处理都是单独通过一个线程完成的。

对象克隆

  所谓的对象克隆指的就是对象的复制,而且属于全新的复制。即:使用已有对象内容创建一个新的对象,如果要使用对象克隆则需要使用到Object类中提供的clone()方法:protected Object clone​() throws CloneNotSupportedException;
  所有的类都会继承Object父类,所以所有的类都一定会有clone()方法,但是并不是所有的类都希望被克隆。所以要实现克隆,所在类必须要实现Cloneable接口,此接口并没有提供需要实现的方法,因为它描述的是一只种能力。
范例:实现对象克隆

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() + "】name = " + this.name + "、age = " + this.age;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();//调用父类提供的clone()方法
    }
}
public class JavaApiDemo {
    public static void main(String[] args) throws Exception {
        Member a=new Member("张三",30);
        Member b=(Member)a.clone();
        System.out.println(a);
        System.out.println(b);
    }
}

  如果不是特殊的开发需求下,很少会出现有对象克隆的需求。

上一篇 下一篇

猜你喜欢

热点阅读