0%

爪哇

课后习题

第01章 语言概述

  1. 谈谈你过去学习编程语言的方法、经验和教训。

    学习过C++和Python, 基本方法是学习简单语法,尝试做简单的题目,这样能够很快的熟悉一门语言。而后在尝试写一些简答的项目,比如Python的爬虫数据分析等。

  2. 高级语言的编译型和解释型语言的编译执行过程有什么区别?

    高级语言编译一次性全部编译成机器码,解释性是一句一句转成机器码

  3. Java语言都有哪些特点?与C, C++, Python有何不同?

    Java是完全的面向对象编程

  4. Java实现跨平台的原理是什么?

    通过java虚拟机在系统平台上运行的,而不同平台有不同的虚拟机。具体流程:

    源文件(.java)—>字节码文件(.class)(二进制文件)—–> 解释—->Unix,Win,Linux等机器

  5. JDK、JRE、JVM分别是什么的简称,它们之间有何联系和区别?

    • JDK(Java Development Kit):是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的Java应用程序。JDK是整个Java开发的核心。
    • JRE(Java Runtime Environment):是指Java的运行环境,是可以在其上运行、测试和传输应用程序的Java平台。
    • JVM(Java Virtual Machine):是java虚拟机,是一种用于计算设备的规范,它是一个虚构出来的计算机,引入JVM后,Java语言在不同平台上运行时不需要重新编译。JVM是Java跨平台的核心。
    • 联系
      • JDK包含了java的运行环境(JRE)和Java工具。
      • JRE包含了一个Java虚拟机(JVM)以及一些标准的类别函数库。
    • 区别:
      • JDK和JRE区别:在 bin文件夹下会发现,JDK有 javac.exe而JRE里面没有, javac指令是用来将 java文件编译成 class文件的,这是开发者需要的,而用户(只需要运行的人)是不需要的。JDK还有 jar.exe, javadoc.exe等等用于开发的可执行指令文件。这也证实了一个是开发环境(JDK),一个是运行环境(JRE);
      • JRE和JVM区别:JVM并不代表就可以执行 class了,JVM执行 .class还需要JRE下的 lib类库的支持,尤其是 rt.jar

第02章 语言基础

  1. Java包含哪两大类数据类型?其中基本类型的每种类型的取值范围和默认值分别是什么?请编程验证。

    1. 基本数据类型
      1. 整数类型
      2. 浮点类型
      3. 字符类型
      4. 布尔类型
    2. 引用数据类型
      1. 类类型
      2. 接口类型
      3. 数组类型
    3. 验证:

  2. Java在什么情况会发生整型溢出?请举例说明,并给出解决方案。

    1. 超出数据类型的范围
    2. 解决方法:
      1. 换成更大范围的类型
      2. 手写高精度算法
  3. Java基本类型的包装类分别是哪些?其高频区间数据缓存范围分别是什么?请选择一种包装类型编程验证其数据缓存特性。

    基本数据类型 包装类 字节数 位数 默认值 数据范围 高频区间数据缓存范围
    byte Byte 1 8 0 $[-128,127]$
    short Short 2 16 0 $[-32768,32767]$ $[-128,127]$
    int Integer 4 32 0 $[-2^{31}, 2^{31}-1]$ $[-128,127]$
    long Long 8 64 0L $[-2^{63},2^{63}-1]$ $[-128,127]$
    float Float 4 32 0.0f 无缓存
    double Double 8 64 0,0d 无huancub
    boolean Boolean 1 8 false
    char Character 2 16 ‘\u0000’ $[0,127]$
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Integer i3 = 128;
    Integer i4 = 128;
    i3 == i4 // false

    Integer i3 = 127;
    Integer i4 = 127;
    i3 == i4 //true

    //比较指向的对象是否一致
    //逻辑比较请用equal
  4. 什么是自动装箱,什么是自动拆箱,请举例说明。

    1
    2
    3
    4
    5
    6
    7
    Integer varInteger=100;//自动装箱
    //等价于
    integer varInteger=Integer.valueOf(100);

    int varInt=varInteger;//自动拆箱
    //等价于
    int varInt=varInteger.intValue();
  5. intInteger有什么区别,它们之间的相互转化是怎样的?请通过 JDK文档自主学习 Integer类,对主要方法进行测试。

    1. Integerint 的包装类,默认值分别为 null0

    2. Integer 需要实例化才可以使用, int 不需要。(不包括自动拆箱装箱)

    3. int->Integer

      1
      2
      3
      int a=66; Integer A=new Integer(a);
      //等价于
      Integer A=Integer.valueOf(a);
    4. Integer->int

      1
      2
      Integer A=new Integer(66);
      int a=A.intValue();
  6. 逻辑运算符 &&&的区别是什么?逻辑运算符 &与位运算符 &的区别是什么?

    1. && 是短路判断语句,只要前半个为错误,就不会判断后面的语句了
    2. & 会将所有语句都跑一边,看是否存在错误。
    3. 两者比较, && 更高效。
    4. 作为逻辑运算符,两边为表达式
    5. 作为为运算符,两边为数字
  7. Java语言中可以采用什么语句跳出多重循环?请举例说明

    • break 跳出当层循环

    • continue 跳出当次循环

    • 跳回到标签位置:

      1
      2
      3
      4
      5
      6
      7
      8
      post:
      for(int i=1;i<=10;i++){
      for(int j=1;j<=10;j++){
      if(i+j>=5) break post;
      //System.out.println(i+j);
      }
      }
      }
  8. 请总结 Java语言与 C/C++在基本数据类型、运算符、表达式、控制语句方面的不同。

    1. 布尔常量的 true false1 0 不等价,不可直接运算。

    2. 字符串作为对象,有自己的方法和属性。 C/C++ 则是 \\0 结束的字符数组

    3. 变量未赋值有默认值,而 C/C++ 是不确定的。

    4. 不支持自动强制类型转换,需手动转换。

    5. 有支持多线程的库, C/C++ 需要自己写。

    6. 前者是先编译,后解释执行,后者是纯编译型,速度后者更快,但是移植型前者更好。

    7. 借鉴博客连接:

      orange-C

