常见的其他对象

1—Object

  • Object是所有类的根类,称为上帝类。
    该类中定义的是所有对象都具备的功能。
    所有类都继承这个方法。相当于class Demo extends Object.
    所有对象都实现这个类的方法。

  • Object类中常见方法

    boolean obj.equals(Object oo);  //比较两个对象是否是同一个对象。
    Class<> obj.getClass();         //获取该Object的运行时类。
    int obj.hashCode();             //获取该对象的哈希值。
    String obj.toString();          //返回该对象的字符串表示形式,一般是引用。
    
    void wait();                    //当前对象线程等待。
    void wait(long time);           //当前对象线程等待指定时间。
    void notify();                  //唤醒在该对象上等待的线程。
    void notifyAll();               //唤醒所有等待线程。
    
  • Object类中定义的都是所有类都应该具有的功能,如比较功能,转为字符串功能,求哈希值等。
    但是有时候对象只是引用,这时候最好不直接比较引用是否相等,而是由子类复写该方法,以达到比较内容的目的。

  • 举例:

    class Demo  // extends Object
    {
        private int num;
        Demo(int num)
        {
            this.num=num;
        }
        public boolean equals(Object oo)//复写时,参数必须是Object类型。
        {
            if (!(oo instanceof Demo))  //判断是否是同一类型对象,如果不是,不用比较。
                return false;
            Demo d=(Demo)oo;            //对象类型从Object类型向下转型,以便于比较内容。
            return this.num==d.num;
        }
    }
    class Object Demo
    {
        public static void main(String [] args)
        {
            Demo d1=new Demo(2);
            Demo d2=new Demo(2);
            System.out.println(d1.equals(d2));//Demo类复写了Object 类中的equals方法,用于比较内容。
        }
    }
    

2—package

  1. package特点

    写在程序文件代码的第一行。
    包名的所有字母小写。
    它是一种封装形式。

    带包的类文件在编译时,要在javac前加参数。
    如,

    javac -d . packageDemo.java。
    //-d 是指目录,目录中存放编译后的class文件;文件夹名为类文件中package 后的名称。
    

    运行时写

        java pack.packageDemo 。
    

    一个项目是由很多类组成。加上package可以分类文件。
    所以包的出现可以让类文件和源文件相分离。方便多机使用,只要copy类文件就行。

    修饰符权限问题表:

              public    protected   default   private
    同一类中      OK         OK         OK        OK
    同一包中      OK         OK         OK
     子类中       OK         OK
     不同包中     OK
    

    举例::
    A类:

    package packa;
    public class A
    {
        public static void main(String [] args)
        {
            packb.A a=new packb.A();//调用另一个带包的类中的方法,类名前需要加包名。
            a.show();
        }
    }
    

    B类:

    package packb;
    protected class B
    {
        public void show()
        {
            System.out.println("show");
        }
    }
    

    C类:

    package packc;
    public class C extends packb.B  //C类继承了B类,所以可以使用被protected修饰的B类。
    {
        public void run()
        {
            System.out.println("run");
            show();                 //调用继承过来的show()方法。
        }
    }
    

    注意:
    (1)调用一个包中的类和方法时,必须要有足够大的权限,所以类和方法都要被 public 修饰。
    (2)被调用的包需要先生成class文件,并且需要设置 classpath 告诉虚拟机去哪里找这个类文件所在的包。
    (3)C类继承了B类,所以C可以访问B中的protected修饰的show方法,而A类不继承B类,所以不能访问B类中方法。
    (4)这就是 protected 的作用:只能是它的子类才可以使用它的内容。
    (5)源文件中如果不写package的话,会直接在指定目录生成class文件,而不是先创建文件夹。

  2. import:导包

    import紧接package下一代码行写。

    对于多层包目录: pack.aa.bb.cc;
    它在 new 对象时,要写成

    pack.aa.bb.cc.Demo d = new pack.aa.bb.cc.Demo();
    

    为了简化书写,所以可以导包:

     import pack.hahaha.haha.ha.Demo.class 。
    

    简化之后,代码可以写成 :

    Demo d=new Demo();
    

    如果要导入的类文件比较多的话,可以用*代替类文件名,导入目录中所有的类文件,如:

    import java.aa.bb.cc.*;
    

    注意:
    (1)如果导入包之后有重复类,必须要声明是哪个包中的。
    (2)不同包中的类同名时,调用时类必须加包名。

    import导入的是包中的类,形式如:

        C:\class\pack\aaa\Demo1.class
        C:\class\pack\aaa\bb\c\Demo2.class
    

    如果导入 import pack.aaa.*; 则只导入了Demo1.class。
    import pack.aaa.bb.c.*; 才能导入 Demo2.class。
    建议不写*通配符,易占用内存空间。

  3. jar : 压缩包

    jar包可以将一个文件夹下的多个文件夹压缩成一个后缀为.jar的包。
    如:
    将c:\class 文件夹下的packa,packb文件夹用jar工具压缩成packab包。
    (1)先切换目录到c:\class下;
    (2)压缩命令 : jar -cf packab.jar packa packb
    会在下生成一个packab.jar de 压缩文件。
    (3)查看jar包的归档信息:jar -tf packab.jar
    (4)导出文字较多的信息:jar -tf packab.jar >c:\class\123.txt
    会在c:\class 下生成123.txt,包含详细的归档信息(数据重定向)。

    jar中的常用关键字

     -c  创建新档案
     -t  列出档案目录
     -x  从档案中提取指定的 (或所有) 文件
     -v  在标准输出中生成详细输出
     -f  指定档案文件名
     -m  包含指定清单文件中的清单信息
     -C  更改为指定的目录并包含以下文件
    

    对于jar包中的文件,可以直接java命令执行。
    如:jar包中的 packa\Demo.class
    可以直接调用命令 java packa.Demo 运行。

