java 基础

  1. java开发入门
    1. java概述
    2. 标识符
    3. java中的变量与常量
      1. 变量
        1. 变量的数据类型
      2. 常量
  2. java编程基础
    1. 基本语句
      1. 选择结构语句
        1. if语句
      2. switch条件语句
      3. 循环语句
        1. for语句
        2. while语句
        3. do···while语句
        4. 循环嵌套语句
        5. 跳转语句
    2. 数组
      1. 数组的定义
      2. 数组赋值
      3. 初始值
  3. 面向对象(1)
    1. 面向对象的概论
    2. 类与对象的的关系
    3. 定义类、成员变量和方法
      1. 定义类
      2. 定义成员变量
      3. 成员方法
      4. 构造方法
    4. 创建并使用对象
      1. 创建对象
      2. 通过对象调用成员
    5. 对象和引用
      1. 了解堆内存、栈内存
      2. 对象、引用和指针
    6. this 关键字
    7. 方法
      1. 方法的所属性
      2. static特点
      3. 方法的传参机制
      4. 参数个数可变的方法
      5. 递归方法
    8. 重载
      1. 重载的概念
    9. 成员变量和局部变量
      1. 根本区别
      2. 初始化使用区别
    10. 封装
      1. 权限控制符
      2. private 私有的
      3. 其他
    11. 构造方法
      1. 构造方法的组成
      2. 构造方法的特点
      3. 构造方法的练习
    12. static (静态)关键字
      1. static 作用
      2. static特点
  4. 面向对象(2)
    1. 类的继承
    2. 重写
      1. 重写的概念和使用
    3. super
      1. super的作用
      2. 使用方法
    4. Object类
    5. Object概念
    6. final 关键字
      1. final的概念
      2. final的特点
    7. 4.6 Lambda 式编程
      1. 4.6.1 了解Lambda
      2. 4.6.2 函数式接口
      3. 4.6.3 方法引用与构造器引用
    8. 多态
      1. 抽象类
      2. 接口和抽象类的区别
    9. 4.7 异常
      1. 4.7.1 什么是异常
      2. 4.1.2 异常的类型
  5. java中的常用类
  6. 集合
  7. I/O流
    1. 输出流
    2. 输入流
    3. 输入流和输出流一起使用实现文件的复制
    4. 字节缓冲流
      1. 带缓冲区的输入输出流
      2. 不带缓冲区的输入输出流
  8. GUI(图形用户接口)
  9. 多线程
  10. 第十章 多线程
    1. 概念
    2. 继承Thread类
    3. 实现Runnable接口
    4. 多个线程共同使用一个资源

java开发入门

java概述

  1. java的特点
    简单易用,安全可靠,跨平台,面向对象,支持多线程
  2. Java的开发环境是JDK
  3. Java的运行环境是JRE

标识符

标识符的名命规则标识符只能以数字,字母,下划线组成,首个字符不能是数字。

java中的变量与常量

变量

变量的内存空间可以重复使用

变量的数据类型

变量的数据类型可以分为基本数据类型和引用数据类,基本数据类型(数值型【整数类型(字节型byte,短整型shot,整数型int,长整型long)、浮点数类型(float,double),字符型char,布尔类型boolean(true,false)】)。引用数据类型分为(类class,接口interfa,数组,枚举enum,注解Annotation)
变量在创建后默认的数据类型是double类型,所以在类型转化(隐式转换)的时候应该注意是否可以忽略数据丢失(强制转换),数据的转换是根据字节数或者是占位符的多少为依据进行转换,如果是小字节数转换为大字节数的数据类型可以自动转换即隐式转换,但如果反过来,则需要进行申明

1
2
3
4
5
隐式转换:
大子节数据类型 a=小字节数据类型 b;
显示转换:
小子节数据类型 a=(小子节数据类型)(大字节数据类型 b);

常量

java中的常量有1.整数常量,2.浮点数常量,3.字符常量,4.字符串常量,布尔常量和null常量
常量必须用final修饰用来声明此常量是一个不可以改变的两

java编程基础

基本语句

