Study - Java期末速成

N 人看过

关于Java考试的两天突击

请求记忆面包!

1 先导

1.1 JDK、JRE、JVM

  • JDK: Java标准开发包,提供了编译、运行Java程序所需的各种工具和资源,包括Java编译器、Java运行时环境,以及常用的Java类库等
  • JRE: Java运行环境,用于解释执行Java的字节码文件
  • JVM: Java虚拟机,是JRE的一部分,负责解释执行字节码文件,是可运行Java字节码文件的虚拟计算机

    三者关系:JDK(开发工具包) > JRE(运行环境) > JVM(Java虚拟机)

  • 区别联系:

    JDK包含JRE,JDK和JRE中都包含JVM。JDK除了包含JRE还包含一些常用开发工具和基础类库

    JDK用于开发,JRE用于运行Java程序

    JVM是Java编程语言的核心并具有平台独立性

1.2 开发Java程序的三个步骤

  1. 编写源程序(.java)
  2. 编译源文件生成字节码(.class)
  3. 加载运行字节码

注意:

  1. 一个Java源文件是由若干个类组成,最简单的只有一个类

  2. 源文件的命名规则:

    如果源文件中有多个类,那么只有一个类是 public 类源文件的名称必须与这个类的名字完全相同

  3. 一个Java应用程序必须要有一个类含有main方法,称为主类

    程序将从main方法开始执行

  4. 一个程序必须有至少一个输出!!

1.3 Java程序运行过程

  • javac: java源文件 —> class字节码文件(0,1)
  • java: 运行class文件
  • 过程:

    高级程序语言 -> 可执行文件(XX.exe) -> 操作系统执行Java源程序(XX.java)

    -> 字节码文件(XX.class) -> JVM

Java采用虚拟机技术、Java语言本身设计都体现出平台无关性

2 编程基础

2.1 Java的基本语法

  • 方法格式:

    权限修饰符 返回值声明 方法名称(参数列表) {
        方法中封装的逻辑功能;
        return 返回值;
    }
    
    public class Test {
        int add(intx, int y) {
            return x+y;
        }
    }
    
  • 权限修饰符:

    | | 类内部 | 本包 | 子类 | 外部包 |
    | ————- | ——— | —— | —— | ——— |
    | public | √ | √ | √ | √ |
    | protected | √ | √ | √ | × |
    | default | √ | √ | × | × |
    | private | √ | × | × | × |

  • 注释:

    1. 单行注释: //(文本)

    2. 多行注释: / (文本) /

    3. 文档注释: /*(文本)

      ​ *(文本)

      ​ *(文本)

      ​ */

  • 关键字:

    Abstract、default、if、package、this、Boolean、do、implements、private、

    throw、Break、double、import、protected、throws、Byte、else、instanceof、

    public、transient、Case、false、interface、short、try、Catch、final、long、

    static、void、Char、finally、native、super、volatile、 Class、float、new、

    switch、while、Continue、for、null、synchronized

  • 标识符:
    1. 由字母、数字、下划线和美元符号组成
    2. 不能以数字开头
    3. 不能是Java中的关键字

2.2 变量、常量

  • 变量的定义:
    1. 按所属类型划分:基本数据类型、引用数据类型
    2. 按声明位置划分:局部变量(方法或语句块内部定义的变量)、成员变量(方法外部、类的内部定义的变量)
  • 变量的基本数据类型:
类型 包含 所占字节
整型 long、int、short、byte 8、4、2、1
浮点型 float、double 4、8
字符型 char 2
布尔型 boolean 1
byte 1

Java三种进制的表示方式:

  1. 十进制:0-9表示,首位不能为0
  2. 八进制:0-7表示,以0为前缀,如:013、027
  3. 十六进制:0-9、a-f或A-F之间的字母表示的数,以0x或0X为前缀,如0xA3、0x1b
  • 变量的引用数据类型:

    1. 字符串(String)
    2. 数组类型
    3. 接口(interface)
    4. 类(class)
  • 变量的类型转换:

    1. boolean类型不能转换成任何其他数据类型

    2. 自动类型转换规则:

      byte,short,int -> floot -> long -> double

    3. 强制类型转换规则:

      (转换类型)转换变量

  • 常量的定义:

    在变量前加上修饰符final

    final [修饰符] [类型标识符] 常量名 = (直接)常量;
    