3—Exception

  • 异常就是程序在运行时出现不正常情况。或者说是对不正常情况进行描述后的对象体现。
    java中把异常通过java的类的形式进行描述,并封装成对象。

    异常把问题划分成两部分:
    1.严重的问题。
    java中通过Error类进行描述。对于Error一般不编写针对性的代码对其进行处理。
    2.不严重的问题。
    java中通过Exception类进行描述。对于Exception可以使用针对性处理方式进行处理。

  • 异常的格式

    try
    {
        需要被检测的代码;
    }
    catch(异常类  异常变量)
    {
        处理异常的代码;
    }
    finally
    {
        一定会执行的语句;//一般是关闭资源的代码。
    }
    

    注意:
    (1)finally 只有一种情况是执行不到的,就是前面执行到了 System.exit(0);表示JVM系统退出。
    (2)finally{} 和 catch{}只能有一个可以省略不写, try 必须写。
    (3)catch 的前面必须是 try{},finally 的前面也是要紧跟 try{}或者 catch(){}。
    (4)try语句中,程序一旦发生异常,就不再继续执行而是直接跳转到catch语句中。

  • Exception常见子类关系图:

    ClassNotFoundException    类未找到异常
    DataFormatException       数据格式异常
    InterruptedException      中断异常
    IOException               IO流异常
    NoSuchMethodException     无此方法异常
    SQLException              数据库异常
    TimeoutException          超时异常
    
    RuntimeException          运行时异常     
        |---- ArithmeticException           数学运算异常
        |----   ClassCastException          类型转换异常
        |----   IllegalArgumentException    无效参数异常
        |----   IllegalStateException       无效状态异常
        |---- NullPointerException          空指针异常
    
        |----   IndexOutOfBoundsException   角标越界异常
              |---- ArrayIndexOutOfBoundsException  数组角标越界异常
              |---- StringIndexOutOfBoundsException 字符串角标越界异常
    
  • Throwable是java语言中所有错误或异常的超类
    Throwable 常用方法有:

    String getMessage()       返回此Throwable 的详细信息字符串。
     void  printStackTrace()  将此错误及其追踪打印出来。
    String toString()         返回错误信息的简短描述。
    

    而Exception中没有特有的方法,它从Throwable继承的常用方法有:

    String  getMessage();       //返回异常信息。
    String  toString();         //返回异常名称和异常信息。
    void    printStackTrace();  //打印异常名称、异常信息、异常位置。
    

    举例

    try
    {
        int x=4/0;
    }
    catch
    {
        System.out.println(e.getMessage()); //获取异常信息。
        System.out.println(e.toString());   //异常名称+异常信息。
        e.printStackTrace();                //异常名称+异常信息+异常位置
        //JVM默认的异常处理机制,就是在调用printStackTrace()方法,打印异常的堆栈跟踪信息。 
    }
    finally
    {
        System.out.println("over!");
    }
    
  • throws:异常的声明。
    如果功能在运行时有可能出现异常,就需要声明异常,或者抛出异常,否则编译失败。

    函数内如果抛出的是RuntimeException以及它的子类,函数上不用声明。因为一旦出现异常程序会直接停掉。
    其他的都要在函数上声明throws。

    如果在函数内抛出RuntimeException异常,函数上不声明,编译一样通过。
    如果在函数上声明了RuntimeException异常,调用者可以不用处理异常,编译一样通过。

    不需要声明的原因:
    在运行时,出现了RuntimeException运行时异常,就是无法运算的情况,这时候希望程序停止。所以不需要调用者处理。

    自定义异常时,如果该异常发生后无法再继续运算,就让该自定义异常继承RuntimeException。

  • 多异常的处理。
    (1)多个异常可以用多个catch()处理。
    (2)异常抛出时,多个异常用逗号隔开。throws x1,x2
    (3)程序如果有指定异常以外的异常,就该终止程序运行,即让JVM自动默认处理异常。

    举例

    class DivDemo
    {
        int div(int a,int b) throws ArithmeticException,ArrayIndexOutOfBoundsException
        {
            int [] arr=new int [a];
            System.out.println(arr[4]);
            return a/b;
        }
    }
    class Demo
    {
        public static void main(String [] args)
        {
            DivDemo d=new DivDemo();
            try 
            {
                int x=d.div(4,0);       
                System.out.println("x="+x);
            }
            catch (ArrayIndexOutOfBoundsException e) //第一个参数小于5时,这里就会捕捉此异常。
            {
                System.out.println("角标越界异常:"+e.toString());
            }
            catch (ArithmeticException e)            //第二个参数为 0 时,这里就会捕捉此异常。
            {
                System.out.println("运算方法异常:"+e.toString());
            }
            System.out.println("over!");
        }
    }
    

    注意:
    (1)声明了几个异常,就对应几个catch块,不要定义多余的catch块。
    (2)多异常不会同时发生。第一个异常发生时,函数已经结束。
    (3)多个catch()块如果有继承关系,父类的catch要放在最下面。

  • 自定义异常:
    对于项目中出现的特有问题,可以按照java对问题封装的思想,进行自定义的异常封装。
    函数中如果抛出自定义异常,就必须要给其定义处理动作。因为JVM中没有自定义异常的默认处理方式。

    自定义异常打印的结果中只有异常的名称,没有异常的信息。因为没有定义信息。

    自定义异常必须是自定义类继承Exception,原因:
    –异常体系有一个特点,异常类和异常对象都被抛出,都具有可抛性。
    而可抛性是Throwable体系中独有的特点,只有这个体系中的类和对象才可以被throw和throws操作。

  • throw和throws的区别
    throws使用在函数上,throw使用在函数内。
    throws后面跟的是异常类,可以跟多个,用逗号隔开。
    throw后跟的是异常对象。

    举例:

    class FushuException extends Exception //自定义异常格式。
    {
        FushuException(String message)      
        {
            super(message);                //自定义异常调用父类带参数构造函数。
        }   
    }
    class DivDemo   
    {
        int div(int a,int b) throws FushuException  //抛自定义异常。
        {
            if (b<0)
                throw new FushuException("不能是负数");  //手动通过throw关键字抛出一个自定义异常对象。
            return a/b;
        }
    }
    class Demo
    {
        public static void main(String [] args)
        {
            DivDemo d=new DivDemo();
            try
            {
                int x=d.div(4,-1);          //b=-1时,就开始处理FushuException异常了。
                System.out.println("x="+x);
            }
            catch (FushuException e)
            {
                System.out.println(e.toString());//toString()包含getMessage()方法,返回的是传入的message的值。
            }
            System.out.println("over!");
        }
    }
    
  • 子父类覆盖时的异常特点:
    1.子类覆盖父类时,如果父类的方法抛出异常,那么子类的覆盖方法只能抛出父类的异常或者该异常的子类。或者不抛。
    2.如果父类方法抛出多个异常,那么子类在覆盖该方法时,只能抛出父类异常的子集。
    3.如果父类或者接口的方法中没有异常抛出,子类在覆盖方法时发生异常,必须try处理,不可以抛出异常。

  • 异常的处理原则:
    1.两种处理方式:try和throws。
    2.定义到抛出异常的功能时,抛出几个,就处理几个。
    3.多个catch时,父类的catch放到最下面。
    4.catch内要定义针对性的处理方式。不是简单的printStackTrace和输出语句,也不要不写。
    5.捕获的异常本功能处理不了时,可以继续抛出。相当于嵌套式异常格式。