流程控制有一下几种:

  1. 顺序结构:自上而下的有顺序的执行,中间没有任何的判断和跳转
  2. 分支结构
    (1)if条件语句
    if
    if···else
    if···else if···else
    (2)switch条件语句
  3. 循环结构
    (1)for循环
    (2)while循环
    (3)循环嵌套

    选择结构语句

    if语句

    if语句使用布尔表达式或布尔值作为分支条件进行分支控制
    if语句后面的括号里逻辑判断条件的结果只有两种true和false。
    多条语句作为条件执行体必须用{}括起来表示一个整体,只有一条执行语句可以省略{}用;作为停止。
    if语句
    if (判断条件){
    执行语句;
    }
    if···else语句
    if (判断条件){
    执行语句1;
    }else{
    执行语句2;
    }
    if···else if···else
    if (判断条件){
    执行语句1;
    }else if{
    执行语句2;
    }else if{
    执行语句3;
    }···else if{
    执行语句n;
    }else{
    执行语句n+1;
    }

    switch条件语句

    switch后面的控制表达式的数据类型只能是byte、short、char、int四种数据类型,java7之后也允许String类型。
    控制表达式不能为布尔类型boolean类型。
    default语句的位置不影响代码块执行的顺序,因为default在会在匹配所有的case不符合的时候才会被执行
    需要注意的是case后的代码块结束后需要留意添加break;否则代码会顺着执行下去直到遇到break;或者执行这个case后面的所有分支
    switch(控制表达式){
    case 目标值1:
    执行语句1;
    case 目标值2:
    执行语句2;
    case 目标值3:
    执行语句3;
    ···
    case 目标值n:
    执行语句n;
    default:
    执行语句n+1;//当以上所有的case的目标值没有与switch的控制表达是达到匹配的时候,就会执行default的语句
    }

循环语句

循环语句可能包含一下四种部分:
1.初始化语句:一条或多条,这些语句用于完成一些初始话工作,在循环开始之前执行
2.循环条件:循环条件是一个布尔表达式,用于判断次循环是否执行。
3.循环体:当循环条件为true的时候就会执行该循环体
4.迭代语句:在第一次循条件符合后执行完循环体后对控制循环变量,是循环在合适的时候结束
在使用循环结构的时候一定要注意结束条件,否者又可能代码会变成死循环

for语句

for(初始表达式;循环条件(与表达式作比较);执行条件(对表达式操作)){
执行语句;
}

while语句

whil(循环条件){
执行语句;
}

do···while语句

do{
执行语句1;
}while{
执行语句;
}
无论怎样do中的语句都会被执行。

循环嵌套语句

  1. for套for
    for(初始表达式;循环条件(与表达式作比较);执行条件(对表达式操作)){
    执行语句;
    for(初始表达式;循环条件(与表达式作比较);执行条件(对表达式操作)){
    执行语句;
     for(初始表达式;循环条件(与表达式作比较);执行条件(对表达式操作)){
     执行语句;
     }
    }
    }

跳转语句

  1. break语句
    break不考虑其下面的代码块直接跳出当前所在的循环。
  2. continue语句
    coninue跳出此次本次循环执行下一个循环。

数组

lengt方法可以返回数组的长度

1
2
3
int []array01=new int{10}
System.out.println("数组array01的长度为:"+array01.length);

数组的定义

  1. 数组类型[] 数组名=new 数组类型{数组长度};
  2. 数组类型[] 数组名=new 数组类型[]{数组元素0,数组元素1,···数组元素n};
  3. 数组类型[] 数组名={数组元素0,数组元素1,···数组元素n};
    多维数组的定义与一维数组的定义相似

数组赋值

  1. 先创建数组变量->给数组变量赋长度(空间)->给数组的索引位置赋值
  2. 先创建数组变量并赋值变量长度->给数组赋值

初始值

在没有赋值的情况下每一个索引所在的空间都有一个默认的值

不同数据类型的初始值
byte、short、int、long0
float、double0.0
char一个空字符
blooleanflase
引用数据类型null,表示变量不引用任何对象

面向对象(1)

输入语句:
java Scanner scanner = new Scanner(System.in); // 创建Scanner对象

面向对象的概论

面向对象的特点可以概括为封装、继承、多态。

  1. 封装是将对象的属性(值)和行为(执行的语句)封装起来,不需要外界知道具体的细节
  2. 继承主要描述的是类与类之间的关系,继承类可以获取被继承类的所有属性和行为(除final修饰的以外);
  3. 多态就是子类调用父类的属性和行为后所表达的属性和行为与父类呈现不同的形态结果。
  4. 类是引用数据类型

    类与对象的的关系

    类是对象的抽象,它描述一组对象的共同的行为和属性。
    类的成员之间可以相互调用但是(static)静态成员不能访问非静态的成员。
    静态

    定义类、成员变量和方法

    一个类有三种最常见的成员:构造方法、成员变量、方法。

    定义类

    类名的命名遵循标识符的命名规则,类名可以由英文字母、数字、下划线、美元字符组成,首字母不能为数字,且特殊的是类名的首字母需要大写。
    1
    2
    [修饰符] class className{
    }