第06章 继承与多态

  1. 实验:利用IDE的debug功能给P5示例的 new语句设置断点,使用单步调试 (step into/step over)跟踪对象实例化(初始化)的执行顺序,并总结该过程。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class AddClass {
    public int x=0,y=0,z=0;
    AddClass (int x) {this.x = x;}
    AddClass (int x,int y) {this(x);this.y = y;}
    AddClass (int x,int y,int z) { this(x,y); this.z = z; }
    public int add() {return x+y+z;}
    }
    public class RunAddClass {
    public static void main(String[] args) {
    AddClass p1=new AddClass(2,3,5);
    }
    }
    1. 访问三变量构造函数
    2. 通过 this(x,y) 调用两变量构造函数
    3. 同理,调用一变量构造函数
    4. 给变量 x 赋值
    5. 返回 两变量构造函数 给 y 赋值
    6. 返回 三变量构造函数 给 z 赋值
  2. 实验:利用IDE的 debug 功能给P12,P13示例的 new语句设置断点,使用单步调试 (step into/step over)跟踪子类对象实例化(初始化)的执行顺序,并总结该过程。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    //显式
    public class SonAddClass extends AddClass{
    int a=0,b=0,c=0;
    SonAddClass (int x) {super(x);a=x+7;}
    SonAddClass (int x,int y){super(x,y); a=x+5; b=y+5;}
    SonAddClass (int x, int y,int z){ super(x,y,z); a=x+4; b=y+4;c=z+4;
    }
    public static void main(String[] args){
    SonAddClass p1=new SonAddClass (2,3,5);
    }
    }
    1. 访问三变量子构造函数。
    2. 通过 super 访问父类三变量构造函数。
    3. 同上文顺序给父类三变量赋值
    4. 返回子类构造函数,给子类变量赋值。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    //隐式
    package test;
    class Pare {
    int i=3;
    Pare(){ System.out.println("call super()"); }}
    class Construct extends Pare{
    int i = 10;
    Construct(){System.out.println("execute Construct()"); }
    Construct(int num){ this(); //如果注释掉该句呢?
    System.out.println("execute Construct(int)"); }
    public static void main(String[] args){
    Construct ct = new Construct(9);
    System.out.println(ct.i);}}
    //注释前
    call super()
    execute Construct()
    execute Construct(int)
    10

    //注释后
    call super()
    execute Construct(int)
    10
  3. 分析P7示例的程序执行过程,画出程序执行的内存布局。(蒙的)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    package test;
    class A {
    int x=4;
    int y=1;
    public void Printme() {
    System.out.println("x="+x+" y="+y);
    System.out.println("class name: "+getClass().getName());
    }
    }
    public class AA extends A {
    int x;
    @Override
    public void Printme() {
    int z=super.x+6;
    super.x = 5;
    super.Printme();
    System.out.println("I am an "+getClass().getName());
    x=6;
    System.out.println(" z="+z+" x="+x+" super.x="+super.x +" y="+y+"super.y="+y);
    }
    public static void main(String arg[]) {
    int k;
    A p1=new A();
    AA p2=new AA();
    p1.Printme();
    p2.Printme();
    }
    }

  4. 总结 thissuper的用法。

    1. this. 调用本对象的属性或方法, this() 调用本对象的构造方法
    2. super. 调用父对象的属性和方法, super() 调用父对象的构造方法
    3. 两者都要放到第一句,所以不可同时使用。
  5. 论述组合与继承的区别以及两者的使用场景(即什么时候宜用组合?什么时候宜用继承?)

    1. 都是代码的复用
    2. 组合中,各类是独立的,继承中,子类缺乏独立性
    3. 从一般到特殊选择继承
    4. 作为工具类选择组合
  6. Java中的运行时多态的含义是什么?通常在什么场景下应用,请举例说明。

    1. 多态含义:同一个类有多个对象,接收到同一个消息时,会有不同的结果
    2. 运行时多态:使用父类引用,指向子类对象,再调用某一父类中的方法时,不同的子类会表现出不同的结果。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    public class Figure {
    double dim1;
    double dim2;
    Figure(double d1, double d2) {
    // 有参的构造方法
    this.dim1 = d1;
    this.dim2 = d2;
    }
    double area() {
    // 用于计算对象的面积
    System.out.println("父类中计算对象面积的方法,没有实际意义,需要在子类中重写。");
    return 0;
    }
    }
    public class Rectangle extends Figure {
    Rectangle(double d1, double d2) {
    super(d1, d2);
    }
    double area() {
    System.out.println("长方形的面积:");
    return super.dim1 * super.dim2;
    }
    }
    public class Triangle extends Figure {
    Triangle(double d1, double d2) {
    super(d1, d2);
    }
    double area() {
    System.out.println("三角形的面积:");
    return super.dim1 * super.dim2 / 2;
    }
    }

    public class Test {
    public static void main(String[] args) {
    Figure figure; // 声明Figure类的变量
    figure = new Rectangle(9, 9);
    System.out.println(figure.area());
    System.out.println("===============================");
    figure = new Triangle(6, 8);
    System.out.println(figure.area());
    System.out.println("===============================");
    figure = new Figure(10, 10);
    System.out.println(figure.area());
    }
    }

    //figure 的对象都是其子类。向上转型,实现多态。
  7. 使用接口改写例6.8中的程序。

  8. 论述抽象类与接口的异同以及两者的使用场景。

  9. 论述内部类的定义和作用以及匿名内部类的使用。

    1. 定义:在类的内部定义类
    2. 作用:可以访问外部类的成员,包括私有成员,使得该类具有其他类没有的特有功能。