4—Runtime

  • Runtime 对象类没有构造函数,说明不可以 new 对象。
    –该类中大都是非静态方法,所以该类肯定提供了静态方法返回一个本类对象。
    由此可以看出该类使用了单例设计模式。

    Runtime 常用方法

    static Runtime getRuntime() //调用静态方法返回一个Runtime对象。
    Process exec(String cmd)    //在单独的进程中执行指定的指令
    long freeMemory()           //返回虚拟机的空闲内存量。
    

    举例:

    class Demo
    {
        public static void main(String [] args) throws Exception 
        {
            Runtime rt=Runtime.getRuntime();  //Runtime不可以 new 对象,只能这样写生成一个单例对象。
            Process p=rt.exec("notepad.exe"); //exec()返回的是一个本机进程Process。
            //也可以不加路径,系统会在当前目录下查找,还回去系统path环境变量里找。
    
            Thread.sleep(4000);     //线程等待4000毫秒。
            p.destroy();            //销毁进程。
        }
    }
    

5—System

  • System包含一些有用的类字段和常用方法。其中的方法和属性都是静态的。
    它不能被实例化。

  • 常见方法:

    System.in           //标准输入流,一般用于获取键盘录入
    System.out          //标准输出流,用于输出信息
    System.err          //标准错误流,此输出流用于显示错误消息
    
    void System.exit(); //终止java虚拟机。
    void System.gc();   //运行垃圾回收器。
    long System.currentTimeMillis();    //返回以毫秒为单位的当前时间。
    
    Properties System.getProperties();  //确定当前系统属性。
    static String System.getProperty(String key);
    

    **说明:**Properties 是HashTable的子类,也就是Map集合的子类对象,可以通过Map的方法取出元素。

  • 举例:

    import java.util.*;
    class Demo
    {
        public static void main(String [] args)
        {
            Properties pro=System.getProperties();
            for (Object oo : pro.keySet())
            {
                String value = (String)pro.get(oo);
    
                System.out.println(oo+"::"+value); 
                //可以通过Map的方法打印系统属性的键值和值。
            }
                        System.out.println(System.getProperty("os.name"));
    //打印系统名称
                    System.out.println(System.getProperty("user.country"));
    //国家名
                    System.out.println(System.getProperty("user.name"));            //系统管理员名称
                    System.out.println(System.getProperty("user.language"));
    //用户语言
    
    System.out.println(System.getProperty("haha"));
    //计算机中没有haha对应的键值信息,可以动态加载属性信息。
    //运行时通过java -Dhaha=qqqqq Demo 的形式传递一个键值信息。
        }
    }