定义成员变量

[修饰符] 类型 成员变量名 = 值;
成员变量:类中方法外,
局部变量:方法定义中或者方法声明上

1
2
3
4
5
6
7
8
public class Demon{
//此处定义member为成员变量
int member ;
publci void dog(){
//此处定义为局部变量
int locality;
}
}

成员方法

方法定义:

1
2
3
[修饰符] [void、返回值类型] 方法名(参数类型 参数名){
[return 返回值;]
}

void 表示无返回值,无需return返回值。
若此方法在执行完语句会需要将执行结果返回给调用此方法的位置的时候需要使用有返回值类型,并且返回值类型,和返回的值的类型统一。

构造方法

构造器格式:

1
2
public 类名(参数类型 参数名){
}

1.构造方法又称构造器。
2.构造器是特殊的方法。
3.构造器不需要使用返回值和return进行返回值,因为类的构造器本身是有隐藏的返回值的就是这个类本身,当使用new来创建这个类的对象的44.时候这个构造器就被调用了,并将这个类的对象值当作返回值返回。
4.在使用者没有手动创建构造方法的情况下,类会自己创建一个隐藏的构造方法,当其他类调用这个类的时候,会自动调用这个隐藏的构造方法。
5.构造器不止有一个,当我们手动创建构造器的时候,系统就不会自动给这个类创建构造器了,一个类可以有多个构造器,不同构造器之间通过参数值的类类型和参数值的个数来区别。

创建并使用对象

创造对象的基本途径是构造器,通过new关键字来调用某个类的构造器即可创建这个类的实例(对象)。

创建对象

1
2
3
4
//通过无参构造创建对象
类名 对象名 = new 类名();
//通过有参构造创建对象
类名 对象名 = new 类名(参数值);

对象名的名命遵循标识符的命名规则。

通过对象调用成员

static修饰的方法和成员变量既可以通过类名调用也可以通过对象名调用。
格式:

1
2
3
4
5
6
//调用成员变量
类名.成员变量名;
对象名.成员变量;
//调用成员方法
类名.成员方法(参数值);
对象名.成员方法(参数值);

实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Animal{
String name;
publci void Animal(){
System.out.print("属性:");
}
setName(String name){
this.name=name;
}
public void operation(String a){
System.out.print(animalNmae);
}
}
public class Dog{
publci void property(){
Animal dog=new Animal();
dog.setName("狗");
System.out.print(dog.name+dog.operation("是人类忠实的朋友"));
}

Dog类运行结果:

1
属性:狗是人类忠实的朋友

对象和引用

了解堆内存、栈内存

https://blog.csdn.net/u011546655/article/details/52170470?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522164715080516781683938954%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=164715080516781683938954&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~rank_v31_ecpm-1-52170470.pc_search_result_cache&utm_term=java%E5%A0%86%E5%92%8C%E6%A0%88%E7%9A%84%E5%8C%BA%E5%88%AB&spm=1018.2226.3001.4187
在Java中,内存分为两种,一种是栈内存,另一种就是堆内存
1.堆内存用来存放由new创建的对象和数组。
2.栈内存用来存放方法或者局部变量等
3.堆是先进先出,后进后出
4.栈是后进先出,先进后出

对象、引用和指针

  1. 创建一个类Person
    1
    2
    3
    4
    5
    public class Person{
    String name;
    public void operation(){
    }
    }
  2. 创建一个Person类的对象
    1
    Person p=new Person();
  3. 堆内存用来存放由new创建的对象和数组。所以此时创建的Person的对象已经被创建存放在堆内存中,而引用变量p则存放在栈中。变量p实际存放的不是Person的对象,而是Person的对象在堆中所对应的地址,它指向Person的对象但其本身不是对象,当使用者访问p的成员变量和方法的时候,实际上是访问p所指向的堆中对象的成员变量和方法。

this 关键字

this关键字用于解决成员变量和局部变量的名称冲突,提高程序的可读性。(当局部变量和成员变量侧名称冲突时,在方法中将无法访问名称发生冲突的成员变量),this指向的是当前对象(类)的地址,代表当前对象.

  1. this关键字访问成员变量,用于解决成员变量和局部变量的名称冲突
    1
    2
    3
    4
    5
    6
    public class Demon{
    String name;
    public void setName(String name){
    this.name=name;
    }
    }
  2. this 调用成员方法。
    成员方法自带this方法。
    1
    2
    3
    4
    public void student(){
    //this 可以省略不写;
    this.setName("邓憨憨");
    }
  3. this 关键字 构造方法的相互调用。