2.3 运算符

运算类型 符号
算术运算 + - * / % ++ —
赋值运算 =
关系运算 > < >= <= == !=
逻辑运算 ! & \ ^ && \ \
条件运算 XX ? X : X
  • 常用数学函数:

    //abs()方法:返回被操作数的绝对值
    int x = Math.abs(50);                //返回50
    float x = Math.abs(-36.8);           //返回36.8
    
    //pow(double y, double x)方法:返回y^x
    Math.pow(8, 2);                      //返回64.0
    
    //round()方法:返回最接近操作数的整数
    //对正数是四舍五入,对负数是四舍五不入
    Math.round(11.5);                    //返回12
    Math.round(-11.5);                   //返回-11
    
    //sqrt(double x)方法:返回操作数的平方根
    Math.sqrt(4.0);                      //返回2.0
    
    //max()方法:返回两个操作数中较大的一个
    Math.max(100.2, 203.5);              //返回203.5
    
    //min()方法:返回两个操作数中较小的一个
    Math.min(100.2, 203.5);              //返回100.2
    
    //random()方法:产生0-1之间的随机数,为double类型
    int a = (int)(Math.random()*10);     //返回0-10之间的随机整数
    
  • 输入输出数据java.util.Scanner

    import java.util.Scanner                       //从包java.util中导入Scanner类
    public class ClassName {
        poblic static void main(String[] args) {
            Scanner s = new Scanner(System.in);    //创建一个Scanner对象
            double d = s.nextDouble();             //输入浮点数
            int i = s.nectInt();                   //输入整数
            String str1 = s.nextLine();            //输入字符串,回车为分隔符
            ……
            s.close();
        }   
    }
    

2.4 选择与循环

  • 选择语句:

    if
    else if
    if
    
    /**********/
    
    switch() {
        case 1: XX; break;
        case 2: XX; break;
        default (可有可无): XX; break;
    }
    
  • 循环语句:

    while
    
    /**********/
    
    for
    
    /**********/
    
    do while
    
    /**********/
    
    for(总的每一个元素的数据类型 别名 : 要遍历的总的) {
        操作这个别名
    }
    
    //for each举例:
    int a[] = new int[]{1,2,3,4,5,6,7};
    for(int a1 : a) {
        System.out.println(a1);
    }
    

2.5 数组

数组不允许在前面的括号中书写元素个数!!

  • 多维数组初始化的3种方式:

    1. 动态初始化方式1、方式2

      int[][] arr1 = new int[3][];    //行必须要写,列可以省略
          arr1[0] = new int[3];       //第0行有3列
          arr1[1] = new int[2];       //第1行有2列
          arr1[1] = new int[1];       //第2行有1列
      
      /**********/
      
      int[][] arr2 = new int[3][2];
          arr[0][0] = 33;
      
    2. 静态初始化方式3

      int arr3[][] = new int[][]{{1,2,3},{4,5}};
      
  • 数组的常见操作:

    1. 声明数组:

      int arr[];
      
    2. 数组初始化:

      int [] arr = {1,2,3,4};
      int [] arr = new int[]{1,2,3,4};
      
    3. 查看数组长度:

      arr.length;
      
    4. for each循环:

      for(int a : arr) {
          System.out.println(a);
      }
      
    5. 数组拷贝:

      int [] arr2 = arr1;
      int [] arr2 = Arrays.copy0f(arr,arr.length(自定义长度));
      
    6. 数组排序:

      Arrays.sort(arr);
      
    7. 将int数组转换为字符串:

      Arrays.toString(arr);
      

2.6 输入输出

  • 输入:

    Scanner s = new Scanner(System.in);
    s.next()          //获取字符串
    s.nextInt()       //获取整型
    s.nextLine()      //获取字符串
    s.nextFloot()     //获取浮点型
    ……
    
  • 输出

    System.out.print("XX");       //无自动换行
    System.out.println("XX");     //有自动换行
    

