总结(上)

  • 接口,异常,多线程,i/o流总结:
    •   接口
    •         1.接口的特性
    •        1.接口不可以被实例化
    •        2.实现类必须实现接口的所有方法
    •        3.实现类可以实现多个接口
    •        4.接口中的常量都是静态常量
    •        2.编写接口类把class代替为interface,实现接口使用关键字implems,如果要实现多个接口则用逗号连接。
    • 3.接口是一种能力,体现在接口方法上。
    • 4.关心实现类有何能力,而不关心实现细节;面向接口的约定二不考虑接口的具体实现。
    • 5.一个人可以具有多项能力,一个类可以实现多个接口。
    • 6.接口有比抽象类更好的特性
    • 1.可以被多继承
    • 2.设计和实现完全分离
    • 3.更自然地使用多态
    • 4.更容易搭建程序框架
    • 5.更容易更换实现
    • 7.接口是一种约定
    • 1.体现在接口名称和注释上:有些接口只有名称 方法的实现方式要通过注释来约定
    • 8.程序设计时面向接口的约定而不考虑具体实现
    •  
    • 第五章 PPT5 异常
    • 1.弊端:
    • 1.代码臃肿
    • 2.程序员要花很大精力"堵漏洞"
    • 3.程序员很难堵住所有"漏洞"
    • 2.异常是指在程序的运行过程中所发生的不正常的事件,它会中断正在运行的程序
    • 3.Java的异常处理是通过5个关键字来实现的:try、catch、 finally、throw、throws
    • 4. 捕获异常 声明异常 抛出异常
    • try 执行可能产生 throws 声明方法可能要 throw 手动抛出异常
    • 异常的 抛出的各种异常
    • catch 捕获异常
    • finally 无论是否发生异常,
    • 代码总能执行
    • 5.异常是一种特殊的对象,类型为java.lang.Exception或其子类
    • 6.printStackTrace的堆栈跟踪功能显示出程序运行到当前类的执行流程
    • 7.在catch块中处理异常
    • 1.加入用户自定义处理信息
    • System.err.println("出现错误:被除数和除数必须是整数, ”+"除数不能为零。");
    • 2.调用方法输出异常信息
    • e.printStackTrace();
    • 3.方法名 说 明
    • void printStackTrace() 输出异常的堆栈信息
    • String getMessage() 返回异常信息描述字符串,
    • 是printStackTrace()输出信息的一部分
    • 8.常见的异常类型
    • 1.Exception 异常层次结构的父类
    • 2.ArithmeticException 算数错误情形,如以零作除数
    • 3.ArraylndexOutOfBoundsException 数组下标越界
    • 4.NullPointerException 尝试访问null对象成员
    • 5.ClassNotFoundException 不能加载所需的类
    • 6.lllegalArgumentException 方法接收到非法参数
    • 7.ClassCastException 对象强制类型转换出错
    • 8.NumberFormatException 数字格式转换异常,如把"abc"转换成数字
    • 9.在try-catch块后加入finally块
    • 1.是否发生异常都执行
    • 2.不执行的唯一情况:在catch块内加入了System.exit(1)
    • 3.如若catch里加有return,则先执行finally,在执行return
    • 10.throws Exception 表明可能抛出的异常
    • throw new Exception();手动抛出异常
    • throws声明异常 throw抛出异常
    • 有throw时必须得有throws,如若没有则运行错误 则有throws时不一定要有throw
    • 抛出异常 是不是首先得声明了有异常 声明异常可以不抛出异常
    • 11.Throwable Exception和Error类的父类
    • Eror 仅靠程序本身无法恢复的严重错误
    • Exception 由Java应用程序抛出和处理的非严重错误
    • RuntimeException 运行时异常,不要求程序必须做出处理
    • SQLException ClassNotFoundException Checked异常,程序必须处理该类异常
    • 12.日志记录器输出级别:fatal>error>warn>info>debug
    • 13.日志顺序
    • 1.输出级别和输出目的地
    • log4j.rootLogger = debug,stdout,logfile
    • 2.把日志信息输出到控制台
    • (1)日志信息输出到控制台
    • (2) 信息打印到System,err上
    • (3)指定日志布局类型
    • 3.把日志输入到文件:jbit.log
    • (1)日志信息写到文件中
    • (2)指定日志输出的文件名
    • (3)指定转换模式
    • (4)指定日志布局类型
    • 第六章 ppt6 集合
    • 1.List、Msp都继承自Collection接口
    • 和数组采用相同储存结构的集合类型是List
    • 2.为什么使用集合框架
    • 不确定的元素数量会导致太少浪费空间,太多空间不足
    • 如果并不知道程序运行时会需要多少对象,或者需要更复杂方式储存对象---可以使用Java集合框架
    • 3.Java集合框架提供了一套性能优良、使用方便的接口和类,它们位于java.util包中
    • 1.接口
    • LIst (1)ArrayList() (2)LinkedLIst()
    • Collection
    • Set (1)HashSet() (2)TreeSet()
    • (1)HashMap()
    • Map
    • (2)TreeMap()
    • 2.括号标注都是具体类
    • 3.算法 Collections 提供了对集合进行排序、遍历多种算法实现
    • 4.Collection接口储存一组不唯一,无序的对象 (唯一:只有一个 不能有相同;无序:没有顺序)
    • List接口储存一组不唯一,有序(插入顺序)的对象
    • Set接口存储一组唯一,无序的对象
    • Map接口存储一组键值对象,提供key到value的映射
    • 5.使用ArrayList储存元素
    • 1.创建ArrayList集合并存储元素 集合.add(下标,名称) 下标可省略 ,默认依次排序
    • 2.输出元素数量 集合.size()
    • 3.逐个获取元素 集合.get(i)
    • 4.从集合中删除元素 集合.remove(可输入下标或者元素名称)
    • 5.判断集合中是否存在指定元素 集合.contains(元素名称) 用if判断语句进行判断
    • 6.LinkedList集合的特殊使用方法
    • 创建LinkedList集合 LinkedList linkedlist = new LinkedList();
    • 存储对象 linkedlist.add(下标,名称) 下标可以省略,默认依次排序
    • 存储到第一条语句位置 linkedlist.addFirst(名称);
    • 存储到最后一条语句位置 linkedlist,addLast(名称);
    • 获取第一元素信息 linkedlist.getFirst();
    • 获取最后一元素信息 linkedlist.getLast();
    • 删除第一元素或最后一元素信息 linkedlist.removeFirst();
    • linkedlist.removeLast();
    • 7.集合框架有什么好处
    • 弥补数组代码元素不确定的缺陷
    • Java集合框架中包含哪些接口和类
    • 接口:Collection,List,Set,Map
    • 类:ArrayList(),LinkedLIst(),HashSet(),TreeSet(),HashMap,TreeMap
    • 算法:Collections 提供了对集合进行排序 遍历多种算法的实现
    • ArrayList和LinkedList的区别
    • ArrayList和LinkedList都继承了List,继承了List有序,不唯一的优点
    • ArrayList实现了长度可变的数组,在内存中分配连续的空间。遍历元素和随机访问元素的效率比较高
    • LinkedList采用链表存储方式。插入、删除元素时效率比较高
    • 8.Map接口专门处理键值映射数据的存储,可以根据键实现对值的操作
    • Map中values相当于是一个个房间,而Key则是一个个对应的打开房间的钥匙
    • 常用实现类是HashMap();
    • Map map = new HashMap();
    • 添加元素 map.put("元素名称","元素值");
    • 提取元素 map.get("元素名称");
    • 获取元素数量 map.size();
    • 判断是否具有指定元素 map.containsKey("元素名称");
    • 删除指定元素 map.remove("元素名称");
    • 输出键集(也就是每个元素名称) map.KeySet();
    • 输出值集(也就是元素值) map.values();
    • 输出键值对集 map
    • 清空Map数据 map.clear();
    • 判断Map数据是否已清空 map.isEmpty();
    • 9.通过Iterator实现遍历
    • 1.获取Iterator:Collection接口的iterator()方法
    • 2.Iterator的方法
    • boolean hasNext():判断是否存在另一个可访问的元素
    • Object next():返回要访问的下一个元素
    • 3.(1)Set key = map.keySet(); // 取出所有key的集合
    • Iterator i = keys.Iterator(); // 获取Iterator对象
    • While(it.hasNext()){
    • String keys = (String)i.next(); //取出key
    • String dog = (String)map.get(key); //根据key取出相应的值
    • System.out.println(keys+" "+dog);
    • }
    • (2)Set keys = map.keySet();
    • for(Object key:keys){
    • String aa = (String)map.get(key);
    • System.out.println(key+" "+aa)
    • }
    • 10.泛型集合
    • 标记元素类型
    • List List<Dog> dog = new ArrayList<Dog>();
    • 设置泛型集合之后
    • add();类型不符合时 会出现错误
    • 无需再类型强制转换
    • 标记键-值类型
    • Map<String,String> map=new HashMap<String,String>();
    • 标记键类型
    • Set<String>keys = map.keySet();
    • Iterator<String>i = keys.iterator();
    • 设置泛型集合之后
    • 同样无需再类型转换
    •  
    • ppt7 第七章 多线程
    • 1.进程 应用程序的执行实例 有独立的内存空间和系统资源 可以有多个应用程序进行执行
    • 2.线程 CPU调度和分派的基本单位 进程中执行运算的最小单位,可完成一个独立的顺序控制流程 一个时间点只能执行一个任务
    • 3.一个进程以多个线程组成
    • 4.(1)多线程 在一个进程之中同时运行了多个线程,用来完成不同的工作,则称之为"多线程"
    • (2)多个线程交替占用CPU资源,而非真正的并行执行
    • 好处:
    • 1.充分利用了CPU的资源
    • 2.简化编程模型
    • 3.带来良好的用户体验
    • 5.Thread类
    • Java提供了java.lang,Thread类支持多线程编程
    • 主线程
    • 1.main()方法即为主线程入口
    • 2.产生其他子线程的线程
    • 3.必须最后完成执行,因为它执行各种关闭动作
    • 示例:
    • Thread t = Thread.currentThread(); 获取主线程对象
    • System.out.println("当前线程为"+t.getName());
    • t.setName("MyJavaThread"); 设置线程名
    • System.out.println("当前线程名是"+t.getName()); 获取线程名
    • 6.在Java中创建线程的两种方式
    • 1.继承java.lang.Thread类
    • 2.实现java.lang.Runnable接口
    • 7.线程使用步骤
    • 1.定义线程--2.创建线程对象--3.启动线程--4.终止线程
    • 8.继承Tread类创建线程
    • 1.定义类继承Thead类
    • 2.重写run()方法,编写线程执行体
    • 3.创建线程对象,调用start方法启动线程
    • 示例:
    • public class MyThread extends Thread{} 继承Thread类
    • public void run(){} 重写run()方法,run()方法中编写线程执行的代码
    • main方法中 对象.start();启动线程
    • 9.如何继承Thread类创建线程
    • 多个线程交替执行,不是真正的"并行";
    • 线程每次执行时长由分配的CPU时间片长度决定
    • 10.启动线程是否可以直接调用run()方法
    • 调用run()方法时只能调用主线程一条执行路径(效率较低)
    • 主线程--t.run()--主线程执行run()--输出 只有主线程一条执行路径 调用主线程执行路径时其他线程不动 直走主线程一条路径
    • 调用start()方法时多条执行路径,主线程和子线程并行交替执行
    • 主线程--t.start()--子线程执行run()方法--输出
    • 11.实现Runnable接口创建线程
    • 1.定义MtRunnable类实现Runnable接口
    • 2.实现run()方法,编写线程执行体
    • 3.创建线程对象,调用start()方法启动线程
    • public class MyrRunnable implements Runnable { 实现Runnable接口
    • public void run(){
    • for (int i = 0;i<100;i++){ run()方法中编写线程执行的代码
    • System.out.println(Thread.currentThread().getName()+" "+i);
    • }
    • }
    • }
    • MyrRunnable r = new MyrRunnable(); 创建对象
    • Thread thread = new Thread(r); 创建线程对象,并把MyRunnable传入Thread构造方法
    • thread.start(); 启动线程
    • 12.比较两种创建线程的方式(推荐使用实现Runnable接口方式创建线程)
    • 1.继承Thread类
    • 编写简单,可直接操作线程
    • 适用于单继承 (继承Thread类之后不会再继承其他类)比较固化
    • 2.实现Runnable接口
    • 避免单继承局限性 (可以实现多个接口 并且不会影响继承类)
    • 便于共享资源
    • 13.线程状态
    • (1)创建状态 将线程创建出来 创建状态--就绪状态:启动线程之后变为就绪状态
    • (2)就绪状态 准备好了,但是还没有运行(等待执行) 就绪状态--运行状态:获得CPU资源变为运行状态
    • (3)运行状态 运行线程 运行状态--死亡状态:线程自然执行完毕或者外部干涉终止线程变为死亡状态
    • 运行状态--就绪状态:把没用完的CPU资源释放回就绪状态
    • 运行状态--阻塞状态:等待用户输入线程休眠等(很多种情况都在阻塞状态)
    • (4)阻塞状态 没法运行 阻塞状态--就绪状态:阻塞接触
    • (5)死亡状态 运行完毕
    • 16.线程调度指按照特定机制为多个线程分配CPU的使用权
    • (1)更改线程优先级: setPriority(int newPriority);
    • // 括号中填入整数(优先级由1~10表示,1最低,默认为5)优先级搞得线程获得CPU资源概率较大
    • 示例:
    • Thread t1 = new Thread(new MyThead(),"线程一");
    • Thread t2 = new Thread(new MyThead(),"线程二"); //创建线程对象并指定线程名
    • t1.setPriority(Thread.MAX_PRIORITY); // 两个对象分别设置最高优先级和最低优先级
    • t2.setPriority(1);
    • (2)让当前线程休眠指定毫秒数: static void sleep(long millis);
    • //括号中填入整数 为休眠时间 以毫秒为单位 ※ 调用sleep()时需处理InterruptedException (休眠时间过长线程进入阻塞状态 休眠时间过后线程继续运行)
    • 示例:
    • try{
    • Thread.sleep(1000);
    • }catch (InterruptedException e){
    • // 休眠一秒
    • e.printStackTrace();
    • }
    • (3)使当前线程暂停执行,等待其他线程 结束后就绪执行本线程(插队): final void join(); join(long millis); join(long millis,int nanos);
    • // millis:以毫秒为单位的等待时长 nanes:要等待的附加纳秒时长 ※ 需处理InterruptedException异常
    • 示例:
    • Thread t = new Thread(new MyThead());
    • t.start();
    • for (int i =0;i<20;i++){
    • if (i==5){
    • try {
    • t.join(); //阻塞主线程 让子线程强制执行
    • }catch (InterruptedException e){
    • e.printStackTrace();
    • }
    • }
    • System.out.println(Thread.currentThread().getName()+"运行:"+i);
    • (4)暂停当前执行线程对象,执行其他线程(线程的礼让): static void yield();
    • // 暂停当前的线程,允许其他具有相同优先级的线程获得运行机会,该线程处于就绪状态,不转为阻塞状态(只是提供一种可能不能保障一定会实现礼让)
    • 示例:
    • for (int i = 0;i<5;i++){
    • System.out.println(Thread.currentThread().getName()+"正在运行"+i);
    • if (i==3){
    • System.out.print("线程礼让");
    • Thread.yield(); // 当i=3时 线程礼让
    • }
    • }
    • public static void main(String[] args) {
    • Thread t1 = new Thread(new Yield(),"线程A");
    • Thread t2 = new Thread(new Yield(),"线程B");
    • t1.start();
    • t2.start();
    • }
    • (5)中断线程: void interrupt();
    • (6)测试线程是否处于活动状态: boolean isAlive();
    • 17.join()方法和yield()方法的区别是什么
    • join强制插队 会使主线程阻塞,主线程一直运行; yield礼让 让其他线程执行 礼让给其他线程
    • 18.多个线程操作同一共享资源时,将引发数据不安全问题,这时候就会用到同步方法。
    • 19.synchronized关键字使用
    • (1)同步方法
    • 使用synchronized修饰的方法控制对类成员变量的访问
    • 访问修饰符 synchronized 返回值类型 方法名 (参数列表){}
    • 或者synchronized 访问修饰符 返回值类型 方法名 (参数列表){}
    • pravit synchronized void patin(){}
    • public void run(){ patin();}
    • synchronized就是为当前的线程声明一个锁,加了锁之后,多线程在调用方法的时候,只能排队执行,只要有一个线程在调用方法,其他线程是没法调用方法的
    • 同一时间内,只有一个线程在修改数据,所以当前数据是安全的
    • (2)使用synchronized关键字修饰的代码块(同步代码块) //当一个线程在其中时,阻挡其他线程进入
    • synchronized(synObject){
    • //需要同步的代码
    • }
    • syncObject为需同步的对象,通常为this ※ 效果与同步方法相同
    • while(true){
    • synchronized(this){//同步代码块
    • //省略修改数据的代码........
    • //省略显示信息的代码........
    • }}
    • 20.多个并发线程访问同一资源的同步代码块时
    • (1)同一时刻只能有一个线程进入synchronized(this)同步代码块
    • (2)当一个线程访问一个synchronized(this)同步代码块时,其他synchronized(this)同步代码块同样被锁定
    • (3)当一个线程访问一个synchronized(this)同步代码块时,其他线程可以访问该资源的非synchronized(this)同步代码
    • 21.查看ArrayList方法的定义(ArrayList为非线程安全的类型)
    • (1)ArrayList类的add()方法为非同步方法
    • (2)当多个线程向同一个ArrayList对象添加数据时,可能出现数据不一致问题
    • 22.线程安全类型(为达到安全性和效率的平衡,可以根据实际场景来选择合适的类型)
    • 线程安全: 方法同步;效率较低;适用于多线程并发共享资源
    • 非线程安全:方法不同步;效率高;适用于单线程
    • 23.常见类型对比
    • 1.Hashtable和HashMap
    • (1)Hashtable:1.继承关系(1)实现了Map接口,Hashtable继承Dictionary类;2.线程安全,效率较低;3.键和值都不允许为null
    • (2)HashMap:1.继承关系(1)实现了Map接口,继承AbstractMap类;2.非线程安全,效率较高;3.键和值都允许为null
    • 2.StringBuffer和StringBuilder
    • (1)前者线程安全效率低,后者非线程安全效率高
    • 24.为什么进行线程同步
    • 为了解决线程不安全,数据不安全问题
    • ppt8 第八章 I/O流
    • 1.Java程序如何访问文件
    • Java API:java.io.File类(File:文件)
    • 2.File类访问文件属性
    • 创建文件对象: 物理文件或目录 通过文件对象的方法操作文件或目录属性
    • File类--创建文件对象--操作文件或者目录的属性(路径、权限、日期和时间等)
    • 创建File类的对象:File file = new File(String pathname);Java提供了两种路径方式:"C:\\test.txt"或"C:/test.txt"(win10会对系统进行一些处理所以尽量使用其他盘)
    • 3.File类常用方法
    • 1.boolean exists() 判断文件或目录是否存在
    • 2.boolean isFile() 判断是否是文件
    • 3.boolean isDirectory() 判断是否是目录
    • 4.String getPath() 返回此对象表示的文件的相对路径名 相对路径,顾名思义就是一个文件相对于另外一个文件的位置.
    • 5.String getAbsolutePath() 返回此对象表示的文件的绝对路径名 绝对引用,引用的是绝对地址
    • 6.String getName() 返回此对象表示的文件或目录的名称
    • 7.boolean delete() 删除此文件指定的文件或目录
    • 8.boolean createNewFile() 创建名称的空文件,不创建文件夹
    • 9.long length() 返回文件的长度,单位为字节,如果文件不存在,则返回OL
    • ※:相对路径更方便更改,相对比较灵活,但是如果不慎易造成链接失效,并且容易被人抄袭 。
    • 绝对路径的话能避免这个问题,但是灵活性上相对较弱。
    • 3.如何读写文件
    • 通过流来读写文件:流是指一连串流动的字符,是以先进先出方式放松信息的通道
    • 流向目的地的数据流: InputStream--F--E--D--C--B--A--OutputStream
    •        4.输入/输出流与数据源1
    •               源数据源--流--通过读的方式--程序 输入流对象负责读取文件
    •               程序--编写--流--目标数据源 输出流对象负责将文件写入另一个文件
    •        5.Java流的分类(输入输出流是相对于计算机内存来说的)
    •        按流向分:
    •               1.输出流:OutputSteam和Writer作为基类
    •               2.输入流:InputStream和Reader作为基类
    •        按照处理数据单元划分:
    •               1.字节流:(1)字节输入流InputStream基类 (2)字节输出流OutputStream基类 (字节流是8位通用字节流)
    •               2.字符流:(1)字符输入流Reader基类 (2)字符输出流Writer基类 (字符流是16位Unicode字符流)支持大量字符操作
    •        6.文件的读写
    •        1.文本文件的读写
    •               (1)用FileInputStream和FileOutputStream读写文本文件
    •               (2)用BufferedReader和BufferedWriter读写文本文件
    •        2.二进制文件的读写
    •               使用DatalnputStream和DataOutputStream读写二进制文件
    •        7.使用FileInputStream读文本文件
    •               引入相关的类(impot java.io.IOException; impot java.io.FolelnputStream;)--构造文件输入流FilelnputStream(FilelnputStream fis
    •               = new FilelnputStream("c:\\test.txt"))--读取文本文件的数据(fis.available(); 读取文档中的第一个信息:fis.read();)--关闭文件流对象(fis.close();)
    •        InputStream类常用方法
    •               int read( )
    •               int read(byte[] b)
    •               int read(byte[] b,int off,int len)
    •               void close( )
    •               int available()
    •        子类FileInputStream常用的构造方法
    •               FileInputStream(File file)
    •               FileInputStream(String name)
    •        8.使用字符流读写文件
    •               使用Reader接口实现--使用String的replace()方法实现--使用Writer实现
    •        9.BufferedReader类(FileReader与BufferedReader结合使用)
    •        如何提高字符流读取文本文件的效率?
    •               使用FileReader类和BufferedReader类
    •        BufferedReader类使Reader类的子类,BufferedReader类带有缓冲区,按行读取内容的readLine()方法(BufferedReader类特有的方法)
    •               使用步骤:引入相关的类--构造BufferedReader和FileReader对象--调用readLine()方法读取数据--关闭文件流对象
    •        Reader类常用方法
    •               int read( )
    •               int read(byte[] c)
    •               read(char[] c,int off,int len)
    •               void close( )
    •        子类BufferedReader常用的构造方法
    •               BufferedReader(Reader in)
    •        子类BufferedReader特有的方法
    •               readLine()
    •        10.使用FileWriter写文件(与字节流FileOutputStream类实现向文本文件写入数据步骤类似)
    •        1.引入相关的类--创建FileWriter对象--写文本文件--关闭相关的流对象
    •               flush:强制刷新缓冲区,将信息写入文件中
    •        2.如何提高字符流写文本文档的效率(引入缓冲提高效率)
    •        使用FileWriter类与BufferedWriter类(BufferedWriter类是Writer类的子类,BufferedWriter类带有缓冲区)
    •               使用步骤:引入相关的类--构造BufferedWriter对象和FileWriter对象--调用write()方法写数据--流对象的清空和关闭flush()和close()
    •        Writer类常用方法
    •               write(String str)
    •               write(String str,int off,int len)
    •               void close()
    •               void flush()
    •        子类BufferedWriter常用的构造方法
    •               BufferedReader(Writer out)
    •        11.读写二进制文件(复制图片和Class文件)
    •               1.DataInputStream类
    •               1.FileInputStream的子类
    •               2.与FileInputStream类结合使用读取二进制文件
    •               2.DataOutputStream类
    •               1.FileOutputStream的子类
    •               2.与FileOutputStream类结合使用写二进制文件
    •        12.使用DataInputStream读二进制文件(和FileInputStream类实现文本文件读取去步骤极其相似)
    •               实现步骤:引入相关的类--构造数据输出流对象--调用read()方法读取二进制数据--关闭数据输入流
    •        13.使用DataOutputStream写二进制文件(和FileOutputStream类实现文本文件读取去步骤极其相似)
    •               实现步骤:引入相关的类--构造数据输出流对象--调用write()方法写二进制文件的数据--关闭数据输入流
    •        14.总结
    •        流分为:
    •        1.字节流 (图片声音二进制文件推荐使用字节流)
    •               (1)输入流:FileInputStream:
    •               (2)输出流:
    •        2.字符流(处理大量文字信息,中文,包括其他国家的语言使用字符流)
    •               (1)输入流:
    •               (2)输出流:
    •        3.缓冲流(加快程序运行)
    •               (1)输入流:
    •               (2)输出流:
    •        4.使用文件流的步骤
    •               (1)引入相关的类
    •               (2)创建输入流/输出流对象
    •               (3)读取/写入文本文件的数据
    •               (4)关闭相关的流对象
posted @ 2020-04-02 18:13  企昂昂  阅读(157)  评论(0编辑  收藏  举报