    构造函数调用必须是构造函数的第一句。

1
2
3
4
5
6
7
public Demon(){
//这是一个无参构造
this("邓憨憨");
}
public Demon(String name){
this.name=name;
}

方法

方法的所属性

在Java中方法不能对立存在,必须定义在类中,因此Java中的方法不能独立执行,必须依赖类或者对象来调用执行。
static定义的方法属于这个类本身,这个方法可以适应类名调用也可以通过对象调用,无论是被类名调用还是对象调用其执行结果是一样的。
没有被stati修饰的方法则属于对象的,只能使用对象来调用,且被不同的对象调用得到的执行结果不一定一样。

static特点

  1. 在不创建对象的情况下也可以被引,可以直接用类名引用
  2. 被static修饰的成员变量可以被所有实例共享
  3. static只能修饰成员变量,不能修饰局部变量
  4. 如果仅仅是在本类中,被static修饰的静态方法可以直接用方法名调用
  5. 静态方法只能访问静态变量(因为没有被static修饰的成员需要创建对象才能访问)
  6. 被static修饰的静态代码块,会在类加载的时被执行,但是也只能被执行一次。

    方法的传参机制

    方法传参通过实参传给形参
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class Person{
    public static void main(String[] args){
    //小明就是实参
    operation("小明");
    }
    //name就是形参
    public void operation(String name){
    }
    }
    main函数在调用operation方法的时候main函数还没有结束,系统会同时在栈内存中创建两个地址分别存放实参“小明”这个变量还有一个是形参name这个变量,当main函数调用到operation这个方法时候系统会将实参的值赋给形参,使得形参和实参的值相等,从而实现方法的传参。
    使用

参数个数可变的方法

从jdk1.5开始Java允许定义形参个数可变的参数,从而允许为方法指定数量不确定的形参,使用方法是在最后一个形参的类型后增加三个点(…),表示形参可以接受多个参数值,多个参数值被当作数组传入。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Person{
public static void main(String[] args){
demon(2,"小红","小蓝","大白");
}
//name就是形参
public void demon(int a,String...name){
//固定的形参a正长输出
System.out.println(a);
//不固定数量的形参作为数组输出
for(i=0;i<name.length();i++){
System.out.print(name[i]+" ");
}
}
}

递归方法

递归就是一个方法体内重复调用它自身的行为。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//当传入的值是5时,打印结果是5 4 3 1
public class Demon{
public static void main(String[] args){
number(5);
}
//name就是形参
public int number(int a){
if(a<1){
return 0;
}else {
System.out.print(a+" ");
return number(--a);
}
}
}

重载

重载的概念

在一个类中可以定义多个方法,方法名相同,只要方法的参数类型或个数不同即可。根据传入参数个数的不同区分调用的不同方法。

成员变量和局部变量

根本区别

注:成员变量分为类变量和实例变量,区别是static修饰的成员变量是类变量,没有别static修饰的是实例变量。

  1. 定义位置:成员变量定义在类中,局部变量定义在方法中
  2. 作用范围:成员变量作用在整个类中,局部变量只能在定义它的方法或者语句中使用
  3. 内存位置:成员变量存储在堆内存中,并且在堆内存中自动的赋予了默认值;局部变量存储在栈内存中,不会自动给默认值
  4. 生命周期:成员变量在对象创建的时候存到堆内存中,在对象被回收的时候销毁;局部变量在方法或者语句执行的时候创建,方法或者语句执行完销毁。

    初始化使用区别

  5. 成员变量当类被加载或者实例化对象的时候,系统会自动为成员变量分配空间,并指定初始值
  6. 局部变量定义后必须显式初始化才能使用,系统不会自动为局部变量初始化,同时这也表示局部变量在没有初始化之前在内存中是不存在的,只有在初始化之后系统才会为局部变量分配内存。

封装

Java的三大特点是继承、多态、封装,其中封装就是java三大特点之一,封装是将对象的属性(值)和行为(执行的语句)封装起来,不需要外界知道具体的细节。

  1. 隐藏类的详细行为方法
  2. 让使用者通过是事先预订的方法来进行操作,防止对成员变量的不合理访问
  3. 便于修改,提高代码的可维护性(封装起来的每个部分的行为都有特定的目的)
  4. 封装实现了代码的高内聚低耦合的特点

    权限控制符