2.7 类与对象

  • 三大特征:封装、继承、多态
  • 封装:

    1. 通过privatedefaultprotectedpublic关键字实现属性或者方法的封装,仅对外提供公共访问方式
    2. 高内聚,低耦合

    封装的好处:

    1. 实现数据项和方法的隐藏
    2. 实现隐藏隔离,允许外部对类做有限的访问,开发者可以自由的改变类的内部实现
    3. 提高了代码的重用性
    public class Student {
        private String username;
    
        public String getUsername() {
            return username;
        }
    
        public void setUsername(String username) {
            this.name = username;
        }
    }
    
    class Test {
         public static void main(String[] args) {
             Student student = new Student();
             student.setUsername("张三");
             student.getUsername();
             System.out.println(username);
         }
    }
    
  • 继承:

    1. 通过extends关键字实现

    继承的好处:

    1. 代码重用了
    2. 通过继承实现了对现实世界更加准确的建模
  • 多态:

    1. 一个对象变量可以指向多种实际类型对象的现象被称为“多态”
    2. 三个必要条件:继承、方法重写、父类引用指向子类对象
    3. Java中多态的实现方法:接口实现、继承父类进行方法重写、同一个类中进行方法重载、父类引用指向子类对象

多态的好处:

  1. 提高了代码的维护性(继承保证),提高了代码的扩展性
  • 实例化(对象的创建)

    /**通过new关键字进行创建**/
    Student zhangchunhui = new Student();
    zhangchunhui.setAge = 20;
    
  • 实例化(的创建)

    /**类的定义格式**/
    [修饰符] class 类名 [extends 父类名] [implements 接口名] {
        //类体,包括类的成员变量和成员方法
    }
    
    /**通过定义格式进行创建**/
    class Test extends Student implements UserDao {
         public static void main(String[] args) {
             Student student = new Student();
    
             student.setUsername("张三");
             student.getUsername();
             System.out.println(username);
         }
    }
    
    /**类体语句介绍**/
    class Stu {
        //1 属性设为私有
        private int age;
    
        //2 构造函数
        public Stu() {           //无参构造
    
        }
        public Stu(int age) {    //全参构造
            this.age = age;
        }
    
        //3 方法 get、set 自主定义
        public void setAge(int age) {
            this.age = age;
        }
        public int getAge() {
            return this.age;
        }
    
        //4 自定义方法
        public void myPrint() {
            System.out.println("nihao");
        }  
    }
    

2.8 继承性

  • object类:

    1. object类是所有类的父类,里面有很多方法,如:

      | 方法 | 作用 |
      | ————- | —————————————————————————————— |
      | getClass | 获取运行时类型,返回值为Class对象 |
      | hashCode | 返回该对象的哈希码值,是为了提高哈希表的性能 |
      | equals | 判断两个对象是否相等,在object源码中equals就是使用==去判断,所以在object中equals是等价于==的。但是在String及某些类对equals进行了重写,实现不同的比较 |
      | clone | 主要是Java里除了8种基本类型传参数是值传递,其他的类对象传参数都是引用传递,我们有时候不希望再方法里将参数改变,这就需要在类中复写clone方法
      如果在clone方法中调用super.clone()方法需要实现Cloneable接口,否则会抛出CloneNotSupportedException
      此方法只实现了一个浅层拷贝,对于基本类型字段成功拷贝,但是如果是嵌套对象,只做了赋值,也就是只把地址拷贝了,所以没有成功拷贝,需要自己重写clone方法进行深度拷贝 |
      | toString | 返回一个String字符串,用于描述当前对象的信息,可以重写返回对自己有用的信息,默认返回的是当前对象的类名+hashCode的十六进制数字 |
      | wait | 多线程时用到的方法,作用是让当前线程进入等待状态,同时也会让当前线程释放它所持有的锁,直到其他线程调用此对象的notify()方法或者notifyAll()方法,当前线程被唤醒 |
      | notify | 多线程时用到的方法,唤醒该对象等待的某个线程 |
      | notifyAll | 多线程时用到的方法,唤醒该对象等待的所有线程 |
      | finalize | 对象在被GC释放之前一定会调用finalize方法,对象被释放前最后的挣扎,因为无法锁定该方法什么时候被调用、减少使用 |

  • 类的继承格式:

    class 父类 {
        //类体
    }
    
    class 子类 extends 父类 {
        //类体
        //方法重写
    }
    
    //定义父类
    public class Parent {         
        private int age;
        public String name;
    
        public Parent() {
    
        }   
        public Parent(int age) {
            this.age = age;
        }
    
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
    
        public void myParent() {
            System.out.println("我是父类的myParent方法");
        }   
    }
    
    //定义子类继承父类
    class Son extends Parent {    
    
        //子类对父类的方法重写!
        public void myParent() {
            System.out.println("我是子类重写的myParent方法");
        }
    
        public static void main(String[] args) {
            Son son = new Son();
            son.name = "zhangsan";
            son.myParent();
        }
    }
    