第 07 章 异常

  1. Throwable的子类包含哪两类?简述 Error类与 Exception类的区别。

    1. 前者不可被捕获,后者可以被捕获
    2. 前者不需要被抛出,后者需要用 Expetion 抛出异常
    3. 前者会导致程序不能运行或中断,后者可以通过捕获抛出
  2. Exception又分为 checked异常和 unchecked异常,请分别举例说明。

    1. 前者是在编译是需要检查的异常,需要用 try - catch 捕获,后者是不需要在编译时处理。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      // checked
      class A{
      public static void main(String[]args){
      try(Scanner sc=new Scanner(System.in)){
      int a=sc.nextShort();
      }catch (Exception e){
      e.printStackTrace();
      }
      }
      }

      //unchecked
      class A{
      public static void main(String[]args){
      int []a;
      System.out.println(a[0]);
      }
      }
  3. 请查阅资料,简述 StackOverflowErrorOutOfMemoryError两类错误的发生情形和原因。

    1. 前者:递归次数太多、线程数量太多
    2. 后者:内存不够发生了内存溢出
  4. 简述异常处理的两种方式,并举例说明区别。

    1. throw 异常上抛,如果直接抛到了 main 就会结束程序
    2. try - catch 异常捕获处理,调用者不会知道哪里出错了,因为在下面已经被捕获并且处理了。
  5. 选取 RuntimeException 类的五个子类,编写抛出并捕获上述子类异常的程序。(例如算术异常,空指针异常,类转换异常,数组越界异常等)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    public class Exception {
    public static void main(String args[]){
    try{
    int a=1/0;
    }catch (java.lang.Exception e){
    System.out.println("算术异常:"+e);
    }

    try{
    int []a = new int[10];
    a[11]=-1;
    }catch (java.lang.Exception e){
    System.out.println("数组越界异常:"+e);
    }

    try{
    Scanner sc = null;//new Scanner(System.in);
    sc.nextInt();
    }catch (java.lang.Exception e){
    System.out.println("空指针异常:"+e);
    }

    try{
    Stack<Integer> stack = new Stack<>();
    stack.pop();
    }catch (java.lang.Exception e){
    System.out.println("空栈异常:"+e);
    }

    try{
    Object a = new Integer(0);
    a=(String)a;
    }catch (java.lang.Exception e){
    System.out.println("类转换异常:"+e);
    }
    }
    }
  6. 根据某业务场景自定义一个异常类,并在某场景下抛出该异常对象。

    关于自定义异常类:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class SelfException extends java.lang.Exception {
    public SelfException(){}
    public SelfException(String s){
    super(s);
    }
    public static void main(String args[]) throws SelfException {
    int a = 1;
    if(a == 1){
    throw new SelfException("a=1");
    }
    }
    }
  7. 异常中的 throws 声明与 throw语句的区别是什么?请举例说明。 1.

  8. finally子句的作用是什么?

第 08 章 字符串

  1. 借助 JDK文档, 选取 StringStringBufferStringBuilder 的常用 API,并编写实例测试 API的功能。

  2. 请简述 StringStringBufferStringBuilder 三者之间的共同点与区别,应该分别在何种场景下使用?

    1. 相同点
      1. 都是字符串类
      2. 内部基于字符数组实现,封装了对字符串的各种操作
    2. 不同点
      1. String 是不可变的,每次改变会重新创建对象。支持共享
      2. StringBuffer 是线程安全的,可变的
      3. StringBuilder 是多线程不安全的,可变的,相比 StringBuffer 更快。提供了和 StringBuffer 兼容的API,但不保证同步。
    3. 使用场景
      1. 多线程使用字符串缓冲区时,使用 StringBuffer 是更为安全的
      2. 效率上讲 StringBuilder>StringBuffer>String
  3. 为什么不建议在for循环中使用“+”进行字符串拼接?

    String 是字符串常量,每次改变都会生成一个新的对象,会十分影响性能。