    权限控制赋
    访问范围privatedefaultprotectedpublic
    同一个类
    同一个包
    子类
    全局范围

private 私有的

private 私有的,被它修饰的属性或成员是本类私有的不能用对象或对象名直接使用,但是私有的属性还是有可能被其他类使用,所以可以使用getter,setter方法用来改变和使用被private修饰的属性和方法。如果一个类中的某个成员变量被privatr修饰并且设置了getter方法但是没有settrt方法那么这个变量就只有只读属性无法修改。

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
public class People{
//private 私有的,被它修饰的属性或成员是本类私有的不能用对象或对象名直接使用;
private String name;
//hobby爱好
private String hobby;
public int age;
public void setName(String name) {
this.name=name;
}
public void setHobby(String hobby) {
this.hobby=hobby;
}
public String getName() {
return name;
}
public String getHobby() {
return hobby;
}
}

//测试类;
public class Test{
public static void main(String[] args){
//
People people=new People();
//用setter方法给Peopel类私有的name属性和hobby属性赋值(改变值);
people.setName("邓憨憨");
people.setHobby("喜欢吃肉肉");
//用getter方法获取Peopel类私有的name属性和hobby属性;
System.out.println("这个人name="+people.getName());
System.out.println(people.getName()+people.getHobby());
}
}

其他

  1. 如果某个类主要用作父类,且类中的方法只希望被子类重写,而不希望被外界直接调用,则可以使用protected修饰类中的方法
  2. 希望暴露出来给其他类共享的方法应该使用public修饰。
  3. 如果Java源文件里定义的所有类都没有用public修饰,那么这个java源文件的文件名可以任意名命,但如果定义了一个public修饰的类,这这个java源文件的文件名必须与public 修饰的类名相同。

构造方法

构造方法的组成

构造方法的命名与类名相同,没有返回值,在方法中不能使用return来返回一个值,但是可以单独写一个return作为方法执行的结束。

构造方法的特点

  1. 构造方法在创建对象的时候被调用;
  2. 在没有显示的创建的构造方法时,会自动创建一个隐式的无参构造方法;
  3. 如果创建了显示的构造方法系统就不会再自动创建构造方法;
  4. 构造方法也可以重载;
  5. 构造方法只能用public修饰;

构造方法的练习

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
public class Animal{
String name;
String className;
//这是一个无参的构造方法
public Animal() {
System.out.println("这是一个无参的构造方法");
}
public Animal(String name) {
this.name=name;
System.out.println("这是只有一个参数的构造方法");
}
public Animal(String name,String className) {
this.name=name;
this.className=className;
System.out.println("这是一个有多个参数的构造方法");
}
}
//测试类
public class text{
public static void main(String[] args){
//调用无参构造方法;
Animal animal=new Animal();
//调用一个参数的构造方法;
Animal cat=new Animal("小花");
//调用2个参数的构造方法;
System.out.println("它的name="+cat.name);
Animal dog=new Animal("小黑","狗");
System.out.println("它的name="+dog.name+"它的品种className="+dog.className);
}
}

static (静态)关键字

static 作用

static 用于修饰类的成员,如成员变量、成员方法以及代码块等,

static特点

  1. 在不创建对象的情况下也可以被引,可以直接用类名引用
  2. 被static修饰的成员变量可以被所有实例共享
  3. static只能修饰成员变量,不能修饰局部变量
  4. 如果仅仅是在本类中,被static修饰的静态方法可以直接用方法名调用
  5. 静态方法只能访问静态变量(因为没有被static修饰的成员需要创建对象才能访问)
  6. 被static修饰的静态代码块,会在类加载的时被执行,但是也只能被执行一次。

面向对象(2)

类的继承

类的继承是指在已经原有一个类A的基础上,在创建一个类B,是的A继承(extends)B,那么A被称为父类或基类,B成为子类
,子类会继承所有父类的行为和属性(属性和方法)。

子类只能继承父类的“非”私有属性和方法即非final修饰的属性和方法

重写

重写的概念和使用

  1. 子类会继承父类的属性和方法,但是有时候对父类的方法需要修改的操作叫做重写。
  2. 子类中重写父类的方法时需要注意重写的方法需要与继承方法的方法名、参数列表、返回值类型保持一致,访问权的修饰符不能比父类的严格。

super

super的作用

super用于当父类的子方法被子类重写后,子类还能调用没有被重写前方法的状态。

使用方法

1
2
3
4
super.方法名(参数值);//调用父类的普通方法;
super();//调用父类的无参构造;
super(参数值);//调用父类的有参构造;

Object类

Object概念

Object类是所有类的父类,即每一个类都直接或间接继承此类,因为Object类又被称为超类、基类、根类。如果一个类没有使用extends关键字指定父类,那么这个类会默认继承Object类。

final 关键字

final的概念

fianl关键字修饰的类、变量、方法都是不能改变的。

final的特点