子类只能继承父类非私有的方法和属性!!!

2.9 类的封装

封装目的:

将类的某些信息隐藏在类的内部,不允许外部程序直接访问,而是通过该类提供getXXsetXX的方法来对隐藏的信息进行操作和访问

  • 封装的实现步骤:

    1. 修改属性的可见性设为private

    2. 创建getXXsetXX方法(用于属性的读写),通过这两种方法对数据进行获取和设定,对象通过调用这两种方法实现对数据的读写

    3. getXXsetXX方法中加入属性控制语句(对属性的合法性进行判断)

      public class Person {
          private String name;
          private int age;
      
          public int getAge() {
              return age;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public void setAge(int age) {
              if(age < 0) {
                  System.out.println("你的年龄不合法,请重新输入");
              }
              else {
                  this.age = age;
              }
          }
      }
      
      class Test2 {
          public static void main(String[] args) {
              Person person = new Person();
              person.setAge(-1);
              person.setName("张三");
              System.out.println(person.getName());
              System.out.println(person.getAge());
          }
      }
      

2.10 构造方法

  • 构造方法的定义:

    主要用于在创建对象时初始化对象,即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中,一个类可以有多个构造函数,可根据其参数个数的不同或参数类型的不同来区分它们,即构造函数的重载。

  • 构造方法的重载:

    public class Person {
        private String name;
        private int age;
    
        //以下是构造方法 
        public Person() {                         //无参构造
    
        }
        public Person(String name) {              //有参构造
            this.name = name;
        }
        public Person(int age) {
            this.age = age;
        }
        public Person(String name, int age) {     //全参构造
            this.name = name;
            this.age = age;
        }
    
        public int getAge() {
            return age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    }
    
    class Test2 {
        public static void main(String[] args) {
            //有参构造引用
            Person person = new Person();
            person.setage(22);
            person.setName("zhangsan");
    
            //全参构造引用(推荐使用)
            Person person = new Person("zhangsan", 22);
        }
    }
    

2.11 方法的重载和重写

  • 重载的概念:

    1. 必须重载在同一个类中

    2. 方法名应相同

    3. 方法的参数的个数、顺序或类型不同

    4. 与方法的修饰符或返回值没有关系

      public void Parent {
          ……
      
          public void myPrint() {
              System.out.println("我是父类原方法");
          }
      }
      
      class Son extends Parent {
          ……
      
          public void myPrint() {
              System.out.println("我是父类重写的方法");
          }
      
          private int myPrint(String name) {
              System.out.println("我是Son类中重载的方法1");
              return 1;
          }
      
          private int myPrint(int age) {
              System.out.println("我是Son类中重载的方法2");
              return 1;
          }
      
          private int myPrint(int age, String name) {
              System.out.println("我是Son类中重载的方法3");
              return 1;
          }
      
          private void myPrint(String name, int age) {
              System.out.println("我是Son类中重载的方法4");
          }
      }
      
  • 重写的概念:

    当父类中的方法无法满足子类需求的时候,需要方法重写

  • 方法重写的注意事项:

    1. 重写的方法必须要和父类一模一样(包括返回值、方法名、参数列表)

    2. 重写的方法可以使用@Override注释来标识

    3. 子类中重写的方法的访问权限不能低于父类中方法的访问权限

      权限修饰符:public > protected > default(或者不写) > private

      public vlass Parent {
          protected void myPrint() {
              Systemm.out.println("我是父类方法");
          }
      }
      
      class Son extends Parent {
          protected void myPrint() {
              Systemm.out.println("我是子类方法");
          }
      }
      
      class Test {
          public static void main(String[] args) {
              Son son = new son;
              son.myPrint();
          }
      }
      

重写和重载的区别:

  1. 重载:在同一个类中,出现多个同名的方法,参数列表不同,与返回值类型、修饰符无关
  2. 重写:子类中出现和父类一模一样的方法(包括返回值类型、方法名、参数列表)

2.12 this、super关键字

  • Java中为了解决变量的命名冲突和不确定性问题,引入关键字this代表其所在方法的当前对象的引用
  • 使用情况:

    /**构造方法中指该构造器所创建的新对象**/
    public class B {
        A a;     //A是一个类
    
        public B(A a) {
            this.a = a;
        }
    }
    
    /**方法中指调用该方法的对象**/
    public class Baby {
        public void wakeUp() {
            System.out.println("宝宝醒啦");
        }
        public void eat() {
            this.wakeUp();
            System.out.println("吃东西");
        }
    }
    
    /**在类本身的方法或构造器中引用该类的实例变量(全局变量)和方法**/
    public void setName(String name) {
        this.name = name;
    }
    

    注意:

    1. this只能在类中的非静态方法(无static修饰)中使用,静态方法和静态的代码块中绝对不能出现this

      (原因:static方法在类加载时就已经存在了,但是对象是在创建时踩在内存中生成)

  • super关键字主要存在于子类方法中,用于指向子类对象中的父类对象,可以访问父类的属性、函数以及构造函数

    1. 子父类存在着同名的成员(包括变量和方法)时,在子类中默认是访问子类的成员,可以通过super关键字指定访问父类的成员
    2. 默认会先调用父类无参的构造方法,可以通过super关键字指定调用父类的构造方法
    public vlass Parent {
        protected void myPrint() {
            Systemm.out.println("我是父类方法");
        }
    }
    
    class Son extends Parent {
        protected void myPrint() {
    
            //此处使用super指向父类方法,最终此语句输出结果为"我是父类方法"
            super.myPrint();
    
            Systemm.out.println("我是子类方法");
        }
    }
    

2.13 static、final关键字

  • static静态变量

    private static String str1 = "static Property";
    
  • static静态代码块

    static {
        static int a = 3;
    }
    

注意:

  1. 被static修饰的变量属于类变量,可以通过类名、变量名直接引用,而不需要new一个类
  2. 被static修饰的方法属于类方法,可以通过类名、方法名直接引用,而不需要new一个类
public class Parent {
    static {
        int a = 3;
    }

    private static String name = "zhangsan";

    public static void myPrint() {
        System.out.println("我是父类的静态方法");
    }
}

calss Test {
    public static void main(String[] args) {
        //Static修饰的变量或方法可以直接调用
        Parent.myPrint();
    }
}
  • final关键字:

    1. final修饰的类,不能被继承

    2. final修饰的方法,不能被重写,但是子类可以用父类中final修饰的方法

    3. final修饰的变量,不能被改变

      但final修饰引用类型变量(String、数组类型、接口、类)时,引用变量引用不可变,但是引用对象的内容可变

      final class A {
          public int a = 3;
      }
      
      public class Test {
          public static void main(String[] args) {
              A a = new A();
              a.a = 3;
              a.a = 4;
          }
      }
      

2.14 抽象类

  • 使用abstract关键字修饰

    1. 抽象类内可以包含普通变量、公共静态变量、普通方法、抽象方法
    public abstract class Action {
    
        public String username;              //普通变量
        int a = 3;
    
        public static int age = 33;          //公共静态方法
    
        public void myPrint() {              //普通方法
            System.out.println("nihao");
        }
    
        public abstract void doSomething();  //抽象方法(不能含有方法体)
    
    }
    

抽象类中的抽象方法不能被直接继承引用,必须经过重写!!!!!

public abstract class Action {

    public abstract void doSomething();  //抽象方法(不能含有方法体)

}

class Son extends Action {
    @Override
    public void doSomething() {
        System.out.println("nihao");
    }
}

2.15 接口

  • 使用interface关键字修饰,使用implements关键字修饰

    1. 接口中的所有定义的方法都是public abstract抽象方法

      可以省略抽象方法关键字,系统会自动默认为抽象方法

    2. 接口中的变量只能是public static final

      可以省略公有静态常量关键字,系统会自动默认为公有静态常量

    public interface UserDao {
        //等效于 public static final int age = 33;
        int age = 33;
    
        //等效于 public abstract void myPrint();
        void myPrint();
    
        //等效于 public abstract int insert();
        int insert(A a);
    }
    
    public class UserTest implements UserDao {
    
        //注意,继承接口中所有抽象方法都需要重写!!
        public void myPrint() {
            System.out.println("nihao");
        }
        public int insert(A a) {
            System.out.println("新增");
        }  
    }
    

接口和抽象类的区别:

  1. 接口要被子类实现,抽象类要被子类继承
  2. 接口中变量全为公共静态变量,而抽象类中可有普通变量
  3. 接口中全为方法的声明,而抽象类中可以有方法的实现
  4. 接口中不可以有构造函数,而抽象类中可以有构造函数
  5. 接口可多实现,而抽象类必须被单继承
  6. 接口中方法全为抽象方法,而抽象类中也可以有非抽象方法

2.16 多态

  • 多态性指同一名字的方法可以有多种实现方式(即不同的方法体)

    1. 利用重载,在同一类中定义多个同名的功能不同的方法
    2. 通过子类对父类的方法进行重写
  • 多态重写时处理规则:

    1. 首先从对象所属类开始,寻找匹配的方法
    2. 如果当前类中没有匹配的方法,则依此在父类、祖先类中寻找匹配方法

2.17 异常处理

  • 常见的异常类型:

    | 异常 | 说明 |
    | ——————————————- | ——————————————————————————- |
    | Exception | 异常层次结构的根类 |
    | RuntimeException | 许多 java.lang 异常的基类 |
    | ArithmeticException | 算术错误情形,如以零作除数 |
    | IllegalArgumentException | 方法接收到非法参数 |
    | ArrayIndexOutOfBoundException | 数组大小小于或大于实际的数组大小 |
    | NullPointerException | 尝试访问 null 对象成员 |
    | ClassNotFoundException | 不能加载所需的类 |
    | NumberFormatException | 数字转化格式异常,比如字符串到 float 型数字的转换无效 |
    | IOException | I/O 异常的根类 |
    | FileNotFoundException | 找不到文件 |
    | FileNotFoundException | 文件结束 |
    | FileNotFoundException | 线程中断 |

  • 异常处理语句:

    try {
        //语句1,可能产生异常的代码
    }
    catch(ExceptionType e) {
        //语句2,捕获某种异常对象进行处理的代码
        //catch语句至少有一个,可以有多个
    }
    finally {
        //语句3,必然要执行的代码
        //finally语句可以省略
    }
    

2.18 Java的常用类库(包)

  • 包是一组相关的接口的集合,将类和接口分装在不同的包中,可以:

    1. 避免重名类的冲突
    2. 限定包之间类的访问权限
    3. 更有效地管理众多的类和接口
  • 使用包的过程:

    1. 先建立与包名相同的文件夹
    2. 再声明类或接口所在的包
    3. 包中所含的类或接口的字节码文件存放于与包同名的文件夹中
    4. 在程序中导入包中包含的类或接口
  • 包的声明:

    1. 包名与文件夹名字的字母大小写要一致
    2. 该语句必须位于程序第一行,且一个源程序只能有一条package语句
    3. 子包、父包、祖先包名之间用” . “隔开
    package 包名;
    
    package mypackage;         //包的名字为mypackage
    
    public class Cpoint {      //文件名为Cpoint.java
        //类体
    }
    
    class CCircle {
        //类体
    }
    
    //Person接口和Teacher类属于subpack包
    //subpack是mypackage的子包
    
    package mypackage.subpack
    
    public interface Person {
        //接口体
    }
    
    class Teacher implements Person {
        //类体
    }
    
  • 包中类或接口的引用:

    /**引用格式**/
    包名.类名
    包名.接口名
    
    public class Cline extends mypackage.Cpoint{
        //类体
    }
    
    public class Graduate implements mypackage.subpack.Person {
        //接口体
    }
    
    //声明类对象
    mypackage.Cpoint point
    
    //实例化Cpoint类
    point = new my.package.Cpoint
    
  • 导入包中的类或接口:

    /**引用格式**/
    import 包名.类名
    import 包名.接口名
    import 包名.*
    
    //导入Java中的util包中的所有的类和接口
    import java.util.*
    

2.19 多线程

进程和线程的区别:

  1. 进程:

    是指一个内存中运行的应用程序,每个进程都有一个独立的内存空间。并且进程互不共享内存空间,除非通过特殊手段。程序就是进程,例如:电脑的各个图标

  2. 线程:

    是进程中的一个执行路径,共享一个内存空间,线程之间可以自由切换,并发执行,一个进程最少有一个线程。

    线程实际上是在进程基础之上的进一步划分,一个进程启动之后,里面的若干执行路径又可以划分成若干个线程。

    用到哪一个哪一个被唤醒,例如:和多人聊天 sleep 生产者和消费者

2.20 文件IO操作

  • 在Java中将信息的输入与输出过程抽象为IO流
  • Java标准输入输出:

    | 对象 | 说明 |
    | ————— | —————————————————————————————— |
    | System.in | 字节输入流InputStream类的一个对象
    public int read() throws IOException
    public int read(byte[] b) throws IOException |
    | System.out | 流PrintStream类的一个对象,其中print和println方法向屏幕输出数据 |
    | System.err | 流PrintStream类的一个对象,用于向屏幕输出错误信息 |

  • 输入流(InputStream)方法

    1. 三个基本read()方法

      int read();           //读一个字节返回
      int read(byte[]);     //将数据读入byte[],返回读的字节数
      int read(byte[], int offset, int length);
      
    2. 其他方法

      void close();         //关闭流
      int available();      //返回未读的字节数
      long skip(long n);    //跳过n个字节
      
  • 输出流(OutputStream)方法

    1. 三个基本write()方法

      void write(int);      //写一个字节
      void write(byte[]);   //写一个字节数组
      void write(byte[], int offset, int length);
      
    2. 其他方法

      void close();         //关闭流
      void flush();         //强行写
      
  • 字节文件输入输出:

    1. 创建文件输入输出流的对象

      FileInputStream构造方法:

      /**基本格式**/
      public FileInputStream(String name) throws FileNotFoundExpection
      public FileInputStream(File file) throws FileNotFoundExpection
      
      /**创建对象**/
      FileInputStream rf = new FileInputStream("d:/java/pro1.java");
      

      FileOutputStream构造方法:

      /**基本格式**/
      public FileOutputStream(String name) throws FileNotFoundExpection
      public FileInputStream(File file) throws FileNotFoundExpection
      public FileOutputStream(String name, Boolean append) throws FileNotFoundExpection
      
      /**创建对象**/
      FileOutputStream wf = new FileOutputStream("d:/java/pro2.java");
      
    2. 打开文件

    3. 用文件读写方法读写数据

      ead方法读取文件数据:

      //返回从文件中读取的一个字节
      public int read() throws IOException
      
      public int read(byte[] b) throws IOException
      
      //返回读取的字节数,若b的长度为0,返回0
      public int read(byte[], int off, int len) throws IOException
      

      write方法读取文件数据:

      //向文件写入一个字节,b是int类型,所以将b的低8位写入
      public void write(int b) throws IOException
      
      public void write(byte[] b) throws IOException
      
      //将字节数组写入文件,其中off是b中的起始位置,len是写入的最大长度
      public void write(byte[] b, int off, int len) throws IOException
      
    4. 关闭数据流

      public void close() throws IOException
      
  • 文件的基本用法:

    1. File给出的构造函数:

      public File(String path) {
          //如果path是实际存在的路径,则该File对象表示的是目录
          //如果path是文件名,则该File对象表示的是文件
      }
      
      public File(String path, String name) {
          //path是路径名,name是文件名
      }
      
      public File(File dir, String name) {
          //dir是路径名,name是文件名
      }
      
    2. 文件名的处理:

      String getName();             //得到一个文件的名称(不包括路径)
      String getPath();             //得到一个文件的路径名
      String getAbsolutePath();     //得到一个文件的绝对路径名
      String getParent();           //得到一个文件的上一级目录名
      
    3. 文件属性测试:

      boolean exists();             //测试当前File对象所指示的文件是否存在
      boolean canWrite();           //测试当前文件是否可写
      boolean canRead();            //测试当前文件是否可读
      boolean isFile();             //测试当前文件是否是文件(不是目录)
      boolean isDirectory();        //测试当前文件是否是目录
      boolean createNewFile();      //创建文件
      boolean mkdir();              //创建文件夹
      boolean listFiles();          //列出文件夹下面的所有子文件
      

2.21 图形用户界面(GUI)设计

  • 在Java中,GUI组成元素都放在java.awtjava.Swing包中,他们都包含了大量的类
  • GUI构成包括:

    | 成分 | 介绍 |
    | :————————- | —————————————————————————————— |
    | 容器(container) | 用来组织和容纳其他界面成分和元素的组件
    Java提供了相应的容器类,包括:框架(JFrame/Frame)、面板(JPanel/Panel)、滚动面板(IScrollPanel/ScrollPanel)等 |
    | 组件(components) | 组件是GUI的基本单位,里面不再包含其他成分
    组件是一个可以以图形化方式显示并进行交互的对象,包括:按钮、标签等等
    组件不能独立显示,必须将组件放到一定的容器里才能显示 |
    | 用户自定义成分 | 只起到显示结果、装饰美化的作用
    不能响应用户的动作,不具有交互功能 |

  • 使用AWT步骤:

    1. 创建容器组件(如Frame、Panel等),在容器中添加需要的其他组件(如Button、Label、TextField、Checkbox等)
    2. 创建布局管理器,用来自动设置容器中组件的位置和大小
    3. 使用委派事件模型来响应用户操作,实现用户和程序的交互

    | 类名 | 常用构造方法 | 主要功能 |
    | ————- | —————————————————————— | ————————————————————— |
    | Label | Label(String title) | 标签,主要用来显示信息 |
    | TextField | TextFiled()
    TextFiled(int m) | 文本框,用来接收用户输入,只能接收一行输入 |
    | TextArea | TextArea()
    TextArea(int rows, int cols) | 文本区域,用来接收用户输入,可接收多行输入 |
    | Button | Button()
    Button(String title) | 按钮,用来捕捉用户操作的简单组件 |
    | Checkbox | Checkbox()
    Checkbox(String title) | 复选框,用于多选项输入 |

  • 使用Swing步骤:

    1. 用来构成一个图形化界面的“各种元素”

      如:按钮、标签、树、表格、框架等

    2. 结构划分,通常有两种类型:

      | 类型 | 说明 |
      | ——————- | —————————————————————————————— |
      | Window 类 | 包括一些“可独立显示”的组件
      指无需托付在其他组件上就可以直接显示,如JFrame类等 |
      | JComponent 类 | 包括一些“不可独立显示”的组件
      指必须依靠可独立显示的组件才能显示,如文本框、按钮等 |

    3. 功能划分,通常有三种类型:

      | 类型 | 说明 |
      | —————————————————————— | —————————————————————————————— |
      | 顶层组件/容器 | 可理解为Window类,指能独立显示的组件
      如:JFrame、JApplet、JDialog、JWindow |
      | 中间组件
      (分为中间容器和特殊中间组件) | 指可充当载体,但不能独立显示的组件,可承载基本组件,但同时必须依托顶层组件
      如:JPanel、JScrollPane、JSplitPane、JtoolBar
      其中特殊容器仅起到美化和专业化作用
      如:JInternalFrame、JLayeredPane、JRootPane |
      | 基本组件 | 指主要用与实现人机交互的组件,不能独立存在
      如:JButton、JComboCox、JList、JMenu、JSlider、JTextField |

    /**基本组件**/
    import javax.swing.*;
    
    public class HelloWorld {
        public static void main(String[] args) {
            JFrame frame = new JFrame("测试窗口");              //创建顶层容器
            JPanel pane = new JPanel();                        //创建中间容器
            frame.setContentPane(pane);                  //将中间容器依托在顶层容器
            JButton button = new JButton("这是一个测试按钮");     //创建一个基本组件
            pane.add(button);                            //将基本组件依托在中间容器
            frame.setBisible(true);
        }
    }
    

大多数Java程序都使用JFrame组件作为顶层容器,一般也有使用JDialog和JApplet

注:JDialog 一般作为弹出窗口使用,而 JApplet 一般作为嵌在网页中的小程序框架使用

2.22 事件

  • 低级事件

    ComponentEvent        //组件事件:组件尺寸的变化,移动
    ContainerEvent        //容器事件:组件增加,移动)
    WindowEvent           //窗口事件:关闭窗口,窗口闭合,图标化 
    FocusEvent            //焦点事件:焦点的获得和丢失
    KeyEvent              //键盘事件:键按下、释放
    MouseEvent            //鼠标事件:鼠标单击,移动
    
  • 高级事件(语义事件)

    ActionEvent           //动作事件:按钮按下,TextField中按Enter键
    AdjustmentEvent       //调节事件:在滚动条上移动滑块以调节数值
    ItemEvent             //项目事件:选择项目,不选择"项目改变"
    TextEvent             //文本事件,文本对象改变
    



ENDING
感兴趣可以分享给身边的小伙伴哦!

本作品采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 (CC BY-NC-ND 4.0) 进行许可。