6—Date & Calendar

  1. Date表示特定的瞬间,精确到毫秒。
    Date 表示的时间是1970 年 1 月 1 日 00:00:00 GMT(林威治标准时)到现在的毫秒数.
    形式如:Tue May 12 21:26:31 CST 2015。

    import java.util.*;
    class Demo
    {
        public static void main(String [] args)
        {
            Date d=new Date();
            System.out.println(d);//格式如:Tue May 12 21:26:31 CST 2015
        }
    }
    

    由于表示的不直观,所以需要用 SimpleDateFormat 对其进行格式化。
    通过SimpleDateFormat 的构造函数 SimpleDateFormat(String s)
    这里s表示一种模式,其中的元素有:

    yyyy :  2015 (年)  yy : 15 (年) 
    MM : 05 (月)      MMM : 五月
    dd: 16 (日)        DD:年中的天数  
    E : 星期六
    HH:时
    mm:分        
    ss:秒            SSS : 毫秒数
    z:时区-CST          Z:时区-+0800
    a:Am/Pm标记
    w:年终的周数         W:月份中的周数
    F:月份中的星期
    

    如:表示公元2015年5月16日下午1点30分 东八区
    表示为:

    "G yyyy.MM.dd  E 'at' a HH:mm:ss z"  //公元 2015.05.16 星期六 at 下午 13:30:00 CST
    "G yyyy年MMMdd日 E ,a HH时mm分ss秒 Z" //公元 2015年05月16日 星期六 , 下午 13时30分00秒 +0800
    

    举例:

    import java.util.*; //导入Date包。
    import java.text.*; //导入SimpleDateFormat包。
    class Demo
    {
        public static void main(String [] args)
        {
            Date d=new Date();  
            SimpleDateFormat f=new SimpleDateFormat("yyyy年MM月dd日"); //创建一个日期模式
    
            String time=f.format(d);
            System.out.println(time);
        }
    }
    
  2. Calendar
    –如果想单独获取Date中的某个值,要用到 Calendar 类。
    Calendar是一个抽象类,可以通过 getInstance 方法返回一个 Calendar 对象:

    Calendar now =Calendar.getInstance();
    

    Calendar有很多字段,可以通过get方法获取字段。

    ca.get(Calendar.YEAR);        //返回日历中的年份
    ca.get(Calendar.MONTH);       //返回日历中的月份,0月表示实际中的1月份。
    ca.get(Calendar.DAY_OF_MONTH);//返回月中的第几天
    ca.get(Calendar.DAY_OF_WEEK); //返回一周中的第几天,第一天表示星期日。
    ca.get(Calendar.HOUR_OF_DAY); //一天中的小时数
    ca.get(Calendar.MINUTE);      //多少分钟
    ca.get(Calendar.SECOND);      //多少秒
    

    Calendar 中的常用方法

    void   ca.add(field,amount);    //给字段自增值
    int    ca.get(field);           //获得字段值
    String ca.toString();           //返回字符串表示形式
    void   ca.set(field,amount);    //将给定字段设置为给定值 
    void   ca.set(year,month,date); //设置年月日
    TimeZone ca.getTimeZone();      //获得时区
    

    举例:

    import java.util.*;
    class Demo
    {
        public static void main(String [] args)
        {
            Calendar ca=Calendar.getInstance();
            ca.set(2020,2,1);           //设置指定年月日
    System.out.println(ca.get(Calendar.YEAR)+"年");
    System.out.println(ca.get(Calendar.MONTH)+1+"月");
                    System.out.println(ca.get(Calendar.DAY_OF_MONTH)+"日");
    
            ca.add(Calendar.YEAR,2);
            ca.add(Calendar.MONTH,2);   //时间是连续的,可以加减到上一年或下一年
            ca.add(Calendar.DAY_OF_MONTH,-1);
                System.out.println(ca.get(Calendar.YEAR)+"年");
                System.out.println(ca.get(Calendar.MONTH)+1+"月");
                System.out.println(ca.get(Calendar.DAY_OF_MONTH)+"日");
    
            }
        }

    注意:求日历中的星期几,最好用查表法。
    Calendar 在设置月份的时候,设置的1月,其实表示的是2月。

