您的位置:首页 > 编程语言 > Java开发

史上最全讲解: JAVA中的单例模式,内部类与异常

2020-01-15 11:42 363 查看

史上最全讲解: JAVA中的单例模式,内部类与异常

文章目录

  • 工厂模式
  • 代理模式
  • 内部类
  • Lambda表达式
  • 异常Exception

  • 设计模式共有23种设计模式,是前辈对代码开发经验的总结.不仅仅Java,其它面向对象语言也有.

    单例模式

    单例模式是保证类只存在一个对象.实现方式主要有懒汉式与饿汉式.

    懒汉模式

    懒汉式:调用功能的时候才创建对象.

    package com.shsxt.single02;
    
    public class SingleLazy {
    //1私有的静态的类属性
    private static SingleLazy single = null;
    //2.空构造方法
    public SingleLazy(){
    
    }
    //3.公共的访问方式 公共的静态的上锁的返回值为SingleLazy的方法
    public static synchronized SingleLazy getInstance() {
    if(SingleLazy.single==null){
    SingleLazy.single = new SingleLazy();
    }
    return SingleLazy.single;
    }
    }

    饿汉模式

    类第一次加载完成之后就创建对象.

    package com.shsxt.single02;
    //饿汉模式 线程安全
    public class SingleHungry {
    //类一加载完就创建对象
    private static SingleHungry single = new SingleHungry();
    //空构造
    public SingleHungry(){
    
    }
    //公共的访问方式 静态方法 返回一个SingleHungry类型的对象single
    public static SingleHungry getInstance (){
    return single;
    }
    }

    二者优缺点

    懒汉式:线程不安全(多个线程操作同一份资源的时候 有可能会出现线程不安全)
    饿汉式:线程安全

    工厂模式

    工厂去创建对象用户拿去用

    代理模式

    为其他对象提供一种代理以控制对这个对象的访问

    • 注意:真实角色需要与代理角色实现相同的接口,代理需要持有真实角色的引用
    • 好处:减少与真实角色的交流,提高代码的安全性,解耦,便于后期维护,代理角色可以扩展功能
    • 实例: 项目经理与HR招聘的过程中,项目经理需要将部分功能交于HR
    package com.shsxt.single01;
    
    public class StaticPolxy {
    public static void main(String[] args) {
    Manager manager = new Manager();//招聘经理创建好了把地址值传给HR
    //HR找到对应的地址值才可以.
    HR hr = new HR(manager);
    hr.recruit();
    }
    }
    
    interface Recruitment{
    public void recruit();
    }
    
    class Manager implements Recruitment{
    
    @Override
    public void recruit() {
    System.out.println("录用");
    
    }
    
    }
    
    class HR implements Recruitment{
    Manager manager;//定义一个Manager类型的manager参数
    //先有项目经理后有HR
    //将manager定义为一个成员属性传给recruit方法
    //也可以定义为recruit方法的一个参数传进来
    //但是重写不可以 接口里的方法没有参数
    public HR(Manager manager){
    super();
    this.manager = manager;
    }
    @Override
    public void recruit() {
    System.out.println("招聘");
    manager.recruit();
    //用到了Manager里的方法
    
    }
    
    }

    内部类

    类中定义的类,当一个类中的成员也是另外一个事务的时候(汽车的发动机,人的心脏器官),这个事务就可以使用内部类定义

    成员内部类

    • 定义:内部类处于外部类的成员位置,是外部类的成员就可以使用成员修饰符,是一个类就有类的特性,可以继承父类,可以实现接口.
    • 注意:
      1.内部类中可以使用外部类中的所有内容,包括私有的
      2.静态内部类以外的其它内部类不可以定义静态的内容,除了静态的常量
      3.外部类中使用内部类的成员,通过内部类的对象
    public class Outer01 {
    private int a=5; //成员变量
    
    String haha="123";
    
    //内部类
    public class Inner extends A{
    int b=3; //内部类中的成员变量
    static final int c=10;
    
    String haha="456";
    
    public void inner(){
    
    String haha="789";
    
    System.out.println("我是内部类中的成员方法");
    System.out.println(b);
    System.out.println(a);
    
    //局部haha
    System.out.println(haha);
    //内部类成员haha
    System.out.println(this.haha);
    //外部类成员haha
    System.out.println(Outer01.this.haha);
    }
    }
    //外部类中的成员方法
    void outer(){
    //内部类对象
    Inner in=new Inner();
    System.out.println(in.b);
    }
    }
    class A{}
    //另外一个java文件
    package com.shsxt.inner03;
    
    /*
    * 内部类测试类
    */
    public class Test {
    public static void main(String[] args) {
    //成员内部类依赖于外部类的对象使用
    //创建成员内部类对象1
    Outer01 out=new Outer01();
    //Inner in=out.new Inner();
    Outer01.Inner in=out.new Inner();
    System.out.println(in.b);
    in.inner();
    //创建成员内部类对象2
    Outer01.Inner in2=new Outer01().new Inner();
    }
    }

    静态内部类

    • 定义:成员内部类一旦被静态修饰符static修饰,就是静态内部类.
    • 注意:
      1.如果在外部类中使用静态内部类的成员,需要跟随内部类对象使用,如果使用静态内部类中的内容直接类名.调用
      2.如果在静态内部类中使用外部的成员,都要跟随外部对象使用,如果使用静态内容,在内部类中可以直接使用
    public class Outer02 {
    private int a=5;
    private static int b=10;
    //静态内部类
    static class Inner{
    String name="zhangsan";
    static int age=15;
    
    void test1(){
    System.out.println("内部类中的成员方法");
    System.out.println(name);
    System.out.println(age);
    Outer02 out=new Outer02();
    System.out.println(out.a);
    System.out.println(b);
    }
    }
    
    void outer(){
    System.out.println(Inner.age);
    Inner in=new Inner();
    System.out.println(in.name);
    in.test1();
    }
    }

    私有内部类

    • 定义:成员内部类一旦被私有修饰符private修饰就是私有内部类.
    • 注意:
      1.私有内部类只能在当前所定义的外部类中使用,其他类无法使用
      2.在外部类中通过内部类的对象使用内部类的内容,保护私有内容
    public class Outer03 {
    private int a=5;
    //私有内部类
    private class Inner{
    private int b=10;
    
    void inner(){
    System.out.println(a);
    System.out.println(b);
    }
    }
    
    void outer(){
    Inner is=new Inner();
    System.out.println(is.b);
    }
    }

    局部内部类

    • 定义:定义在一个类中的方法当中的类.局部内部类只能在当前定义的方法中使用,外部类中的其他方法无法使用局部内部类.
    • 注意:
      局部内部类中使用当前所在类中的参数时,参数默认被final修饰,在局部内部类中使用不能修改参数的值
    public class Outer04 {
    String name="lisi";
    void test(int i){
    //局部变量
    int a=10;
    //局部内不类
    class Inner{
    void inner(){
    System.out.println(a);
    System.out.println(name);
    
    System.out.println(i);
    }
    }
    //方法中通过内部类的对象使用成员
    new Inner().inner();
    }
    void outer(){
    //new Inner().inner();
    }
    }

    匿名内部类

    • 定义: 如果某个类单纯只是为了实现某个接口(重写某个抽象方法)的实现类.而本身没有自己的作用,这时候可以使用匿名内部类
    package com.shsxt.inner03;
    
    public class Anonymous {
    public static void main(String[] args) {
    //接口的匿名对象调用其中的一个方法
    new Study(){
    
    @Override
    public void study() {
    System.out.println("好好学习");
    
    }
    
    @Override
    public void sleep() {
    System.out.println("好好睡觉");
    }
    
    }.study();
    //匿名对象调用很多方法
    Study s = new Study(){
    
    @Override
    public void study() {
    System.out.println("好好学习");
    
    }
    
    @Override
    public void sleep() {
    System.out.println("好好睡觉");
    
    }
    
    };
    s.study();
    s.sleep();
    
    new Anonymous().test(new Study(){
    
    @Override
    public void study() {
    System.out.println("好好学习");
    
    }
    
    @Override
    public void sleep() {
    System.out.println("好好睡觉");
    
    }
    
    });
    new Anonymous().test(s);
    }
    void test(Study s){
    s.study();
    s.sleep();
    }
    
    }
    
    interface Study{
    void study();
    void sleep();
    }

    Lambda表达式

    • 作用:用来简化匿名内部类
    • 前提:函数式接口(只有一个抽象方法的接口),修饰符@FunctionalInterface
    • 语法格式:
        () -> {}
        ()抽象方法的参数列表
        ->箭头函数或者参数列表,具有上下文推导的作用
        {}抽象方法的方法题;
    • 注意:
      1.lamdba表达式最全写法不要忘记{}后的分号
      2.如果方法体只有一句,可以省略花括号{};
      3.如果抽象方法有参数,参数类型可以省略
      4,抽象方法的参数只有一个,()可以省略
      5.如果与具体只有一句,是return的话,前后{}与return关键字可以一起省略
    package com.shsxt.inner03;
    
    public class Lambda04 {
    public static void main(String[] args) {
    new Sleep(){
    
    @Override
    public int sleep(int a) {
    System.out.println("好好睡觉");
    return 1;
    
    }
    
    }.sleep(1);
    
    Sleep s= (a) -> {
    System.out.println("好好睡觉");
    return 1;
    };
    
    s = (a)->{System.out.println("好好睡觉");
    return 1;};
    
    Eat e = (a)-> 0;
    System.out.println(e.eat(1));
    
    }
    
    }
    
    @FunctionalInterface
    interface Sleep{
    int sleep(int a);
    }
    @FunctionalInterface
    interface Eat{
    int eat(int a);
    }

    异常Exception

    在java中,异常与错误是两个不同的概念,throwable分为exception和error.错误error一般是由虚拟机产生的,不需要关注.异常分为编译异常和运行异常.throw制造异常, throw new NullPointerException();

    编译异常 CheckedException

    出现不处理程序无法执行,一般有两种处理方式

    • throws抛出异常 把异常抛给上一层,谁用谁处理
    • try…catch(){}捕获异常
      格式:
    try..catch(){}
    * 		try{
    * 			可能会出现异常的代码
    * 		}catch(FileNotFoundException e){
    * 			执行...
    *
    * 		}catch(NullpointerException e){
    * 			执行...
    *
    * 		}catch(Exception e){
    * 			接盘侠
    * 		}
    * 			....
    * 		 fially{
    * 			无论是否会出现异常,都会执行的代码
    * 		}
    • 注意:
      1.一个try后可以跟多个catch
      2.如果try中的代码没有出现异常,正常执行完毕,执行finally中的内容结束
      3.如果try中出现异常,下面的代码不会执行,直接进入对应的catch中
      4.finally无论是否出现异常,都会执行的代码
    public class ExceptionDemo02 {
    public static void main(String[] args) {
    try {
    System.out.println("try开始了");
    test();
    System.out.println(5/0);
    System.out.println("try结束了");
    } catch (FileNotFoundException e) {
    e.printStackTrace();
    } catch(ArithmeticException e){
    System.out.println("出现数学异常了");
    } catch(Exception e){
    e.printStackTrace();
    } finally{
    System.out.println("最后的最后我们都会狗带...");
    }
    }
    
    static void test() throws FileNotFoundException{
    //对象是异常的形式出现
    //throw new NullPointerException();
    
    InputStream is=new FileInputStream("D:/test.txt");
    }
    }

    常见的异常Exception

    1.空指针异常

    • 2.数组越界异常IndexOutOfBoundryException
    • 3.数学异常 ArithmeticException
    • 4.类型转换异常 ClassCastException
    • 5.数组长度负数异常 NegativeArraySizeException
    • 6.数学转换异常 NumberFormatException
    • 7.空指针异常 NullPointerException

    自定义异常

    • 自定义异常类步骤
      1.继承java.lang.Exception声明自己是异常类
      2.方法的适当语句制造异常 throw
      3.在方法声明部分用throws语句声明该方法可能抛出异常
      4.调用该方法的时候用try catch语句捕获异常
      自定义异常可以更好地提示发生的异常是什么,更加灵活!
    • 实例
    package com.shsxt.definedexception;
    
    public class DefinedException02 {
    public static void main(String[] args) {
    try {
    Users users = new Users("111");
    System.out.println(111222);
    } catch (MyException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }finally{
    System.out.println("我是finally");
    }
    }
    }
    
    class Users {
    //private String name;
    private String password;
    
    public String getPassword() {
    return password;
    }
    public Users() {
    super();
    }
    public Users(String password) throws MyException {
    if("111".equals(password)){
    throw new MyException("密码错误,请重新输入,谢谢!");
    }
    this.password = password;
    }
    }
    
    class MyException extends Exception {
    private String msg;
    public String getPassword() {
    return msg;
    }
    
    public void setPassword(String msg) {
    this.msg = msg;
    }
    
    public MyException() {
    super();
    }
    public MyException(String msg) {
    super(msg);
    this.msg = msg;
    }
    }
    • 点赞
    • 收藏
    • 分享
    • 文章举报
    hulincup 发布了21 篇原创文章 · 获赞 4 · 访问量 321 私信 关注
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: