zoukankan      html  css  js  c++  java
  • 面向对象

    异   常

    什么是异常:异常是指在程序的运行过程中所发生的不正常的事件,它会中断运行的程序。

    异常处理通过五个关键字来实现:try、catch、finally、throw和throws

    try:执行可能产生的异常代码(try包裹整个执行的代码从头到尾)

    catch:捕获异常,根据执行条件写入相关异常类型。

    finally:无论是否发生异常,代码都能执行。

    throw:声明方法可能要 抛出的各种异常,只能用于抛出一种异常。

    throws:手动抛出异常,让调用者处理异常

    try-catch块

    在catch块中处理异常

    1.加入用户自定义处理信息

    System.err.println("出现错误:年龄不能是负数")

    2.调用方法输出异常信息

    e.printStackTrace();

    3.异常处理方法

    1.void printStackTrace()  输出异常的堆栈信息

    2.String getMessage()   返回异常信息描述字符串,是printStackTrace()输出信息的一部分

    常见的异常类型

    Exception    异常层次结构的父类

    ArithmeticException   算术错误情形,如以零作除数

    ArraylndexOutOfBoundsException   数组下标越界

    NullPointerException   尝试访问 null 对象成员

    ClassNotFoundException   不能加载所需的类

    IllegalArgumentException    方法接收到非法参数

    NumberFormatException   数字格式转换异常

    ClassCastException     对象强制类型转换出错

    多重catch块

    1.排列catch 语句的顺序:先子类后父类

    2.发生异常时按顺序逐个匹配

    3.只执行第一个与异常类型匹配的catch语句

    异常的分类

    Error:程序本身的异常,重启程序或没有解决办法。(现实中硬件出问题了,只能更换硬件)

    Exception:分为检查性异常非检查性异

    检查性异常:必须在编写代码时,使用try catch捕获。

    非检查性异:在Java中所有RuntimeException的派生类都是非检查型异常,与检查型异常对比,非检查型异常可以不在函数声明中添加throws语句,调用函数上也不需要强制处理。如果有异常产生,则异常将由JVM虚拟机进行处理。

    log4j记录日志

    日志(log)

    主要用来记录系统运行中一些重要操作信息。

    便于监视系统运行情况,帮助用户提前发现和避开可能出现的问题,或者出现问题后根据日志找到原因。

    log4j

    控制日志的输出级别。

    控制日志信息输送的目的地是控制台、文件等。

    控制每一条日志的输出格式。

    Java集合框架

    Java集合框架提供了一套性能优良、使用方便的接口和类,它们位于java.util包中

    java.util包中常用的类和接口

    1.常用接口

    (1)Collection

    Collection 层次结构 中的根接口。

    (2)Iterator

    对 collection 进行迭代的迭代器。

    (3)List

    有序的 collection(也称为序列)。

    (4)Map

    将键映射到值的对象。

    (5)Map.Entry

    映射项(键-值对)。

    (6)Set
    一个不包含重复元素的 collection。

    2.常用类

    ArrayList

    List 接口的大小可变数组的实现。

    Arrays

    此类包含用来操作数组(比如排序和搜索)的各种方法

    Collections

    此类完全由在 collection 上进行操作或返回 collection 的静态方法组成。

    Date

    类 Date 表示特定的瞬间,精确到毫秒。

    HashMap

    基于哈希表的 Map 接口的实现。

    HashSet

    此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。

    Random

    此类的实例用于生成伪随机数流。

    Timer

    一种工具,线程用其安排以后在后台线程中执行的任务。

    接口

    collection接口存储一组不唯一,无序的对象。

    List 接口存储一组不唯一,有序(插入顺序)的对象。

    Set 接口存储一组唯一,无序的对象。

    Map接口存储一组键值对象,提供key到value的映射。

    List:

    ArrayList可变数组,在内存中分配连续的空间。访问效率比较高。

    LinkedList采用链表存储方式。插入、删除(修改)元素时效率比较高

    常用方法

    LinkedList:频繁修改时,可使用LinkedList来提高效率。提供头尾元素进行添加和删除操作的方法

    使用方法:

    迭代器Iterator

    如果遇到遍历容器时,判断删除元素的情况,使用迭代器遍历。

    /*
    *迭代器遍历Set
    */
    public class Test {
        public static void main(String[] args) {
            Set<String> set = new HashSet<String>();
            for (int i = 0; i < 5; i++) {
                set.add("a" + i);
            }
            System.out.println(set);
            for (Iterator<String> iter = set.iterator(); iter.hasNext();) {
                String temp = iter.next();
                System.out.print(temp + "	");
            }
            System.out.println();
            System.out.println(set);
        }
    }

    迭代器遍历Map

    //1
    public class Test {
        public static void main(String[] args) {
            Map<String, String> map = new HashMap<String, String>();
            map.put("A", "王五");
            map.put("B", "小赛文");
            Set<Entry<String, String>> ss = map.entrySet();
            for (Iterator<Entry<String, String>> iterator = ss.iterator(); iterator.hasNext();) {
                Entry<String, String> e = iterator.next();
                System.out.println(e.getKey() + "--" + e.getValue());
            }
        }
    }
    
    //2
    public class Test {
        public static void main(String[] args) {
            Map<String, String> map = new HashMap<String, String>();
            map.put("A", "王五");
            map.put("B", "小赛");
            Set<String> ss = map.keySet();
            for (Iterator<String> iterator = ss.iterator(); iterator.hasNext();) {
                String key = iterator.next();
                System.out.println(key + "--" + map.get(key));
            }
        }
    }

    多线程

    在一般情况下,创建一个线程是不能提高程序的执行效率的,所以要创建多个线程。但是多个线程同时运行的时候可能调用线程函数,在多个线程同时对同一个内存地址进行写入,由于CPU时间调度上的问题,写入数据会被多次的覆盖,所以就要使线程同步。

    在多线程编程里面,一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数据在任何时刻,最多有一个线程访问,以保证数据的完整性。

    好处:

    1.充分利用CPU的资源

    2.简化编程模型

    3.良好的用户体验

    主线程

    1.main()方法即为主线程入口

    2.产生其他子线程的线程

    3.必须最后完成执行,因为它执行各种关闭动作

    4.终止线程

    线程:

    1. 一个进程内部的一个执行单元,它是程序中的一个单一的顺序控制流程。
    2. 一个进程可拥有多个并行的(concurrent)线程。
    3. 一个进程中的多个线程共享相同的内存单元/内存地址空间,可以访问相同的变量和对象,而且它们从同一堆中分配对象并进行通信、数据交换和同步操作。
    4. 由于线程间的通信是在同一地址空间上进行的,所以不需要额外的通信机制,这就使得通信更简便而且信息传递的速度也更快。
    5. 线程的启动、中断、消亡,消耗的资源非常少。

    继承Thread类创建线程

    public class TestThread extends Thread {  //自定义类继承Thread类
        
        public void run() {  //run()方法里是线程体
            for (int i = 0; i < 10; i++) {
                System.out.println(this.getName() + ":" + i);
    //getName()方法是返回线程名称
            }
        }
     
        public static void main(String[] args) {
            TestThread thread1 = new TestThread();   //创建线程对象
            thread1.start();   //启动线程
            TestThread thread2 = new TestThread();
            thread2.start();
        }
    }

    多个线程交替执行,线程每次执行时长由CPU决定

    Runnable接口创建线程

    1.定义MyRunnable类实现Runnable接口

    2.实现run()方法,编写线程执行体

    3.创建线程对象,调用start()方法启动线程

    public class TestThread2 implements Runnable {   //自定义类实现Runnable接口;
        public void run() {    //run()方法里是线程体;
            for (int i = 0; i < 10; i++) {
                System.out.println(Thread.currentThread().getName() + ":" + i);
            }
        }
        public static void main(String[] args) {
            //创建线程对象,把实现了Runnable接口的对象作为参数传入;
            Thread thread1 = new Thread(new TestThread2());
            thread1.start();    //启动线程;
            Thread thread2 = new Thread(new TestThread2());
            thread2.start();
        }
    }

    线程调度

    线程调度指按照特定机制为多个线程分配CPU的使用权

     线程优先级

    1.线程优先级由1~10表示,1最低,默认优先级为5

    2.优先级高的线程获得CPU资源的概率较大

    线程休眠

    让线程暂时睡眠指定时长,线程进入阻塞状态

    睡眠时间过后线程会再进入可运行状态

    public class Wait {
    public static void bySec(long s) {
        for (int i = 0; i < s; i++) {
            System.out.println(i + 1 + "秒");
            try {
                Thread.sleep(1000);    //线程休眠1秒(1秒=1000毫秒)
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
                    }
             }
    }

    线程的强制运行

    public final void join()

    public final void join(long mills)

    public final void join(long mills,int nanos)

    millis:以毫秒为单位的等待时长

    nanos:要等待的附加纳秒时长

    需处理InterruptedException异常

    死锁及解决方案

    死锁的概念

    多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能进行,而导致两个或者多个线程都在等待对方释放资源,都停止执行的情形。

    因此, 某一个同步块需要同时拥有“两个以上对象的锁”时,就可能会发生“死锁”的问题。

    “化妆线程”需要同时拥有“镜子对象”、“口红对象”才能运行同步块。那么,实际运行时,“小丫的化妆线程”拥有了“镜子对象”,“大丫的化妆线程”拥有了“口红对象”,都在互相等待对方释放资源,才能化妆。这样,两个线程就形成了互相等待,无法继续运行的“死锁状态”。(一下是百战程序员案例代码)

    class Lipstick {//口红类
     
    }
    class Mirror {//镜子类
     
    }
    class Makeup extends Thread {//化妆类继承了Thread类
        int flag;
        String girl;
        static Lipstick lipstick = new Lipstick();
        static Mirror mirror = new Mirror();
     
        @Override
        public void run() {
            // TODO Auto-generated method stub
            doMakeup();
        }
     
        void doMakeup() {
            if (flag == 0) {
                synchronized (lipstick) {//需要得到口红的“锁”;
                    System.out.println(girl + "拿着口红!");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
     
                    synchronized (mirror) {//需要得到镜子的“锁”;
                        System.out.println(girl + "拿着镜子!");
                    }
     
                }
            } else {
                synchronized (mirror) {
                    System.out.println(girl + "拿着镜子!");
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (lipstick) {
                        System.out.println(girl + "拿着口红!");
                    }
                }
            }
        }
     
    }
     
    public class TestDeadLock {
        public static void main(String[] args) {
            Makeup m1 = new Makeup();//大丫的化妆线程;
            m1.girl = "大丫";
            m1.flag = 0;
            Makeup m2 = new Makeup();//小丫的化妆线程;
            m2.girl = "小丫";
            m2.flag = 1;
            m1.start();
            m2.start();
        }
    }

     在实际开发中,尤其是“架构设计”中,会大量使用这个模式。这就是必须掌握的内容。

    IO流

    字节流:二进制,可以一切文件 包括  纯文本 doc 音频、视频等等

    字符流:文本文件,只能处理纯文本

    输入流和输出流,差别在于出和入,是相对于程序而言的。“输入流式得到数据,输出流是输出数据”,这种说法是对的。你把问题想复杂了,输入是程序得到外部数据,输出是程序向外部传输数据,二者没专有必然的联系,都是流,差别是方向不同,也就是说,程序可以只有输入流而没有输出流,或者只有输出流而没有输入流

  • 相关阅读:
    代码块;继承;this与super关系;重载与重写对比;类的继承特点;final关键字 (Java Day08)
    变量访问;this关键字;静态;工具类;帮助文档;Math使用;Arrays使用(Java Day07)
    面向对象;类和对象;访问对象;创建对象在内存中的理解;匿名对象;封装和this (Java Day06)
    如何保证 RocketMQ 不丢失消息
    Java-String类型的参数传递问题
    图解前中后序遍历
    一文彻底理解ReentrantLock可重入锁的使用
    聊聊MySQL、HBase、ES的特点和区别
    MySQL vs Java 数据类型
    Multi-Tenancy多租户模式
  • 原文地址:https://www.cnblogs.com/zhrehe-11/p/12885301.html
Copyright © 2011-2022 走看看