7—Math & Random

  1. Math
    它包含执行基本数学运算的方法。

    Math 中常见方法:

    static T  abs(n);   //返回绝对值。n只可以是double,float,int,long。
    static T  max(n);   //返回较大值。n只可以是double,float,int,long。
    static T  min(n);   //返回较小值。n只可以是double,float,int,long。
    
    static double random();         //返回随机值,介于0-1之间。包含头不包含尾。
    static long  round(double d);   //返回d的四舍五入的long值。
    static int  round(float f);     //返回f的四舍五入的int值。
    
    static double ceil(double d);           //返回大于d的最小的double值。ceil可以当做是天花板的意思。
    static double floor(double d);          //返回小于d的最大的double值。floor可以当做是地板的意思。 
    static double cbrt(double d);           //返回d的立方根。
    static double sqrt(double d);           //返回d的平方根。
    static double hypot(double x,y);        //返回x和y的平方和的平方根。相当于求直角三角形的斜边。
    static double pow(double x,y);          //返回x的y次方的值。
    

    举例:

    class Demo
    {
        public static void main(String [] args)
        {
            double d1=Math.ceil(5.6);
            double d2=Math.ceil(5.4);
            long L=Math.round(5.6);
            System.out.println(d1); //d的进位 double值。小数位只要大于0.0,整数位就进1 。
            System.out.println(d2); //d的舍位 double值。小数位不管是多少都舍弃。
            System.out.println(L);  //L的四舍五入值。
    
            random(6,10);           //用随机数生成10次骰子的点数。
            random(10,10);          //用随机数生成10次打靶命中分数。
            random(100,10);         //用随机数生成10个学生考试分数。
        }
        public static void random(int n,int time)
        {
            for (int x=0;x<time;x++)
            {
                double d=Math.random(); //生成一个介于0-1的随机小数
                int i=(int)(d*n+1);     //小数转整数,整数范围在1-100之间。
                System.out.println(i);
            }
        }
    }
    
  2. Random :
    此类用于生成随机数。
    与 Math.random() 相比,它不如 Math.random() 易用。

    常用方法:

    protected int next(int bits);       //生成下一个随机数。
              int nextInt();            //返回下一个随机整数。
              int nextInt(int n);       //返回取自0~(n-1) 的随机整数。
    

    举例:

    import java.util.*;
    class Demo
    {
        public static void main(String [] args)
        {
            Random rand=new Random();
            for (int x=0;x<10;x++)
            {
                 int n=rand.nextInt(10)+1;  //nextInt(10)返回的数不包括10.
                System.out.print(n+"    ");
            }
        }
    }
    