  1. final修饰的类不能被继承,也就是不能派生子类
  2. final修饰的方法不能被重写
  3. final修饰的变量(成员变量、局部变量)是“常量”,只能赋值一次。

4.6 Lambda 式编程

4.6.1 了解Lambda

局限性: 只针对于有且只有一个抽象方法的接口(函数式接口)才能使用。
组成:一个Lambda表达式包括三个部分:参数列表、“->”(箭牌)、表达式主体(接口中的抽象方法)。
语法格式:([数据类型 参数名,数据类型 参数名···])->{表达式主题}。
只有一个参数时可以省略小括号,表达式主题只有一条语句可以省略大括号,数据类型可以不写,后面表达式会自行校对和匹配。
表达时式主体允许有返回值,当只有一条return语句时可以省略return关键字。

4.6.2 函数式接口

上课笔记:

1
2
3
4
5
6
7
8
9
10
11
12
13
inerface MathAnd{
public int and(int a,int b) ;
}
public class Demo{
public static void main(String[] args) {
and(2,3,(x,y)->x+y);
}
public static void and(int a,int b,MathAnd mathand) {
mathand.and(a,b);
System.out.println(mathand.and(a,b));
//输出结果为 5;
}
}

4.6.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
33
34
35
36
37
38
39
40
41
42
43
44
45
package qingwa;
interface Animal{
public void animalShout(String name);
}
public class Demo{
public static void main(String[] args) {
//Lambda表达式,类名调用静态方法;
shout("猫",name->AnimalName01.thisAnimal(name));
//引号,类名调用静态方法;
shout("猫",AnimalName01::thisAnimal);
//创建 AnimalName对象;
AnimalName02 animalname=new AnimalName02();
//Lambda表达式,对象名调用静态方法;
shout("人" ,name->animalname.thisAnimal(name));
//引号,类名调用静态方法;
shout("人",animalname::thisAnimal);
//Lambda表达式,构造器引用方法;
printName("狗" ,name->new AnimalName03(name));
//引号,构造器引用方法;
printName("狗",AnimalName03::new);
}
public static void shout(String name,Animal animal){
animal.animalShout(name);
}
public static void printName(String name,Animal animal){
animal.animalShout(name);
}
}
class AnimalName01{
//类名引用的方法和成员必须用static修饰;
public static void thisAnimal(String name){
System.out.println("我的品种是:"+name);
}
}
class AnimalName02{
public void thisAnimal(String name){
System.out.println("我的品种是:"+name);
}
}
class AnimalName03 {
//创建构造器;
public AnimalName03(String name) {
System.out.println("我的品种是:"+name);
}
}

多态

类(包括抽象类)和类(包括抽象类)之间是继承关系
接口和接口是继承关系
类(包括抽象类)和接口时实现关系

抽象类extends/implements
接口
implements/
接口

抽象类

如果一个类中有一个方法是用abstract修饰的,那么这个类必须是抽象类。

特点: (1)被abstract修饰的类称为抽象类。 (2)抽象方法没有方法体依赖继承来实现。 ### 接口 特点: (1)被interface关键字修饰。 (2)接口中的方法都是抽象方法。 (3)接口里面只能定义抽象方法和最终常量。

接口和抽象类的区别

  1. 方法:接口中的方法全都是抽象方法,抽象类中可有抽象方法也可以有非抽象方法
  2. 实现:一个类可以实现(implement)多个接口类,但是只能实现(extends)一个抽象类。
  3. 方法的实现:当实现一个接口的时候实现类需要实现接口中的多有方法,但实现一个抽象类就不必须实现全部的方法。

4.7 异常

4.7.1 什么是异常

所有的异常类都继承java.lang.Throwble 类。
·Error 错误类,它时产生的“系统内部资源耗尽”的错误,是比较严重的,仅靠修改程序本身是不能恢复执行的行的,如虚拟机错误,系统崩溃等。
·Excption 异常类,它是程序本身可以处理的错误。

4.1.2 异常的类型

异常分为 编译时异常(又称 checked 异常)和运行是异常(又称 unchecked异常)。
Exception异常类除 RuntimeException 类及其子类(是运行时异常),其他子类为编译时异常
Throwable 类的 String getName() 方发能返回此 throwable 的详细信息字符串(异常信息)。
·编译时异常的解决方法:
(1)使用 try···catch 捕捉异常。
语法格式:

1
2
3
4
5
6
try{ //可能发生异常的语句(捕捉异常),发生异常语句后面的代码不会被执行;
}catch (Exception 类及其子类 e){
//对捕捉的异常进行处理(抛出处理);
}finally{
//无论try是否捕捉到异常,放在这里的语句都会被执行;
}

(2)使用 throws 关键字声明抛出异常,让使用者对其处理。
优点:可以一次性抛出多种异常。
语法格式:

1
2
3
[修饰符] 返回值 方法名()throws 异常类1,异常类2,···{
//方法体···;
}

·运行时异常程序可能编译通过,只是在运行中可能会报错

3)throw 自定义异常
上课笔记:

1
2
3
4
5
6
7
8
9
10
11
12
13
//自定义异常 DivideException
//除数不能是负数异常;
public class DivideException extends Exception{
public DivideException() {
//super(),调用父类的无参构造方法;
super();
}
public DivideException(String m) {
//super(m),调用父类的有参构造
super(m);
}
}

测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class Text02 {
public static void main(String[] args) {
try {
int i=divide(4,-2);
} catch (DivideException e) {
// 输出异常信息;
System.out.println(e.getMessage());
}

}
//2.方法throws关键字向上抛出异常;
public static int divide(int x,int y) throws DivideException {
if(y<0) {
// 1. throw 关键字抛出异常对象(匿名对象),自定异常的特殊方式;
throw new DivideException("除数不能为负数");
}

return x/y;
}
}

java中的常用类

集合

1.集合是专门用来存储Java对象的容器,这些对象可以是任意数据类型,并且长度可以改变。这些集合都位于 java.util 包下,使用时要注意导包问题。
集合体系架构图

2. Collection 集合是所有单列集合的根接口,它用于存储一系列符合某种规则的元素,List、Set是它的主要两个子接口。
3 List接口
List 接口继承了 Collection 接口中的全部方法,而且还自身增加了一些操作集合特有的方法

I/O流

上课笔记:

  1. 流的方向是从‘内存’的角度看的。
  2. 在标准输‘入’过程,数据从键盘的输入设备流入内存,这是输入流。
  3. 在标准输‘出’过程中,数据从内存流向显示器或打印机等输出设备,这叫输出流。
  4. ‘读’文件操作中存在输入流,数据从磁盘流入内存。
  5. ‘写’文件操作中存在输出流,数据从内存流向磁盘。
  6. 字‘节’流包括字节输入流InputStream和自己输出流OutputStream。
  7. 字‘符’流包括字符输入流Reader和Writer字符输入

输出流

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
/**
*输出流
*/
import java.io.FileInputStream;

public class Test01 {
public static void main(String[] args) {
try {
//文件输入流;
//当main方法和被操作文本文件在同一个包里就不用写路径
FileInputStream in=new FileInputStream("C:\\郭露露dejava\\eclipse 项目\\work\\src\\io\\guolu.txt");
int b=0;
while(true) {
b=in.read();
if(b== -1) {
break;
}
System.out.print((char)b);
}
in.close();
} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}
}

输入流

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
/**
* 输入流
*/
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