第 09 章 多线程

  1. 创建线程的基本方法有哪些?

    1. 通过继承 Thread
    2. 通过实现 Runnable 接口
  2. FutureTask 类有什么作用?它实现了哪些接口?

  3. volatile 关键字有什么作用?

    1. 保证程序的可见性和有序性(不能保证原子性)
  4. Java提供了哪些同步机制来实现互斥?

    1. synchronized
    2. ReentrantLock
  5. 编写 Java程序模拟烧水泡茶最优工序。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    package Acwing;

    class WashKettle implements Runnable{

    @Override
    public void run() {
    System.out.println("开始洗水壶");
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    throw new RuntimeException(e);
    }
    System.out.println("水壶洗完了");
    }
    }
    class HeatWater implements Runnable{

    @Override
    public void run(){
    System.out.println("开始烧水");
    try {
    Thread.sleep(10000);
    } catch (InterruptedException e) {
    throw new RuntimeException(e);
    }
    System.out.println("水烧完了");
    }
    }
    class WashCup implements Runnable{

    @Override
    public void run() {
    System.out.println("开始洗茶杯");
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    throw new RuntimeException(e);
    }
    System.out.println("茶杯洗完了");
    }
    }
    class GetTea implements Runnable{

    @Override
    public void run() {
    System.out.println("开始拿茶叶");
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    throw new RuntimeException(e);
    }
    System.out.println("茶叶拿完了");
    }
    }
    class Finish implements Runnable{

    @Override
    public void run() {
    System.out.println("开始泡茶");
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e) {
    throw new RuntimeException(e);
    }
    System.out.println("茶泡完了");
    }
    }
    public class Tea {
    public static void main(String args[]) throws InterruptedException {
    Thread t1 = new Thread(new WashKettle());
    Thread t2 = new Thread(new HeatWater());
    Thread t3 = new Thread(new WashCup());
    Thread t4 = new Thread(new GetTea());
    Thread t5 = new Thread(new Finish());
    t1.start();
    t1.join();

    t2.start();

    t3.start();
    t3.join();

    t4.start();
    t4.join();

    t2.join();
    t5.start();
    }
    }

    /*
    开始洗水壶
    水壶洗完了
    开始烧水
    开始洗茶杯
    茶杯洗完了
    开始拿茶叶
    茶叶拿完了
    水烧完了
    开始泡茶
    茶泡完了
    */
  6. 阅读公众号“码农翻身”的文章—《我是一个线程》。