8—Scanner

  • Scanner是可以使用正则表达式来解析基本类型和字符串的简单文本扫描器。

    构造方法:

        Scanner(File res)
        例:Scanner scan=new Scanner(new File("aaa.txt"));
        Scanner(InputStream res)
        例:Scanner scan=new Scanner(System.in);
        Scanner(String res)
        例:Scanner scan=new Scanner("aaa");
    

    常用方法:

    scan.nextBoolean();
    scan.nextByte();
    scan.nextDouble();
    scan.nextFloat();
    scan.nextInt();
    scan.nextLong();
    scan.nextShort();
    
    Scanner.reset();    //重置此扫描器。返回Scanner。
    
  • 举例:

    import java.util.*;
    
    class Demo
    {
        public static void main(String [] args)
        {
            Scanner scan=new Scanner(System.in);//Scanner作为一个容器使用。
            System.out.println("请输入一个数字:");
            int x=scan.nextInt();
            System.out.println("你输入的是:"+x);
        }
    }
    

9—BigInteger

  • 有些运算数值超过 long 的范围,这时可以定义 BigInteger 对这样的数值进行存储并运算。

    常用方法:
    (1)字段:

        BigInteger.ONE;         //BigInteger 类型,代表1 。
        BigInteger.TEN;         //BigInteger类型,代表10。
        BigInteger.ZERO;        //BigInteger 类型,代表0 。
    

    (2)构造方法:

        BigInteger(String s);   //将s表示成BigInteger形式。
    

    (3)方法:

        BigInteger bi.abs();                 //返回BigInteger的绝对值
        BigInteger bi.add(BigInteger val);   //返回 (bi + val) 的结果
        BigInteger bi.and(BigInteger val);   //返回 (bi & val) 的结果
        BigInteger bi.divide(BigInteger val);//返回 (bi / val) 的结果
        BigInteger bi.max(BigInteger val);   //返回 bi 与 val 的最大值
        BigInteger bi.min(BigInteger val);   //返回 bi 与 val 的最小值
        BigInteger bi.mod(BigInteger val);   //返回 (bi % val) 的结果
        BigInteger bi.multiply(BigInteger val);       //返回 (bi * val) 的结果
        static BigInteger BigInteger.valueOf(long L); //long型值转成BigInteger型
        int bi.compareTo(BigInteger val);             //bi大于val,返回1,小于返回-1,等于返回0 。
        int bi.intValue();                   //将BigInteger转成int型
        String bi.toString();                //BigInteger的字符串表示形式
    
  • 举例:

    import java.math.BigInteger;
    class Demo
    {
        public static void main(String [] args)
        {
            BigInteger bi=BigInteger.ONE;   //BigInteger.ONE 代表BigInteger类型的 1 。
            for (int x=2;x<=100;x++)
            {
                bi=bi.multiply(BigInteger.valueOf(x));  //两BigInteger相乘。
            }
            System.out.println(bi);
            System.out.println(bi.mod(BigInteger.TEN)); //打印 bi 模10 的结果。
        }
    }
    

