• 进阶Java编程(5)基础类库


    Java基础类库

    1,StringBuffer类

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

        ①每一个字符串的常量都属于一个String类的匿名对象,并且不可更改;

        ②String有两个常量池:静态常量池、运行时常量池;

        ③String类对象实例化建议使用直接赋值的形式完成,这样可以直接将对象保存在对象池之中以方便下次重用。

      虽然String类很好使用,但是如果认真去思考也会发现其最大的弊端:内容不允许修改,虽然大部分情况下都不会涉及到字符串内容的频繁修改,但是依然可能会存在有这样的情况,所以为了解决此问题,专门提供了一个StringBuffer类可以实现字符串内容的修改处理。

      StringBuffer并不像String类那样拥有两种对象的实例化方式,StringBuffer必须像普通类对象那样首先进行对象实例化,而后才可以进行调用方法执行处理,而这个时候可以考虑StringBuffer类中的如下方法:

        ·构造方法:public StringBuffer()

        ·一参构造方法:public StringBuffer(String str)

        ·数据追加:public StringBuffer append(数据类型 变量),相当于字符串中的【+】操作;

      ·范例:观察String与StringBuffer对比

    String类对象引用传递

    StringBuffer类对象引用

    public class Main {
    public static void main(String[] args){
            String str="Hello ";
    change(str);
            System.out.println(str);

    //内容没有发生修改!!!
    }
    public static void change(String temp){
            temp+="World !";
        }
    }

    public class Main {
    public static void main(String[] args){
            StringBuffer str=new StringBuffer("Hello ");
    change(str);
            System.out.println(str);

    //内容没有发生修改!!!
    }
    public static void change(StringBuffer temp){
            temp.append("World !");
        }
    }

    Hello

    Hello World !

      实际上大部分的情况下,很少会出现有字符串内容的改变,这种改变指的并不是针对于静态常量池的改变。

      ·范例:分析以下已有问题

    1 public class Main {
    2 public static void main(String[] args){
    3         String strA = "www.mldn.cn";
    4         String strB = "www."+"mldn."+"cn";
    5         System.out.println(strA==strB);
    6         System.out.println(strA.equals(strB));
    7     }
    8 }

    这个时候的strB对象的内容并不算改变,或者更加严格意义上来讲,对于现在的strB当程序编译之后会变成如下的形式:

    String

    String strB = "www."+"mldn."+"cn";

    StringBuffer

    StringBuffer buf=new StringBuffer();
    buf.append("www.").append("mldn.").append("cn");

      所有【+】在编译之后都变为了StringBuffer中的append()方法,并且来讲在程序之中StringBuffer与String类之间本来就可以直接互相转换。

        ①String类对象变为StringBuffer可以依靠StringBuffer类的构造方法或者使用append方法;

        ②所有类对象都可以通过toString()方法将其转变为String类型。

      在StringBuffer类里面除了可以支持有字符串内容的修改之外,实际上也提供有了一些String类所不具备的方法。例如insert()追加数据,删除指定范围的数据delete(),字符串反转reverse()

      实际上与StringBuffer类还有一个类似的功能类:StringBuilder类(JDK1.5),与StringBuffer类的功能基本相同。

      最大的区别在于StringBuffer类中的方法属于线程安全的,全部使用了synchronized关键字进行标注,而StringBuilder类属于非线程安全的。

    面试题:请解释String、StringBuffer、StringBuilder的区别?

      ①String类是字符串的首选类型,其最大的特定是内容不允许修改;

      ②StringBuffer类与StringBuilder类的内容允许修改;

      ③StringBuffer是在JDK1.0提供,属于线程安全的操作,而StringBuilder是在JDK1.5提供属于非线程安全操作。

    2,CharSequence接口

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

    String类

    StringBuffer类

    StringBuilder类

    public final class String extends Object implements Serializable Comparable<String>,CharSequence

    public final class StringBuffer extends Object implements Serializable ,CharSequence

    public final class StringBr extends Object implements Serializable ,CharSequence

    wps2

      现在只要有字符串就可以为CharSequence接口实例化。

      ·范例:

    public class Main {
    public static void main(String[] args) throws CloneNotSupportedException{
            CharSequence str="hello,Mufasa";
        }
    }

    获取指定索引字符

    public char charAt(int index)

    获取字符串长度

    public int length()

    截取部分字符串

    public CharSequence subSequence(int start,int end)

    CharSequence本身是一个接口,在该接口之中也定义有如下操作方法:

    ·范例:字符串的截取

    1 public class Main {
    2 public static void main(String[] args) throws CloneNotSupportedException{
    3         CharSequence str="hello,Mufasa";
    4         CharSequence sub=str.subSequence(2,5);
    5         System.out.println(sub);
    6     }
    7 }

    3,AutoCloseable接口  CharSequence描述的就是一个字符串。 

      AutoCloseable主要是用于日后进行资源开发的处理上,以实现资源的自动关闭(释放资源),例如:以后进行文件、网络、数据库开发的过程之中由于服务器的资源有限,所以使用之后一定要关闭资源,这样才可以被更多的使用者所使用。

      下面为了更好的说明资源的问题,将通过一个消息的发送处理来完成。

      ·范例:手工实现资源处理

     1 interface IMessage{
     2 public void send();
     3 }
     4 class NetMessage implements IMessage{
     5 private String msg;
     6 public NetMessage(String msg) {
     7 this.msg = msg;
     8     }
     9 public boolean open(){
    10         System.out.println("【OPEN】获取消息发送连接资源");
    11 return true;
    12     }
    13 @Override
    14 public void send() {
    15         System.out.println("【发送消息】"+this.msg);
    16     }
    17 public void close(){
    18         System.out.println("【CLOSE】关闭消息发送通道");
    19     }
    20 }
    21 public class Main {
    22 public static void main(String[] args) throws CloneNotSupportedException{
    23         NetMessage netMessage=new NetMessage("Mufasa");
    24 
    25 //定义发送处理
    26 if(netMessage.open()){//是否打开了连接
    27 netMessage.send();//消息的发送
    28 netMessage.close();//关闭连接
    29 }
    30     }
    31 }

      关闭方法:public void close() thrws Exception;  此时有位设计师说了,既然所有的资源完成处理之后都需要进行关闭操作,那么能否实现一种自动关闭的功能呢?再这样的要求下推出了AutoCloseable访问接口,这个接口是在JDK1.7的时候提供的,并且该接口只提供有一个方法:

    wps3

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

      ·范例:实现自动关闭处理

     1 interface IMessage extends AutoCloseable{
     2     public void send();
     3 }
     4 class NetMessage implements IMessage{
     5     private String msg;
     6     public NetMessage(String msg) {
     7         this.msg = msg;
     8     }
     9     public boolean open(){
    10         System.out.println("【OPEN】获取消息发送连接资源");
    11         return true;
    12     }
    13     @Override
    14     public void send() {
    15         System.out.println("【发送消息】"+this.msg);
    16     }
    17     public void close() throws Exception{
    18         System.out.println("【CLOSE】关闭消息发送通道");
    19     }
    20 }
    21 public class Main {
    22     public static void main(String[] args) throws Exception{
    23         try(IMessage nm=new NetMessage("Mufasa")){
    24             nm.send();
    25         }catch (Exception e){
    26             e.printStackTrace();
    27         }
    28     }
    29 }

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

      Runtime描述的是运行时的状态,也就是说在整个的JVM重,Runtime类是唯一一个与JVM运行状态有关的类,并且都会默认提供有一个该类的实例化对象。

      由于在每一个JVM进程里面只提供有一个Runtime类的对象,所以这个类的构造方法被默认私有化了,那么就证明该类使用的是单例设计模式,并且单例设计模式一定会提供有一个static方法获取本类实例。

    wps4

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

    获取实例化对象

    public static Runtime getRuntime()

       

      ·范例:获取Runtime对象

    1 public class Main {
    2     public static void main(String[] args) {
    3         Runtime run=Runtime.getRuntime();
    4         System.out.println(run.availableProcessors());//8核心CPU
    5     }
    6 }

      但是除了以上方法之外,在Runtime类里面还提供有以下四个重要的操作方法:  通过这个类中的【availableProcessors()】方法可以获取本机的CPU的内核数量。

    获取最大可用内存空间

    public long maxMemory()

    默认为本机内存的1/4

    获取可用内存空间

    public long totalMemory()

    默认为本机内存的1/64

    获取空闲内存空间

    public long freeMemory()

     

    手动GC处理

    public void gc()

     

      面试题:什么是GC?如何处理?

      答:GC(garbage collector)垃圾收集器,是可以由系统自动调用的垃圾释放功能,或者使用Runtime类中的GC手工调用。

    5,System类

      System类是一直陪伴着我们学习的程序类【System.out.println()】

    数组拷贝

    public static void arraycopy(Object src,int srcPos,Object dest,int destPos,int length)

    获取当前日期时间

    public static long currentTimeMillis()

    进行垃圾回收

    public static void gc()

      ·范例:操作耗时的统计

     1 public class Main {
     2 public static void main(String[] args) {
     3 long start=System.currentTimeMillis();
     4         String str="";
     5 for(int x=0;x<30000;x++){
     6             str+=x;
     7         }
     8 long end = System.currentTimeMillis();
     9         System.out.println("操作耗时:"+(end-start));
    10     }
    11 }
    操作耗时:602

      在System类中也提供一个【gc()】方法,但是这个gc()方法并不是重新定义的新方法,而是继续执行【Runtime.getRuntime.gc()】。

    wps5

    6,Cleaner类

      Cleaner是在JDK1.9之后提供的对象清理操作,其主要功能是进行【finialize()】方法的替代。在C++语言里面有两种特殊的函数:①构造函数(对象初始化);②析构函数(对象手工回收),在Java里面所有的垃圾空间都是通过GC进行自动回收的,所以很多情况下是不需要使用这类析构函数的,也正是因为如此,所以Java并没有提供这一方面的支持。

      但是Java本身依然提供了给用户收尾的操作,每一个实例化对象在回收之前至少给它一个喘息的机会,最初提供对象收尾处理的方法是Object类中所提供的【finalize】方法,这个方法的定义如下:

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

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

     1 class Member{
     2 public Member(){
     3         System.out.println("【构造】实例化对象诞生");
     4     }
     5 @Override
     6 protected void finalize() throws Throwable {
     7         System.out.println("【回收】实例化对象收尾");
     8 throw  new Exception("还想继续存在");
     9     }
    10 }
    11 public class Main {
    12 public static void main(String[] args) throws Exception{
    13         Member member=new Member();
    14         member=null;
    15         System.out.println("对象失去索引称为垃圾");
    16 Runtime.getRuntime().gc();
    17         System.out.println("手动进行GC处理");
    18     }
    19 }
     1 import java.lang.ref.Cleaner;
     2 class Member implements Runnable{
     3     public Member(){
     4         System.out.println("【构造】实例化对象诞生");
     5     }
     6     @Override
     7     public void run() {//执行清除最终执行的是此操作
     8         System.out.println("【回收】实例化对象收尾");
     9     }
    10 }
    11 class MemberCleaning implements AutoCloseable{//实现清除的处理
    12     private static final Cleaner CLEANER=Cleaner.create();
    13     //创建一个清除处理
    14     private Member member;
    15     private Cleaner.Cleanable cleanable;
    16     public MemberCleaning(){
    17         this.member=new Member();//创建新对象
    18         this.cleanable=this.CLEANER.register(this,this.member);
    19         //注册使用的对象
    20     }
    21     @Override
    22     public void close() throws Exception {
    23         this.cleanable.clean();//启动多线程
    24     }
    25 }
    26 public class Main {
    27     public static void main(String[] args) throws Exception{
    28         try(MemberCleaning mc=new MemberCleaning()) {
    29             ;
    30         }catch (Exception e){
    31             e.printStackTrace();
    32         }
    33     }
    34 }

      在新一代的清除回收处理过程之中,更多情况下考虑的是多线程的使用,即:为了防止有可能造成的延迟处理,所以许多对象回收前的处理都是单独通过一个线程完成的。  但是从JDK1.9开始,这个操作已经不建议使用了,而对于对象的回收释放。从JDK1.9开始建议开发者使用AutoCloseable或者使用java.lang.ref.Cleaner类进行回收处理(Cleaner也支持有AutoCloseable处理)。

    7,对象与克隆

      所谓的对象克隆指的就是对象的复制,而且属于全新的复制。即:使用已有对象创建新对象,使用Object类中提供的clone()方法。

      所有的类都会继承Object父类,所以所有的类都一定会有clone()方法,但是并不是所有的类都希望被克隆。所以如果想要实现对象克隆,那么对象所在的类需要实现一个Cloneable接口,此接口没有任何方法提供,是因为它描述的是一种能力。

      备注:接口的作用①标准;②能力(接口没有方法是一种能力标识的接口)

      ·范例:实现对象克隆

     1 class Member implements Cloneable{//clone是一个protected权限方法
     2     private String name;
     3     private int age;
     4     public Member(String name, int age) {
     5         this.name = name;
     6         this.age = age;
     7     }
     8     @Override
     9     public String toString() {
    10         return "【"+super.toString()+"】name="+this.name+",age="+this.age;
    11     }
    12     @Override
    13     public Object clone() throws CloneNotSupportedException {
    14         return super.clone();//覆写clone方法,调用父类方法,更改权限
    15     }
    16 }
    17 public class Main {
    18     public static void main(String[] args) throws CloneNotSupportedException{
    19         Member memberA=new Member("万雨",25);
    20         Member memberB=(Member) memberA.clone();
    21         System.out.println(memberA.toString());
    22         System.out.println(memberB.toString());
    23     }
    24 }

      如果在开发之中不是非常特别的需求下,很少会出现对象克隆的需求。

  • 相关阅读:
    Ceph中的容量计算与管理
    Ceph Monitor基础架构与模块详解
    Ceph:pg peering过程分析
    API调用过程
    Windows内核—保护模式
    逆向笔记——C、C++对应的汇编结构(一)
    2020年内网渗透培训:红队攻防
    2020年 初级渗透工程师【Web安全方向】
    渗透测试【网络安全】入门指南【20190607】
    渗透学习问题【一】遇到坑需要停下来补吗
  • 原文地址:https://www.cnblogs.com/Mufasa/p/11140744.html
Copyright © 2020-2023  润新知