第 10 章 JavaIO

  1. Java中流的分类有哪些?

    1. 输入流、输出流
    2. 字节流、字符流
    3. 节点流、过滤流
  2. 字节流 InputStreamOutputStream的子类分别有哪些?请编程举例说明其使用场景。与其对应的字符流分别有哪些?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    public class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
    byte[] b = "hello".getBytes();

    //ByteArrayInputStream
    //字节数组和流之间的桥梁
    ByteArrayInputStream bais = new ByteArrayInputStream(b);
    int n = 0;
    while((n = bais.read())!=-1){
    System.out.print((char)n);
    }

    //FileInputStream
    //文件和流之间的桥梁
    try{
    FileInputStream rf = new FileInputStream("C:\\\\Users\\\\JMhhh\\\\Desktop\\\\hello.txt");
    int n2 = 512,c = 0;
    byte[] b2 =new byte[n2];
    while((c = rf.read(b2,0,n2))!=-1){
    String s = new String(b2,0,c);
    System.out.println(s);
    }
    rf.close();
    } catch (FileNotFoundException e) {
    throw new RuntimeException(e);
    } catch (IOException e) {
    throw new RuntimeException(e);
    }

    //PipedInputStream
    //一个程序的输出连接到另一个的输入
    PipedInputStream in = new PipedInputStream();
    PipedOutputStream out = new PipedOutputStream();
    in.connect(out);
    new Thread(new Input(in)).start();
    new Thread(new Output(out)).start();

    //ObjectInputStream
    //对象的序列化传输——恢复
    people p1 = new people("sda",10);
    ObjectOutputStream oout = new ObjectOutputStream(new FileOutputStream("C:\\\\Users\\\\JMhhh\\\\Desktop\\\\hello.txt"));
    oout.writeObject(p1);
    ObjectInputStream oin = new ObjectInputStream(new FileInputStream("C:\\\\Users\\\\JMhhh\\\\Desktop\\\\hello.txt"));
    people O = (people) oin.readObject();
    System.out.println(O.name);

    }

    }
    class people implements Serializable {
    public String name;
    public int old;
    public people (String name,int old){
    this.name = name;
    this.old = old;
    }
    }
  3. 字节流与字符流的转化是怎样的? Java对此提供了哪些支持?

    1. 提供了InputStreamReader 类和 OutputStreamWriter类为字节流和字符流之间实现相互转换。
    2. 前者将字节流解码成字符,后者将字符转成字节写入流
  4. Java中的过滤流(流的装配)有什么作用?请编程举例说明常用的过滤流。

    1. 功能:

      1. 可从字节流中写入,读取Java基本数据类型,不依赖机器的具体数据类型,方便存储和恢复数据

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(new FileOutputStream("C:\\Users\\JMhhh\\Desktop\\hello.txt")));
        dos.writeInt(3);
        dos.writeUTF("sda");
        dos.writeDouble(3.14);
        dos.close();

        DataInputStream dis = new DataInputStream(new BufferedInputStream(new FileInputStream("C:\\Users\\JMhhh\\Desktop\\hello.txt")));
        System.out.println(dis.readInt());
        System.out.println(dis.readUTF());
        System.out.println(dis.readDouble());
        dis.close();
      2. 用于缓存字符流,可以一行一行的读

        1
        2
        3
        4
        5
        BufferedReader bin = new BufferedReader(new InputStreamReader(System.in));
        for(int i=1;i<=3;i++){
        String s = bin.readLine();
        System.out.println(s);
        }
  5. 什么是对象的序列化和反序列化? Java 对此提供了哪些支持?对象序列化用于什么情形?请编程相关示例。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
            people p1 = new people("sda",10);
    ObjectOutputStream oout = new ObjectOutputStream(new FileOutputStream("C:\\Users\\JMhhh\\Desktop\\hello.txt"));
    oout.writeObject(p1);
    ObjectInputStream oin = new ObjectInputStream(new FileInputStream("C:\\Users\\JMhhh\\Desktop\\hello.txt"));
    people O = (people) oin.readObject();
    System.out.println(O.name);

    class people implements Serializable {
    public String name;
    public int old;
    public people (String name,int old){
    this.name = name;
    this.old = old;
    }
    }
  6. JavaFile类表示什么?有什么作用?

    1. 访问文件和目录,文件属性等

  7. Java对文件的读写分别提供了哪些支持?

    1. 文件输入输出流的类

第 11 章 网络编程

  1. 基于 TCP SocketC/S通信与基于 UDP数据报的 C/S 通信有哪些区别? Java分别提供了哪些支持
  2. 编写一个基于 TCP Socket套接字的 C/S聊天器程序。
  3. 编写一个基于 UDP数据报的 C/S聊天器程序。

泪和对象

  1. 对象和对象的引用
1
2
3
new dog();//创建对象,规划堆(heap)内存,没有引用则为孤儿,自动回收
dog dp;// 声明一个引用(不会生成对象,不会关联对象),存栈里
dp=new dog()//dg指向实际对象
  1. 参数传递
  • 简单类型作为变量参数
1
2
3
4
5
6
7
8
9
10
11
pubilc class ValuePass{
prinvate static int a;//静态数据-属于类
public static void main(Strring [] args){
modify(a);//方法引用,实参传入
System.out.println(a);
}
public static void modify(int a){
a++;
}
}
//输出0
  • 对象引用变量作为参数
1
2
3
4
5
6
7
8
9
10
11
12
13
class InsClass{
int value;
}
public class RunIntClass{
public static void modefyValue(IntClass s,int val){
s.value=val;
}
public static void main(String[] args{
IntClass s=new IntClass();// 分配堆空间
modifyValue(a,8);//分配栈空间
System.out.println(a.value);
}
}
  1. 数组对象
  • 声明格式
1
2
3
int [] arr;
Stiring [] ex;
//int []10] arr 是错误滴!
  • 数组初始化对象
1
int[] arr=new int[10];//在堆上为数组对象分配整型空间,默认为0;
  • 二维数组
1
2
int arr[][]//数组声明
arr=new int[3][4]//数组初始化
  1. Static 和 final 修饰符
  • static数据成员初始化:静态数据成员仅在类加载时进行初始化,且只执行一次初始化、首次访问某类的静态字段或静态方法是,会加载该类,并执行静态初始化语句