10—单例设计模式

  • 优点: 在内存中只有一个对象,节省内存空间。
    也可以避免频繁地创建和销毁对象,避免对共享资源的多重占用,提高了性能。
    可以全局访问。
    单例设计模式有两种:
    (1)饿汉式:先初始化对象。

    class demo
        {
            private demo(){}
            private static demo x=new demo();
            public static demo getInstance()
            {
                return x;
                }
            }
    

    (2)懒汉式:方法被调用时才初始化(延时加载)。

    class demo
    {
        private static demo x=null;
        private demo(){};
        public static demo getInstance()
        {
            if (x==null)
            {   
                synchronized(demo.class)
                {   
                    if (x==null)
                        x=new demo();
                    }
                }
            }
        }
    

    注意:定义单例时,一般使用饿汉式。因为它安全。

11—模板方法设计模式

  • 定义功能时,功能的一部分是确定的。确定的部分在使用不确定的部分。将不确定的部分由子类复写。

    举例:一段获取程序运行时间的代码。

    class GetTime
    {
        public void getTime()
        {
            long start=System.currentTimeMillis();
            //返回一个long值,代表1970Y 1M 1D 开始至今的毫秒数。
    
            for (int x=0;x<1000;x++)
            //for语句部分的运行左右着时间的多少。不同程序不同运行时间。要想获取其他程序的时间就改这部分。
            {
                System.out.print(x+"    ");
            }
            long end=System.currentTimeMillis();
    
            System.out.println("TIME:"+(end-start));
            //程序开始和结束的时间相减,可以获取程序运行的时间。
        }
    }
    class Demo8
    {
        public static void main(String [] args)
        {
            GetTime gt=new GetTime();
            gt.getTime(); 
        }
    }
    

    该例可以获取一段程序的运行时间,只要替换需要求运行时间的程序,就可以求其他程序的运行时间。
    如果把这段固定的程序封装成模板,就可以解决一类问题。
    这就是模板方法设计模式

  • 模板的代码抽取:

    abstract class GetTime          //模板,不能实例化。
    {
        public final void getTime() //加final修饰,防止子类把特有定义复写。
        {
            long start=System.currentTimeMillis();
            run();
            long end=System.currentTimeMillis();
            System.out.println("TIME:"+(end-start));
        }
        public abstract void run(); //模板中,这一块不一定是抽象的。
    }
    class  GTime extends GetTime    //套用模板
    {
        public void run()           //复写抽象类中的run方法,
        {
            for (int x=0;x<199;x++)
            {
                System.out.print("x="+x+"   ");
            }
        }
    }
    class Demo
    {
        public static void main(String [] args)
        {
            GTime ti=new GTime();
            ti.getTime();
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值