public class Test02 {
public static void main(String[] args) {
try {
//将字节写入到硬盘;
FileOutputStream out=new FileOutputStream("C:\\郭露露dejava\\eclipse 项目\\work\\src\\io\\123.txt");
String str="Hello... winter";
byte[] b=str.getBytes();
for(int i=0;i<b.length;i++) {
out.write(b[i]);
}
out.close();

} catch (Exception e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
}

}

输入流和输出流一起使用实现文件的复制

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
/**
*输入流和输出流一起使用实现文件的复制
*/
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;

public class Test03 {
public static void main(String[] args) throws Exception {
//读取文件;
InputStream in=new FileInputStream("C:\\Users\\23566\\Pictures\\图群\\tu.jpg");
//写入文件;
OutputStream out=new FileOutputStream("C:\\郭露露dejava\\eclipse 项目\\work\\src\\io\\tu.jpg");
int len;
long beginTime=System.currentTimeMillis();
while ((len=in.read())!= (-1)) {
out.write(len);
}
long endTime=System.currentTimeMillis();
System.out.println("拷贝文件所需要的时间:"+(endTime-beginTime)+"毫秒");
in.close();
out.close();
}

}

字节缓冲流

带缓冲区的输入输出流

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
/**
* 字节缓冲流
*/

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
//带缓冲区的输入输出流;
public class Test04 {
public static void main(String[] args) throws Exception {
//读取文件到内存;
InputStream in=new FileInputStream("C:\\Users\\23566\\Pictures\\设计图\\乱涂-标题.mp4");
//输入流缓冲区
BufferedInputStream bis=new BufferedInputStream(in);
//从内存写出到硬盘;
OutputStream out =new FileOutputStream("C:\\郭露露dejava\\eclipse 项目\\work\\bin\\io\\乱涂-标题.mp4");
//输出流缓冲区;
BufferedOutputStream bos=new BufferedOutputStream(out);
int len;
//获取当前时间;
long beginTime=System.currentTimeMillis();
while((len=in.read())!= (-1)) {
bos.write(len);
}
//获取当前时间;
long endTime=System.currentTimeMillis();
System.out.println("拷贝文件所需要的时间:"+(endTime-beginTime)+"毫秒");
in.close();
out.close();
}

}
//拷贝文件所需要的时间:1156毫秒

不带缓冲区的输入输出流

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
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
//不带缓冲区的输入输出流;
public class Test04 {
public static void main(String[] args) throws Exception {
//读取文件到内存;
InputStream in=new FileInputStream("C:\\Users\\23566\\Pictures\\设计图\\乱涂-标题.mp4");
//从内存写出到硬盘;
OutputStream out =new FileOutputStream("C:\\郭露露dejava\\eclipse 项目\\work\\bin\\io\\乱涂-标题.mp4");
int len;
//获取当前时间;
long beginTime=System.currentTimeMillis();
while((len=in.read())!= (-1)) {
out.write(len);
}
//获取当前时间;
long endTime=System.currentTimeMillis();
System.out.println("拷贝文件所需要的时间:"+(endTime-beginTime)+"毫秒");
in.close();
out.close();
}

}
//拷贝文件所需要的时间:2607毫秒

GUI(图形用户接口)

多线程

第十章 多线程

概念

·单核cpu在同一时间只能处理一个任务(顺序执行)。
·多线程在应用上是配置系统资源。
·线程是比进程更小的单位,一个进程至少有一个线程。

继承Thread类

(1)子类继承Thread类具备多线程能力
(2) 启动线程: 子类对象.start()
(3)顺序:
创建一个子类A继承(extends)Thread类;
在子类A中重写run()方法;
对子类A实例化对象a;
通过a.start()启动线程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Test_02 {
public static void main(String[] args) {
MyThread myThead=new MyThread();
// 3.start()方法启动线程
myThead.start();
while (true) {
System.out.println("main...");
}
}
}
// 1.继承Thread类
class MyThread extends Thread{
// 2.重写run()方法
public void run() {
while(true) {
System.out.println("MyThread...");
}
}
}

实现Runnable接口

(1)实现类接口Runnable具备多线程能力
(2)启动线程:传入目标对象+Tread对象.对象.start()
(3)顺序: 创建一个 Runnable 接口的实现类,同时重写接口中的 run() 方法;
创建Runnable 接口的现类对象;
使用 Thread 有参构造方法创建线程实例,并将Runnable接口的实现类的实例对象作为参数传入;
调用线程实例的 start() 方法启动线程
(3)与继承Thread类相比优点:避免单继承局限,灵活方便,方便同一个对象被多个线程使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public class Test_03 {
public static void main(String[] args) {
MyThread03 myThead03=new MyThread03();
Thread thread=new Thread(myThead03);
thread.start();
while (true) {
System.out.println("main...");
}
}
}
//实现Runnable接口
class MyThread03 implements Runnable{
public void run() {
while(true) {
System.out.println("MyThread...");
}
}

}

多个线程共同使用一个资源

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
public class Test_05 {
public static void main(String[] args) {
TickeWindows02 t1=new TickeWindows02();
new Thread(t1,"窗口1").start();
new Thread(t1,"窗口2").start();
new Thread(t1,"窗口3").start();
new Thread(t1,"窗口4").start();
new Thread(t1,"窗口5").start();
}
}
class TickeWindows02 extends Thread{
private int tickets=50;
public void run() {
while(true) {
if(tickets>0) {
//获取当前线程;
Thread th=Thread.currentThread();
//获取子线程的名称;
String th_name=th.getName();
System.out.println(th_name+"正在发售"+(tickets--)+"张票");
}

}
}
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 jaytp@qq.com

×

喜欢就点赞,疼爱就打赏