  • 静态方法:

1
2
3
4
5
6
7
8
9
class IntClass{
static int countNum(){
return num;
}
}

public static void main(String args[]){
System.out.println(IntClass.countNum());//首次访问加载该类
}
  • final修饰属性,则属性为常量
1
2
final int NUM=20;
NUM=30;//编译错误
  • final修饰方法,则该方法在子类当中不能被覆盖
1
2
3
4
5
6
class Parent{
public final voidmethod1(){}//这个方法不能被子类继承
}
class Child extends Parent{
public final void method1(){...}//编译错误
}
  • final修饰类,则该类不能被继承
1
2
3
4
5
6
class Parent{
}
final class Person entends Parent{
}//可以继承Parent类
class Child extends Person{
}//编译报错,不能继承Person类
  1. 包( package
1
2
3
4
5
6
//被访问
package com.resource;
//类访问权限与属性、方法访问权限需修改为public

//访问
import com.resource.FinghterPlane

第五章 封装、继承与多态

1
2
3
4
5
public void setName(String_name){
if(_name!=null){//提高安全性
name=_name.trim();
}
}

一、封装

  1. 访问权限控制符
    1. publc(公共访问权限)
    2. protected(包访问权继承访问权限)
    3. 无访问控制符修饰(默认为包访问权限)
    4. private(类内部访问权限)

二、继承

  1. 通过 extends 关键字实现
  2. 子类继承了父类的所有属性和方法,但只有 publicprotected的属性和方法在子类是可见的。

三、多态

  1. 多态的概念:多态是指一个程序中同名的不同方法共存情况

  2. Java中提供两种多态机制 重载 overloading与 覆写 overriding

    ​ a.重载:方法名称相同,参数类型或个数不同

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class stuMange{
    public int getScore(int i){
    return i;
    }
    public int getScore(Integer i){
    return i;
    }
    public int getScore(int ... i){//可能有多个参数
    return 3;
    }
    }
    p.getScore(5) //调用优先级:1>2>3

    ​ b.覆写:子类堆父类的同名方法重新进行定义。

    ​ (i)子类的访问修饰符权限应大于等于父类。

    ​ (ii)应该能够向上转型为父类的返回类型。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class Parent{
    Number getScore(int a){
    return Integer(7);
    }
    }
    class Son extends Parent{
    @override//帮忙检查是否覆写
    Number getScore(int b){
    return new INteger(8);
    }
    }

第六章 继承与多态

一、 thissuper

  1. this

    1. 主要应用场合:
      1. 表示当前对象引用,常用与形参或局部变量与类成员变量同名的情形,使用 this. 成员名表示当前对象的成员。
      2. 调用当前类的构造方法
  2. super 访问当前类的直接父亲,主要应用场合:

    1. 子类的数据成员或成员方法与父类的数据成员或成员方法名字相同时,当要调用父亲的痛,同名方法或同名数据成员时则可用 super.数据成员、成员方法。

    2. super (参数列表),表示现实调用父类构造方法,对子类对象中从父类继承过来的数据成员进行初始化。

    3. 显式使用 super 调用父类的构造方法

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      class AC{
      private int x=0,y=0,z=0;
      AC (int x){
      this.x=x;
      }
      }
      public class SonAC extends AC{
      int a=0,b=0,c=0;
      SonAC (int x){
      super(x);//调用父类构造方法
      a=x+7;
      }
      }
    4. 隐式使用 super 调用父类的构造方法

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      class Pare{
      int i=3;
      Pare(){
      System.out.println("call super()");
      }
      }
      class Construct extends Pare{
      int i=10;
      Construct(){
      System.out.println("execute Construct()");
      }
      Construct(int num){
      this();
      System.out.println("excute Construct(int));
      }
      public static void main(String[] args){
      Construct ct=new Construct(9);
      System.out.println(ct.i);
      }
      }
      //输出结果
      /*
      call super()
      ececute Construct()
      execute COnstruct()
      10
      */

二、抽象类

  1. 抽象类:用 abstract 修饰的类称为抽象类,用 abstract 修饰的成员方法称为抽象方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public abstract class A{
    private int m;
    public abstract void a();//抽象方法
    public abstract void b();//抽象方法
    public void c(){//非抽象方法可以调用抽象方法
    a();
    }
    }
    abstract class B extends A{
    @Override
    public void b(){}//仅实现抽象方法b()
    }
    class C extends B{
    @Override
    public void a(){}//实现抽象方法a()
    }
  2. 抽象类的应用:抽象类和具体类的关系就是一般类和特殊类之间的关系,在继承体系中对外提供抽象的子类公共的行为接口。

三、接口 interface

  1. 接口声明

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public interface InterfaceA {
    public static final int ON = 1;
    public abstract void a();
    }
    public interface InterfaceB {
    public abstract void b();
    }
    public interface InterfaceC extends InterfaceA, InterfaceB {
    public abstract void c();
    }
    public class InterfaceImp implements InterfaceC{
    @Override
    public void a() { //必须public,权限不能缩小
    System.out.println("call a()");
    }
    @Override
    public void b() {
    System.out.println("call b()");
    }
    @Override
    public void c() {
    System.out.println("call c()");
    }}

  2. 注意事项

    • 接口定义用关键字 interface,而不是用classinterface前的修饰符要么为public,要么为缺省。
    • 在类中,用implements关键字来实现接口。一个类可以实现多个接口,在implements后用逗号隔开多个接口的名字。一个接口也可被多个类来实现。
    • 接口具有继承性,可通过extends关键字声明接口的父接口列表。
    • 接口定义的数据成员全是public final static(静态常量),即使没有修饰符。存储在该接口的静态存储区域内,使用接口名.字段或实现类.字段均可访问。
    • 接口中没有构造方法;所有的抽象方法都是public abstract 方法(与抽象类有所不同)。即使没有修饰符,其效果完全等效。注:方法前不能修饰为final
    • 如果实现某接口的类不是abstract修饰的抽象类,则在类的定义部分必须实现接口的所有抽象方法,而且方法头部分应该与接口中的定义完全一致。
    • 如果实现接口的类是abstract类,则它可以不实现该接口的所有方法。但对于抽象类的任何一个非抽象的子类而言,接口中的所有抽象方法都必须实现。
    • 类在实现接口的抽象方法时,必须显式使用public修饰符,否则将被警告为缩小了接口中定义的方法的访问控制范围。
  3. 实现过程

    1. 定义接口

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      public interface  Washer {
      public static final int ON = 1 ;
      public static final int OFF = 0 ;
      abstract void startUp(); //启动
      abstract void letWaterIn(); //进水
      abstract void washClothes(); //洗衣
      abstract void letWaterOut(); //排水
      abstract void stop(); //停止
      }

    2. 实现接口

      1
      2
      3
      4
      5
      6
      7
      8
      class RoseBrand implements Washer{
      public void startUp(){ System.out.println("startUp");}
      public void letWaterIn(){System.out.println("letWaterIn");}
      public void washClothes(){System.out.println("washClothes");}
      public void letWaterOut(){System.out.println("letWaterOut");}
      public void stop(){System.out.println("stop");}
      public void dehydrate(){System.out.println("dehydrate ");}//脱水
      }
    3. 使用接口

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      public class Consumer {
      public static void main(String args[]){
      //接口声明引用实现接口的RoseBrand类的对象。
      Washer w = new RoseBrand();
      w.startUp();
      w.letWaterIn();
      w.washClothes();
      w.letWaterOut();
      w.stop();
      //w.dehydrate ();当通过接口调用玫瑰洗衣机类独有的,
      //接口未定义的功能方法,编译会报错。
      }
      }

抽象类与接口

相同点:二者都可具有抽象方法,都不能实例化,但都可以有自己的声明,并能引用子类或实现类对象。

不同点:

特性 抽象类 接口
组合 子类只能继承单一抽象类 实现类可以继承多个接口
属性 可以包含一般属性,非抽象方法可以引用这些属性 只有静态属性,不支持对象状态
方法 在子类中实现抽象方法 在实现类中实现抽象方法
构造器 可以有构造器 没有构造器
设计 is-a关系 can-do关系

内部类

  1. 定义:内部类就是在某个类的内部又定义了一个类。

  2. 实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    class Outer{
    private String index="The String is in Outer Class";
    public class Inner {
    String index="The String is in Inner Class";
    void print(){
    String index="The String is in print Method";
    System.out.println(index);
    System.out.println(this.index);
    System.out.println(Outer.this.index);
    }
    }//内部类Inner定义

    void print(){
    Inner inner = new Inner();
    inner.print();
    }

    Inner getInner(){
    return new Inner();
    }}


    public class TestOuterAndInner{
    {
    Outer outer = new Outer(); //先产生外部类对象
    //利用外部类对象引用.new语句创建内部类对象实例
    Outer.Inner inner = outer.new Inner();
    //利用外部类提供的getter方法创建内部类对象实例
    //Outer.Inner inner = outer.getInner();
    inner.print();
    }
    }

第七章 异常

  1. 异常分类

    1. Error:致命异常。需人工介入(虚拟机产生的错误:StackOverflowErrorOutOfMemoryError
    2. Exception:非致命异常。
  2. 异常处理

    1. 声明抛出处理:向调用方传播异常
      1. 显式声明抛出:throws语句
      2. 隐式声明抛出:throws语句可省略
    2. 程序捕获处理:在当前方法捕获处理异常
      1. 非嵌套:try/catch/finally语句
      2. 嵌套:同上

第八章 字符串——string

  • string 对象的构造与初始化

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    String s1 = "abc";
    String s3 = "abc";
    String s2 = new String(“abc");
    String s4 = new String(“abc");
    //“==”用于比较两个对象的引用是否相同
    System.out.println(s1==s2); // false
    System.out.println(s1==s3); // true
    System.out.println(s2==s4); // false

    // String对equals方法进行了覆写,可用于比较两个字符串的内容是否相同。
    System.out.println(s1.equals(s3)); // true
    System.out.println(s2.equals(s4)); // true
  • String 对象的特点

    • String对象是不可变的,在String类中每一个看起来会修改String对象内容的方法,实质都是创建了一个全新的String对象。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      public final class String   implements java.io.Serializable, Comparable<String>, CharSequence {
      /** The value is used for character storage. */
      private final char[] value; //常量字符数组对象引用

      public String concat(String str) {//字符串连接
      int otherLen = str.length();
      if (otherLen == 0) {
      return this;//返回当前对象
      }
      int len = value.length;
      char[] buf = Arrays.copyOf(value, len + otherLen);//拷贝之前的
      str.getChars(buf, len);//连接现在的
      return new String(buf, true); //创建新的对象
      }
    • StringBuffer : StringBuffer 对象的值是可变的,对字符串的增加、插入、修改、删除等操作比String高效(不需多次创建新的对象)。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      //StringBuffer源码
      public final class StringBuffer extends AbstractStringBuilder
      implements java.io.Serializable, CharSequence {

      //AbstractStringBuilder源码
      abstract class AbstractStringBuilder implements Appendable, CharSequence {
      /**
      * The value is used for character storage.
      */
      char[] value; //普通字符数组对象引用,被StringBuffer继承

      //AbstractStringBuilder源码
      public AbstractStringBuilder append(String str) {
      if (str == null)
      return appendNull();
      int len = str.length();
      ensureCapacityInternal(count + len); //有可能扩容,产生新数组
      str.getChars(0, len, value, count);
      count += len;
      return this;
      }

      //StringBuffer 源码
      @Override
      public synchronized StringBuffer append(String str) {
      toStringCache = null;
      super.append(str); //调用父类的append方法
      return this; //返回当前对象引用
      }
    • StringBUilder : JDK5 引入了 StringBuilder,其与 StringBuffer的 API兼容,性能比 StringBuffer更高,但不是线程安全的。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //String字符串拼接:
    String s = "a";
    for(int i=0; i<10000;i++){
    s = s + “b” ; //编译器会进行优化,但此种写法仍然效率低下,循环体内每次
    需要产生StringBuilder对象

    //StringBuilder字符串拼接:
    StringBuilder st = new StringBuilder("a"); //效率较高,只需新建一个对象
    for(int i=0; i<10000;i++){
    st.append(“b");
    }

    //字符串拼接,应使用StringBuilder或StringBuffer,并将对象创建语句放到循环体外
  • String 类的常用方法及源码学习

  • string 类的设计优点及使用场景

线程

创建线程—— Thread

1
public class Thread extends Object implements Runnable

方法一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import java.util.*;
class Adder extends Thread{
int[] datas=null;
public int total=0;
Adder(int[] _datas){
datas = _datas;
}
public void run(){
int sum=0;
for (int i=0;i<datas.length;i++){
sum += datas[i];
}
total = sum;
}
}

public class TestJoin {
public static void main(String args[]) {
Random rd = new Random();
int[] datas = new int[10000];
for(int i = 0; i < 10000; i++) {
datas[i] = rd.nextInt(Integer.MAX_VALUE);
}//生成1万个随机数
Adder a = new Adder(datas);
a.start();
try{
a.join();//等待a所引用的线程执行完毕
}
catch(InterruptedException it){
}
System.out.println(a.total);//获得a线程结果
}
}

方法二:

方法三:异步

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import java.util.*;
import java.util.concurrent.*;

public class FutureTasks {
public static void main(String args[]) {
Random rd = new Random();
int[] datas = new int[10000];
for(int i = 0; i < 10000; i++) {
datas[i] = rd.nextInt(Integer.MAX_VALUE);
}//生成1万个随机数

Adder a = new Adder(datas);
FutureTask<Integer> ft = new FutureTask<Integer>(a); //异步任务
new Thread(ft).start();

try {
//此处可以做其他事情
System.out.println(ft.get().intValue()); //获取异步结果
} catch (InterruptedException e){}
catch (ExecutionException e) {}
}
}
int[] datas=null;
Adder(int[] _datas){
datas = _datas;
}
public Integer call(){
int sum=0;
for (int i=0;i<datas.length;i++){
sum+=datas[i];
System.out.println(sum);
}
return Integer.valueOf(sum); }}

线程安全

  1. 数据单线程内可见
  2. 只读对象
  3. 线程安全类

如果多个线程想要对某个对象进行并发更新操作,但又不属于上述三类,此时需要考虑线程安全问题,在代码中实现安全同步机制。

  • 线程安全-访问共享资源问题

  • 线程安全问题-访问共享资源-可见性

  • 线程安全问题-访问共享资源-原子性

  • 解决线程安全问题:线程同步机制(互斥)

    • 对象监视器
      • 同步块又称临界区,保证同一时间只有一个线程执行同步块内的代码
      • 锁的范围尽可能小:能锁对象,就不要锁类;能锁代码块就不要锁方法。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    class Resource implements Runnable { 
    volatile public int i;
    volatile public Integer it;
    public Resource(int _i){
    i = _i;
    it = new Integer(i);
    }
    public void run(){
    while(true){
    synchronized(it){
    if (i>0){
    try{
    Thread.sleep(200);
    }
    catch(Exception e){}
    i--;
    System.out.println(Thread.currentThread().getName()+" "+i);
    }
    else{
    System.out.println(Thread.currentThread().getName());
    break; }}
    }}}

    public class TestSecurity{
    public static void main(String[] args){
    Resource m = new Resource(9);
    Thread t1 = new Thread(m);
    Thread t2 = new Thread(m);
    t1.start();
    t2.start();
    }
    }
    • Java并发包中的锁类

      • 死锁问题(dead lock)

        如果多个线程都处于等待状态,彼此需要对方所占用的监视器所有权,就构成死锁,Java即不能发现也不能避免死锁。

线程同步通信(协作)

第十章 I/O输入输出

流的分类

字节流与字符流

PNG image.png

流的装配与序列化

文件操作