Java学习记录 课程来自黑马刘意(风清扬)19年版

Java是跨平台的

Java程序是跨平台的。但是JVM不是跨平台的 不同的系统下有不同的JVM
JRE (Java Runtime Environment) 是java程序的运行时环境,包含JVM和运行时所需的核心类库。
JDK(Java Development Kit) java程序开发工具包 包含jre和开发工具包。 同理如SDK
如果我们想要运行一个java程序的话,那么只需安装jre即可
如果我们项开发一个java程序的话,那么就必须安装jdk

附图Java学习记录 课程来自黑马刘意(风清扬)19年版_第1张图片

JAVA中的编译器和解释器:

Java中引入了虚拟机的概念,即在机器编译程序之间加入了一层抽象的虚拟的机器。这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口。编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由解释器来将虚拟机代码转换为特定系统的机器码执行。在Java中,这种供虚拟机理解的代码叫做字节码(即扩展名为**.class的**文件),它不面向任何特定的处理器,只面向虚拟机。每一种平台的解释器是不同的,但是实现的虚拟机是相同的。Java源程序经过编译器编译后变成字节码,字节码由虚拟机解释执行,虚拟机将每一条要执行的字节码送给解释器,解释器将其翻译成特定机器上的机器码,然后在特定的机器上运行,这就是上面提到的Java的特点的编译与解释并存的解释。
Public class后面代表定义一个类的名称,类是Java中所有源代码的基本组织单位。

常量:在程序运行期间,固定不变的量。

字符常量:凡是用单引号引起来的单个字符,就叫做字符常量
注意:两个单引号中间必须有且仅有一个字符,没有不行。

空常量:其中有一个空常量 null 代表没有任何数据
空常量不能直接用来打印输出。 会报空指针异常

基本数据类型中 取值范围比较 double>float>long>int >short>byte
基本数据类型
整数型:byte 1字节 取值范围-128-127 short 2字节 int 4字节long 8字节
浮点型:float 4字节 double 8字节
字符型:char 2字节
布尔型:boolean 1字节
附图Java学习记录 课程来自黑马刘意(风清扬)19年版_第2张图片
注意:
1、 String不是基本类型,而是引用类型。
2、 浮点型可能只是一个近似值,并非精确的值。用浮点型计算会出错,所以Java有个工具类BigDecimal 是用来计算浮点类型数据的
3、 数据范围和字节数不一定相关,例如float数据范围比long更加广泛,但是float是4字节,long是8字节。
4、 浮点数当中默认类型是double。如果一定要使用float类型,需要加上一个后缀F
如果是整数,默认是int类型,如果一定要使用long类型,需要加上一个后缀L

注意
1、在给变量赋值的过程中,右侧数值范围不能超过左侧数据类型的取值范围
例如byte num=400; //右侧超出了byte数据范围,错误!

2、在给long和float类型赋值时,一定不要忘记加后缀L和F

3、没有进行赋值的变量,不能直接使用,一定要赋值之后,才能使用。即使赋值null

当数据类型不一样时,将会发生数据类型转换。

自动类型转换(隐式)
1、 特点:代码不需要进行特殊处理,自动完成。
2、 规则:数据范围从小到大
大的转换成小的就会有精度丢失
强制类型转换(显式)
1、 格式:范围小的变量名=(范围小的类型) 原本范围大的数据;
注意事项:
1、 强制类型转换一般不推荐使用,因为有可能发生精度损失、数据溢出。
2、 Byte/short/char这三种类型都可以发生数学运算,例如加法“+”
一旦char类型进行了数学运算,那么字符就会按照一定的规则翻译成为一个数字。
3、 Byte/short/char这三种类型在运算的时候,都会被首先提升为int类型,然后再计算。
4、 Java中的boolean类型不能发生数据类型转换 可以转化成String类型的 用String.valueof()方法

ASCII码表中
48代表0 65代表A 97代表a 这些常见的要记住,现实开发中有点帮助

ASCII码表:American Standard Code for Information Interchange,美国信息交换标准代码。
Unicode码表:万国码。也是数字和符号的对照关系,开头0-127部分和ASCII完全一样,但从128开始包含有更多字符。比如20013代表“中”字

注意:
1、在四则运算中,一旦运算当中有不同类型的数据,那么结果将会是数据类型范围大的那种。
**2、对于String来说,加号代表字符串连接。任何数据类型和字符串(String)进行连接的时候,结果都会变为字符串。**所以字符串加任意东西都会变为字符串,在实际开发中,如果项目用的是以前的JDBC,那么这个可以用来拼接SQL

逻辑运算符

与“&&”,或“||”具有短路效果
优点:如果根据左边已经可以判断出最终结果,那么右边的代码将不再执行,从而节省一定的性能。
缺点:在实际开发的时候可能会造成错误 要避免这样子的判断

三元运算符:需要三个数据才可以进行操作的运算符。
格式:
数据类型 变量名称=条件判断?表达式A:表达式B;
注意事项
1、 必须同时保证表达式A和表达式B都符合左侧数据类型的要求。
2、 三元运算符的结果必须拿来使用
Switch后面小括号当中只能是基本数据类型byte/short/char/int/String/enum
float和long就不行

break的关键字的用法
1、 可以在switch语句当中,一旦执行,整个switch语句立刻结束。
2、 还可以用在循环语句当中,一旦执行,整个循环语句立刻结束。打断循环。跳出循环体,是跳出循环,不是跳出if

continue的用法
一旦执行,立刻跳过当前循环剩余内容,马上开始下一次循环。
死循环的标准格式
while(true){
循环体
}

随机数Random
Random r = new Random();
int number = r.nextInt(10);//随机数0-9 不包括10
数组
静态初始化:
Int[ ]arr={1,2,3}
int[] a = new int[3];
表示有a[0],a[1],a[2],但是没有a[3],数组会越界
数组在初始化时,会为存储空间添加默认值。
整数:默认值0
浮点数:默认值0.0
布尔值:默认值false
字符:默认值是空字符
引用数据类型:默认值是null
int[] a = new int[3];
int[] a
栈内存:存储局部变量
定义在方法中的变量,例如:arr

使用完毕,立即消失

new int[3]
堆内存:存储new出来的内容(实体,对象)
每一个new出来的东西都有一个地址值

使用完毕,会在垃圾回收器空闲时被回收。

栈内存比较浅 堆内存比较深
int[] arr = new int[3];
arr = null;
System.out.println(arr[0]);
这样会造成空指针异常 因为arr的地址被赋值为null之后就找不到arr[0]值了

遍历数组
借助arr.length
int[] arr = new int[3];
for (int i = 0; i < arr.length; i++)
System.out.println(arr[0]);

方法

形参和实参
形参:方法定义中的参数
等同于变量定义格式,例如:int number
实参:方法调用中的参数
等同于使用变量或者参数,例如: 10,number

带返回值的方法定义
方法定义时return后面的返回值与方法定义上的数据类型要匹配。否则程序将报错。

方法的返回值通常会使用变量接收,否则该返回值将没有意义。当然也可以在sout直接打印输出。

方法的注意事项:
Void表示无返回值,可以省略return,也可以单独书写return,表示方法到return这结束了。后面不加数据

方法重载
方法重载指同一个类中定义的多个方法之间的关系。
1、 多个方法在同一个类中
2、 多个方法具有相同的方法名
3、 多个方法的参数不相同,类型不同或者数量不同

方法重载的特点
1、 重载仅对应方法的定义
2、 重载仅针对同一个类中方法的名称和参数进行识别
static int sum(int a, int b) {
return a + b;
}

static double sum(double a, double b) {
return a + b;
}

static int sum(int a, int b, int c) {
return a + b + c;
}
在调用的时候,Java虚拟机会通过参数的不同来区分同名的方法。
对于引用类型的参数,形式参数的改变,影响实际参数的值。 因为引用类型的参数是引用的地址
对于基本类型的参数,形式参数的改变,不影响实际参数的值。

**

面向对象

** 有人说懂了这章Java就算入门了
类:类是对现实生活中具有共同属性和行为的事物的抽象
对象:是能够看得到摸得着的真实存在的实体。
类是对象的抽象
对象是类的实体

例子:手机是类 小米8就是手机这个类的一个对象

类的重要性:是Java程序的基本组成单位
成员变量和局部变量的区别
Java学习记录 课程来自黑马刘意(风清扬)19年版_第3张图片
栈内存:
存储的都是局部变量,而且变量所属作用域一旦结束,该局部变量自动释放。
堆内存:
存储是数组和对象(数组也是对象的一直)凡是new建立的对象,建立在堆中。
Private关键字
1、 是一个权限修饰符。
2、 可以修饰成员(成员变量和成员方法)
3、 保护成员不被别的类使用,被private修饰的成员只能在自己的类中才能访问

针对private修饰的成员变量,如果需要被其他类使用,提供相应的操作
1、 提供get、set方法用于获取获取和设置成员变量的值,方法用public修饰

this关键字
1、 this修饰的变量用于指代成员变量
方法的形参如果和成员变量同名,不带this修饰的变量指的是形参,而不是成员变量。
2、 什么时候使用this
解决局部变量隐藏成员变量
3、 this:代表所在类的对象引用
记住:方法被哪个对象调用,this就代表哪个对象。

封装

1、封装是面向对象的三大特征之一(封装,继承,多态) 很多面试官爱问的题目
封装是面向对象编程语言对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界是无法操作的
2、 封装原则
将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法实现对隐藏信息的操作和访问。
3、 封装的好处
通过方法来控制成员变量的操作,提高了代码的安全性
把代码用方法进行封装,提高了代码的复用性。

构造方法
构造方法是一种特殊的方法,作用是创建对象
功能:主要是完成对象数据的初始化。

构造方法的注意事项
构造方法的创建
1、 如果没有定义构造方法,系统将给出一个默认的无参数构造方法
2、 如果定义了构造方法,系统将不再提供默认的构造方法。
3、 如果自定义了带参构造方法,还要使用无参的构造方法,就必须再写一个无参构造方法。

推荐使用方式:无论是否使用,都手工书写无参构造方法。

API: 应用程序编程接口

Java API:指的就是JDK中提供的各种功能的Java类
这些类将底层的实现封装了起来,我们不需要关心这些类式如何实现的,只需要学习这些类如何使用即可,我们可以通过帮助文档来学习这些API如何使用。 Java中有许多封装好的API 功能非常强大,如果你学会用会在实际开发中减少很多代码

String概述:

String类代表字符串,Java程序中的所有字符串文字,都被实现为此类的实例,也就是说,Java程序中所有的双引号字符串,都是String类的对象

字符串的特点
1、 字符串不可变,它们的值在创建后不能被更改
2、 虽然String的值时不可变的,但是它们可以被共享
3、 字符串效果上相当于字符数组(char[ ]),但是底层原理是字节数组(byte[ ])

String的构造方法:
public String():创建一个空白字符串对象,不含任何内容
public String(char[] chs):根据字符数组的内容来创建字符串对象
public String(byte[] bys):根据字节数组的内容,zz来创建字符串对象
String s=”abc” 直接赋值的方式创建字符串对象,内容就是abc

推荐使用直接赋值的方式得到字符串对象

String对象的特点:
1、 通过new创建的字符串对象,每一次new都会申请一个内存空间,虽然内存相同,但是地址值不同
2、 以“ ”方式给出的字符串,只要字符序列相同(顺序和大小写),无论在程序代码中出现几次,JVM都只会建立一个String对象,并在字符串池中维护。

遍历String字符串

for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
System.out.print(c+",");
}

字符串进行拼接只需要用+号来就可以
例如s+=int arr[i];

但是如果+拼接操作,都会构建一个新的String对象,既耗时,又浪费内存空间 而原来的那个String对象还会存在在内存中

**StringBuilder概述 **
是StringBuffer的替代品 StringBuffer有安全线程 但是现在已经不是很常用了
StringBuilder是一个可变的字符串类,String不可以改变,我们可以把它看成是一个容器 这里的可变指的是StringBuilder对象中的内容是可变的

String和StringBuilder的区别
1、 String的内容是不可变的
2、 StringBuilder的内容是可变的

Java学习记录 课程来自黑马刘意(风清扬)19年版_第4张图片
Java学习记录 课程来自黑马刘意(风清扬)19年版_第5张图片

可以在StringBuilder里面直接放String 让其变成StringBuilder对象

那么为什么要用StringBuilder呢?
因为StringBuilder比String更节省内存空间,更有效率
并且StringBuilder里面有reverse方法直接反转。

可以用sb.toString()或者StringBuilder的构造方法将String和StringBuilder互相转换

java.lang包是java语言的核心,它提供了java中的基础类。包括基本Object类、Class类、String类、基本类型的包装类、基本的数学类等等最基本的类。

万包基于java.lang包

**

集合概述

集合类的特点:提供一种存储空间可变的存储模型**,存储的数据容量可以发生改变 类似C语言中的malloc
集合类有很多,ArrayList只是其中一个

ArrayList<E>:

1、 可调整大小的数组实现
2、 E:是一种特殊的数据类型,泛型。
怎么用?
1、 在出现E的地方我们使用引用数据类型替换即可
2、 举例:ArrayList,ArrayList

Java学习记录 课程来自黑马刘意(风清扬)19年版_第6张图片
其中get和size方法比较常用
集合的遍历写法
for (int i = 0; i < arrayList.size(); i++) {
String s1 = arrayList.get(i);
}

System.exit(0)是和C语言的exit(0)一样是退出的意思。

为了让程序不再往下执行,可以给出return停止执行
退出所在方法 如果在main方法中有return 说明程序到这就不再往后执行了

继承

继承概述
继承是面向对象三大特征之一。可以使得子类具有父类的属性和方法,还可以在子类中重新定义,追加属性和方法。 子类继承父类 子类可以自己再发展方法和属性 在现实开发中用到的不要太多
1、 继承的格式:public class子类名 extends 父类名{}
2、 范例:public class Zi extengds Fu{ }
3、 Fu:是子类,也被称为基类、超类
4、 Zi:是子类,也被成为派生类

继承中子类的特点
1、 子类可以有父类的内容
2、 子类还可以有自己特有的内容

继承的好处和弊端
继承好处
1、 提高了代码的复用性(多个类相同的成员可以放在同一个类中)
2、 提高了代码的维护性(如果方法的代码需要修改,修改一处即可)

继承弊端
1、继承让类与类之间产生了关系,类的耦合性增强了,当父类发生变化时子类不得不变化,削弱了子类的独立性

什么时候使用继承?
举例子:苹果和水果,苹果是水果的一种,所以可以使用继承
猫和动物,猫是动物的一种,所以可以使用继承
猫和狗,猫既不是狗的一种,狗也既不是猫的一种,所以不可以使用继承
继承中变量的访问特点
在子类方法中访问一个变量
1、 子类局部范围找
2、 子类成员范围找
3、 父类成员范围找
4、 如果都没有就报错
(先从子类自己的方法找,如果没有,在子类自己的成员变量里找,如果没有,就回到父类的成员遍历里找,如果还是没有,那么就会报错 但是如果父类的父类有 就不会报错)
先从自己找,自己找没有的话 就从父亲那里找,父亲那里没有就报错
super
super关键字的用法和this关键字的用法相似
1、 this:代表本类对象的引用
2、 super:代表父类存储空间的表示(可以理解为父类对象引用)

Java学习记录 课程来自黑马刘意(风清扬)19年版_第7张图片

继承中构造方法的访问特点
子类中所有的构造方法默认都会先访问父类中无参的构造方法
为什么呢?
1、 因为子类会继承父类中的数据,可能还会使用父类的数据,所以在子类初始化之前,一定要先完成父类数据的初始化
2、 每一个子类构造方法的第一条语句默认初始化都有一条:super(),只不过被省略了。
3、 super(message)意思是带着子类的构造函数的参数message调用父类的构造函数。如果不写这一句,那么父类的message就没有值。
如果父类中没有无参构造方法,只有带参构造方法,怎么办?
1、 通过使用super关键字显示的调用父类的带参构造方法
2、 在父类中自己提供一个无参构造方法
推荐:自己给出无参构造方法。
继承中成员方法的访问特点
通过子类对象访问一个方法
1、 子类成员范围找
2、 父类成员范围找
3、 如果都没有就报错
(先在子类自己的成员方法找,如果没有就去父类的成员方法找,如果还是没有就会去父类的父类去找,父类的父类要是有的话就不会报错)
和找变量是一个道理
方法重写概述
1、 子类中出现了和父类中一模一样的方法声明

方法重写的应用
1、 当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,既沿袭了父类的功能,又定义了子类特有的内容。
2、 @Override 是一个注解 可以帮助我们检查重写方法的方法声明的正确性

方法重写注意事项
私有方法不能被重写(父类私有成员子类是不能继承的)
子类访问权限要比父类更高(public>默认(什么都不写)>私有)才能访问父类的方法

java中继承的注意事项
1、 Java中一个子类只能继承一个父类
2、 Java中类支持多层继承(比如子类继承父类,父类继承爷类)

只支持单继承

包的概念和使用
其实就是文件夹
作用:对类进行分类管理
仅作了解 因为我们用到都是IDEA这种开发工具 自动导包等操作已经做好了
权限修饰符:
Java学习记录 课程来自黑马刘意(风清扬)19年版_第8张图片
public在任何情况下都能被访问,protected在不同包的无关类中不能被访问,但是不同包的子类还是可以访问的,默认的(就是什么都不写)只能在同一个包中被访问,private只能在自己的类中被访问
状态修饰符
1、 final(最终态)
2、 static(静态)

final
final关键字时最终的意思,可以修饰成员方法,成员变量,类
final修饰的特点
1、 修饰方法:表明方法是最终方法,不能被重写。
2、 修饰变量:表明变量是最常量,不能再次被赋值。
3、 修饰类:表明该类是最终类,不能被继承。

final修饰局部变量
1、 变量是基本类型:final修饰的是基本类型的数据值不能发生改变
2、 变量是引用类型:final修饰指的是引用类型的地址值不能发生改变,但是地址里面的值还是可以发生改变的

static
static关键字是静态的意思,可以修饰成员方法,成员变量
static修饰的特点
1、 被类的所有对象共享
也是我们判断是否使用静态关键字的条件
2、 可以通过类名调用
当然也可以通过对项目调用
推荐使用类名调用
类名.
static访问特点
静态成员方法只能访问静态成员。

多态

同一个对象,在不同时刻表现出来的不同形态
多态的前提和体现
1、 有继承/实现关系
2、 有方法重写
3、 有父类引用指向子类对象

多态中成员访问特点
1、 成员变量:编译看左边,执行看左边
2、 成员方法:编译看左边,执行看右边
为什么成员变量和成员方法的访问不一样呢?
因为成员方法有重写,而成员变量没有。

多态的好处和弊端
1、 多态的好处:提高了程序的扩展性
具体表现:定义方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的子类型参与操作
2、 多态的弊端:不能使用子类的特有功能。(但是向下转型可以解决)

多态中的转型
1、 向上转型
从子到父
父类引用指向子类对象
Animal b = new Dog();
b.eat();

2、 向下转型
从父到子
父类引用转为子类对象
安全的向下转型(指向子类)
Animal b = new Dog();
Dog d=(Dog)b;
d.eat();
d.doLookDoor();
指向子类
不安全的向下转型(指向父类)
Animal b=new Animal();
((Dog) b).doLookDoor();//它直接强转了父类 所以是不安全的 可以通过instanceof来解决这个问题
向上转型会丢失子类特方法 但是可以通过向下转型拿回来
向下转型可以解决不能使用子类的特有功能的弊端
向上转型可以使代码变得简洁,
 所以向下转型过程中要注意的是:     
    情况一:如果父类引用的对象如果引用的是指向的子类对象,那么在向下转型的过程中是安全的。也就是编译是不会出错误的。
    情况二:如果父类引用的对象是父类本身,那么在向下转型的过程中是不安全的,编译不会出错,但是运行时会出现****java.lang.ClassCastException错误。它可以使用instanceof来避免出错此类错误。

instanceof是Java的一个二元操作符(运算符),和==,>,<是同一类东西。由于它是由字母组成的,所以也是Java的保留关键字。它的作用 是判断其左边对象是否为其右边类的实例,返回boolean类型的数据可以用来判断继承中的子类的实例是否为父类的实现。java中的instanceof是通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例。

抽象类

概述
在Java中,一个没有方法体的方法被定义为抽象方法而类中如果有抽象方法,该类必须定义为抽象类。
抽象类的特点
1、 抽象类和抽象方法必须使用abstract关键字修饰
2、 抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
a) 抽象类中可以有其他方法
3、 抽象类不能实例化
抽象类如何实例化呢?参照多态的方式,通过子类对象实例化,这叫抽象类多态
会主动帮你重写方法
4、 抽象的子类
要么重写抽象类的所有抽象方法
要么自己本身就是抽象类
抽象类的成员特点
抽象类可以有构造方法,但是不能实例化 可以用抽象类多态进行实例化
接口和抽象类的区别: 这个面试也爱问到
Java8中的接口是可以有实现代码的,且方法修饰符只能是public 类中没有构造方法
抽象类中可以有普通成员方法,抽象方法修饰符可以有pubic,protected,default。可以有构造方法

接口概述

接口就是一种公共的规范标准,只要符合规范标准,大家都可以通用
Java中的接口更多的体现在对行为的抽象

接口的特点
1、 接口使用关键字interface修饰
2、 类实现接口用
implements表示
3、 接口不能实例化

接口如何实例化呢?参照多态的方式,通过实现类对象实例化,这叫接口多态
多态的形式:具体类多态,抽象类多态,接口多态
4、 接口的实现类
a) 要么重写接口中所有的抽象方法
b) 要么就是抽象类

接口的成员特点
1、 成员变量
a) 只能是常量
b) 默认修饰符:public static final
也使被省略了
2、 构造方法
a) 接口没有构造方法,因为接口主要是对行为进行抽象的,没有具体存在
b) 一个类如果没有父类,默认继承Object (祖宗)
3、 成员方法
a) 只能是抽象方法
b) 默认修饰符:public abstract
只是被省略了

类和接口的关系
1、 类和类的关系
a) 继承关系,只能单继承,但是可以多层继承
2、 类和接口的关系
a) 实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口
3、 接口和接口的关系
a) 继承关系,可以单继承,也可以多继承

接口和接口之间可以多继承,但是类和类之间只能是单继承。
类名作为形参和返回值
1、 方法的形参是类名,其实需要的就是该类对象
2、 如果方法的返回值是类名:其实返回的是该类的对象

抽象类名作为形参和返回值
1、 方法的形参是抽象类名,其实需要的是该抽象类的子类对象
2、 方法的返回值是抽象类名,其实返回的是该抽象类的子类对象

接口名作为形参和返回值
1、 方法的形参是接口名,其实需要的是该接口的实现类对象
2、 方法的返回值是接口没,其实返回的是该接口的实现类对象

抽象类作为形参和返回值的话需要的是其子类对象,类作为形参和返回值则需要的是该类对象,接口名作为形参和返回值的话需要的是其接口的实现类对象

内部类:

就是在一个类中再定义一个类
内部类的访问特点
1、 内部类可以直接访问外部类的成员,包括私有
2、 外部类要访问内部类的成员,必须创建对象

匿名内部类:
前提:存在一个类或者接口,这里的类可以是具体类也可以是抽象类
本质:是一个继承了该类或者实现了该接口的子类匿名对象

常用API

Math :Math包含执行基本数字运算的方法
没有构造方法,如何使用类中的成员呢?
看类的成员是否都是静态的,如果是,通过类名可以直接调用
Java学习记录 课程来自黑马刘意(风清扬)19年版_第9张图片
System
Java学习记录 课程来自黑马刘意(风清扬)19年版_第10张图片

Object类

Object是类层次结构的根,每个类都可以将Object作为超类所有类都直接或者间接的继承该类
为什么说子类的构造方法默认访问的是父类的无参构造方法?
因为它们的顶级父类只有无参构造方法。
看方法的源码,选中方法,按下Ctrl+B
Java学习记录 课程来自黑马刘意(风清扬)19年版_第11张图片
观Object类中的equals有感 类原来可以自动生成比较方法,那么.equals在字符串中比较的是内容是否相等,但是在类中却是默认比较地址,所有要重写.equal()的方法之后就可以比较对象内容是否相等了。别忘记还要重写hashcode()方法

冒泡排序

相邻两两进行比较,大的放后面,
1、 如果有n个数据进行排序,总共需要比较n-1次。
2、 每一次比较完毕,下一次的比较就会少一个数据参与。
3、 每一轮都会出现一个最大值
思路:两个循环 外循环控制趟数,内循环每趟减去外循环次数再减一个1 因为每趟比较都会少一个值,并且每趟的最大值会放在最后面

Arrays

Arrays类包含用于操作数组的各种方法
不是array数组
使用来操作数组的
比较好用的是sort排序方法
Java学习记录 课程来自黑马刘意(风清扬)19年版_第12张图片
工具类的设计思想(Arrays,Math,System)
1、 构造方法用private修饰
a) 为了防止被外界创建对象
2、 成员用public static 修饰
a) 为了可以通过使用类调用

Java学习记录 课程来自黑马刘意(风清扬)19年版_第13张图片

**基本类型包装类

再创建pojo的时候里面的属性都需要用包装类 这样不会默认为空值**
将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据
常用的操作之一:用于基本数据类型与字符串之间的转换。

其他都是把他弄成大写的 只有char变成Character
Interger类的概述和作用
Interger:包装一个对象中的原始类型int的值
在这里插入图片描述
int和String的相互转换
基本类型包装类的最常见操作就是:用于基本类型和字符串之间的相互转换

String是valueOf() int是parstInt()
自动装箱和拆箱
1、 装箱:把基本数据类型转换为对应的包装类类型
2、 拆箱:把包装类类型转换为对应的基本数据类型
int转为String 用String的方法valueOf(int i)
String转为int 用Integer的方法parseInt(String s)
自动装箱操作 Integer ii=100; .//其实做了Interger.valueOf(100);
自动拆箱操作 ii+=200; //其实做了 ii.intValue()+200;的操作

注意:在使用包装类类型的时候,如果做操作,最好先判断是否为null
开发须知:推荐:只要是对象,在使用前必须进行不为null的判断。

日期类

Date类常用方法
Java学习记录 课程来自黑马刘意(风清扬)19年版_第14张图片
SimpleDateFromat
它是一个具体的类,用于以区域设置敏感的方式格式化和解析日期。我们重点学习日期格式化和解析
Java学习记录 课程来自黑马刘意(风清扬)19年版_第15张图片
日期和事件格式由日期和事件模式字符串指定,在日期和时间模式字符串中,从A到Z以及从’a’到‘z’引号的字母被解释为表示日期或事件字符串的组件的模式字母
常用的模式字母及对应关系如下
常用时间格式patten: yy-MM-dd HH:mm:ss

Calendar类
为某一时刻和一组日历字段之间转换提供了一些方法,并且为操作日历字段提供了一些方法
Java学习记录 课程来自黑马刘意(风清扬)19年版_第16张图片
Calendar 提供了一个类方法 getInstance用于获取Calendar对象,因为Calendar是抽象类,其日历字段已使用当前日期和时间初始化
类似抽象类的实例化(也是抽象类实例化的一个例子)
Calendar rightNow=Calendar.getInstance

异常概述

异常:就是程序出现了不正常的情况
异常体系:

Error:严重问题,不需要处理
Exception:称为异常类,它表示程序本身可以处理的问题

我们处理的都是Exception类
1、 RuntimeException:在编译期是不检查的,出现问题后,需要我们回来修改代码
2、 非RuntimeException:编译期就必须处理的,否则程序不能通过编译,就更不能正常运行了。
异常处理
如果程序出现问题,我们有两种方案来处理异常
1、 try catch
2、 throws
Throwable的成员方法

throws异常和try catch异常的区别
throws异常只是将异常抛出,并没有处理异常,如果采用throws异常的话,将来谁调用这个方法就由谁来处理,最后处理的方式还是用try catch

使用thorws只会将异常抛出 不会向下执行 程序就此结束
而try catch就会往下执行直到程序结束

Thow和Throws的区别
thorws表示抛出异常,但是不一定会有异常,throw表示一定抛出了某种异常
throw用在方法体内
而throws跟在方法体后面

Collection

集合知识回顾
集合类的特点:提供一种存储空间可变的存储模型,存储的数据容量可以随时发生改变。
Java学习记录 课程来自黑马刘意(风清扬)19年版_第17张图片
Collection 单列 Map双列 接口
List 可重复 Set 不可重复 接口
ArrayList 实现类
Java学习记录 课程来自黑马刘意(风清扬)19年版_第18张图片

IDEA中 alt+7 打开一个窗口,能够看到类的所有信息

collection集合的遍历
Iterator:迭代器,集合的专用遍历方式。
1、 Iterator iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到
2、 迭代器是通过集合的iterator()方法得到的,所以说迭代器是依赖集合而存在的。

Iterator中的常用方法
1、E next():返回迭代中的下一个元素
2、Boolean hasNext():如果迭代具有更多元素,则返回true

List集合特点:
1、 有序:存储和取出的元素顺序一致
2、 可重复:存储的元素可以重复
3、 带索引,可以根据索引增删查改元素

并发修改异常
ConcurrentModificationException
1、 产生原因
a) 迭代器遍历的过程中,通过集合对象修改了集合中元素的长度,造成了迭代器获取元素中判断预期修改值和实际修改值不一样。
2、 解决方案
a) 用for循环遍历,然后用集合对象做对应的操作即可。
ListIterator:列表迭代器
这是List集合特有的迭代器

其中它有hasPrivious方法 它可以从后向前遍历。
其中它的add方法 注意 是迭代器中的add的 不是list中的add 方法 ,可以解决并发修改异常。

但是这个迭代器不怎么用,仅作了解

增强for:简化数组和Collection集合的遍历 现实开发中经常用到

		底层是实现Iterable接口的类
		是JDK5之后出现的,其内部原理是一个Iterator迭代器
		格式:
		for(元素数据类型 变量名:数组或collection集合){
//在此处使用变量即可,该变量就是元素

}
Java中的数据结构
数组是一种查询快,增删慢的模型,因为查询数据可以通过索引,但是删除和添加需要前移或者后移元素
链表是一种增删快,查询慢的模型(对比数组来说)

List集合常用子类:ArrayList,LinkedList
1、 ArrayList
a) 底层数据结构是数组,查询快,增删慢
2、 LinkedList
a) 底层数据结构是链表,查询慢,增删快
注意:在未来开发的过程中,如果不清楚到底要查询还是增删,那么选择ArrayList,比较常用。
Java学习记录 课程来自黑马刘意(风清扬)19年版_第19张图片
Set集合
1、 不包含重复元素的集合
2、 不带索引,所以不能使用普通for循环遍历
所以 普通for是需要集合有带索引才可以使用的
HashSet:是Set集合的一个子类,对集合的迭代顺序不做任何保证,就是说输出顺序是乱的

哈希值:是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
Object类中有一个方法可以获取对象的哈希值

public int hashCode():返回对象的哈希码值
对象的哈希特点
1、 同一个对象多次调用hashCode()方法返回的哈希值是相同的
2、 默认情况下,同一对象new出来的不同的实例的哈希值是不同的。而重写hashCode()方法,可以实现让对象的哈希值相同
例子
String的HashCode返回的值是一样的,因为String把hashCode方法重写了
HashSet集合特点
1、 底层数据结构是哈希表
2、 有set集合的共有特点

set方法是如何实现元素唯一性?
因为重写hashCode()和equals(),在类(对象)中重写

LinkedHashSet
1、 哈希表和链表实现的Set接口,具有可预测的迭代次序
2、 由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
3、 由哈希表保证元素唯一。
所以LinkedHashSet能保证实现的链表是有序且唯一的
集合中<>尖括号中所填元素应该是数据类型的包装型
TreeSet集合特点
1、 元素有序,这里的顺序不是值存储和取出的顺序,而是按照一定的规则进行排序,具体排序方式取决于构造方法
a) TreeSet():根据其元素的自然排序进行排序
b) TreeSet(Comparator comparator):根据指定的比较器进行排序

TreeSet使用结论:
1、 用TreeSet集合存储自定义对象,无参构造方法使用的是自然排序对元素进行排序
2、 自然排序,就是让对象类实现Comparable接口,重写compareTo()方法
3、 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写

TreeSet如果使用带参构造方法,就可以使用匿名类的方式 在TreeSet创建的过程中的方法new一个Comparator的方法,在里面重写compare方法

泛型概述

Java学习记录 课程来自黑马刘意(风清扬)19年版_第20张图片
泛型的本质是参数化类型
就是将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型
泛型的好处
1、 把运行时期的问题提前到了编译期间
2、 避免了强制类型转换

泛型类
Java学习记录 课程来自黑马刘意(风清扬)19年版_第21张图片
修饰符 class 类名<类型>{}
泛型方法
Java学习记录 课程来自黑马刘意(风清扬)19年版_第22张图片
泛型接口
Java学习记录 课程来自黑马刘意(风清扬)19年版_第23张图片
泛型相当于一个模板 把里面的T当成一个实体例如来看
类型通配符
Java学习记录 课程来自黑马刘意(风清扬)19年版_第24张图片

可变参数

public static int sum(int…a) 这是Java8新特性
在这里插入图片描述

可变参数注意事项:
1、 这里的变量…a其实是一个数组
2、 如果方法有多个参数,包含可变参数,那么可变参数要放在最后面
Java学习记录 课程来自黑马刘意(风清扬)19年版_第25张图片

Map集合概述

不能包含重复的键,每个键只能映射到最多一个值
创建Map集合的对象
1、 多态的方式
2、 具体的实现类HashMap(哈希来保证键的唯一性)
Java学习记录 课程来自黑马刘意(风清扬)19年版_第26张图片
大部分方法和集合一样
Java学习记录 课程来自黑马刘意(风清扬)19年版_第27张图片
keySet可以获取所有键的集合
在hashMap中,如果要让键一样的对象覆盖前面的对象数据,如果键是对象。那么需要重写.equeal和hashCode()方法才能实现

TreeMap和TreeSet一样 可以让无序的集合变得有序

Collections类

	是针对集合操作的工具类

在这里插入图片描述
这里有一个案例挺好的 综合了集合的知识
Java学习记录 课程来自黑马刘意(风清扬)19年版_第28张图片
有兴趣的可以做一下 这里附上代码

 public static void main(String[] args) {
        //
        HashMap<Integer, String> map = new HashMap<Integer, String>();
        ArrayList<Integer> list = new ArrayList<Integer>();
        //创建扑克牌
        String colors[] = {"☮", "✝", "☪", "♊"};
        String numbers[] = {"2", "3", "4", "5", "6", "7", "8", "9", "J", "Q", "K"};
        //存入数组
        int index = 0;
        for (String o : colors) {
            for (String o1 : numbers) {
                map.put(index, o + o1);
                list.add(index);
                index++;
            }
        }
        map.put(index, "小王");
        list.add(index);
        index++;
        map.put(index, "大王");
        list.add(index);
        //洗牌
        Collections.shuffle(list);
        //发牌
        TreeSet<Integer> wangjia1 = new TreeSet<Integer>();
        TreeSet<Integer> wangjia2 = new TreeSet<Integer>();
        TreeSet<Integer> wangjia3 = new TreeSet<Integer>();
        TreeSet<Integer> dipai = new TreeSet<Integer>();
        for (int i = 0; i < list.size(); i++) {
            int porker = list.get(i);
            if (i >= list.size() - 3) {
                dipai.add(porker);
            } else if (i % 3 == 0) {
                wangjia1.add(porker);
            } else if (i % 3 == 1) {
                wangjia2.add(porker);
            } else if (i % 3 == 2) {
                wangjia3.add(porker);
            }
        }
        lookPorker("wangjia1", wangjia1, map);
        lookPorker("wangjia2", wangjia2, map);
        lookPorker("wangjia3", wangjia3, map);


    }

    public static void lookPorker(String name, TreeSet<Integer> set, HashMap<Integer, String> map) {
        System.out.print("玩家" + name + "的牌是");
        for (int s : set) {
            String s1 = map.get(s);
            System.out.print(s1 + " ");
        }
        System.out.println();
    }

IO流

File:它是文件和目录路径名的抽象表示
1、 文件和目录是可以通过File封装成对象的
2、 对于File而言,其封装只是一个路径名而已。它可以是存在的,也可以是不存在的。将来要通过具体的操作把这个路径的内容转换为具体存在的。
File的构造方法
Java学习记录 课程来自黑马刘意(风清扬)19年版_第29张图片
File的创建功能
Java学习记录 课程来自黑马刘意(风清扬)19年版_第30张图片
如果存在 则返回false 表示文件已存在
如果不存在 则返回true 表示文件不存在 创建成功!
创建文件用createNewFile(),创建文件夹用mkdir(),但是这个方法不能创建多级目录,创建多级目录需要用到mkdirs()
注意:文件就是文件 目录就是目录 创建文件就用创建文件的方法,创建目录就用创建目录的方法
File类判断和获取功能
Java学习记录 课程来自黑马刘意(风清扬)19年版_第31张图片
前面三个为判断文件的存在 中间三个表示获取文件的信息 后面两个则表示获取这个目录的名字和获取这个目录的所有东西

File类删除功能
Java学习记录 课程来自黑马刘意(风清扬)19年版_第32张图片
绝对路径和相对路径的区别:
1、 绝对路径
a) 完整的路径名,不需要任何其他信息就可以定位它所表示的文件。例如:E:\itcast\java.txt
2、 相对路径
a) 必须使用取自其他路径名的信息进行解释。例如:myFile\java.txt
删除目录的注意事项:
如果一个目录中有内容,不能直接删除。应该先删除目录中的文件,最后才能删除目录

递归

递归概述:以编程的角度来看,递归指的是方法定义中调用方法本身的现象
递归解决问题的思路:
把一个复杂的问题层层转化成为一个与原问题相似的规模较小的问题来求解
递归策略只需要少量的程序就可以描述出解题过程所需要的多次重复计算
递归解决问题需要找到两个内容:
1、 递归出口:否则会出现内存溢出
2、 递归规则:与原问题相似的规模较小的问题

IO流概述:

1、 IO:输入/输出
2、 FileInputStream 继承自InputStream
3、 FileOutputStream 继承自OutputStream

4、 流:是一种抽象概念,是对数据传输的总称。也就是说数据在设备间的传输称为流,流的本质是数据传输
5、 IO流就是用来处理设备间数据传输问题的
a) 常见的应用:文件复制;文件上传;文件下载
IO流分类:
1、 按照数据的流向
a) 输入流:读数据
b) 输出流:写数据
2、 按照数据类型来分
a) 字节流
i. 字节输入流,字节输出流
b) 字符流
i. 字符输入流;字符输出流
一般来说,我们说的IO流的分类是按照数据类型来分的
那么两种流都在什么情况下使用呢?
1、 如果数据用记事本打开不乱码就用字符流
否则使用字节流,如果不知道该使用哪种类型的流,就使用字节流 字节流是万能的流

字节流写入数据
字节流抽象基类:
Input和output都是相对于程序来说的
1、 InputStream:这个抽象类是表示字节输入流的所有类的超类
2、 OutputStream:这个抽象类是表示字节输出流的所有类的超类

3、 子类名的特点:子类名称都是以其父类名作为子类名的后缀 例如对File进行操作的话就是FileOutputStream

FileOutputStream:文件输出流用于将数据写入File 用于写数据
1、 FileOutputStream(String name):创建文件输出流以指定的名称写入文件

使用字节输出流写入数据的步骤:
1、 创建字节输出流对象
在这里插入图片描述
2、 调用字节输出流对象的写数据方法
在这里插入图片描述
3、 释放资源
在这里插入图片描述

字节流读数据
FileInputStream:从文件系统中的文件获取输入字节 用于读取数据
FileInputStream(String name):通过打开与实际文件的连接来创建一个FileInputStream,该文件由文件系统中的路径名name命名

使用字节输入流读数据的步骤:
1、 创建字节输入流对象
2、 调用字节输入流对象的读数据方法
3、 释放资源

字节输入标准读数据方法
Java学习记录 课程来自黑马刘意(风清扬)19年版_第33张图片
一次读一个字节数组的数据
在这里插入图片描述

字节缓冲流
1、 BufferOutputStream:该类实现缓冲输出流。通过设置这样的输出流,应用程序可以向底层输出流写入字节,而不必为写入的每个字节导致底层系统的调用
2、 BufferInputStream:同理可得,
Buffer 缓冲区
构造方法
1、 字节缓冲输出流:
a) BufferedOutputStream(OutputStream out)
2、 字节缓冲输入流:
a) BufferedInputStream(InputStream in)
为什么构造方法需要的的是字节流,而不是具体的文件或者路径呢?
1、 字节缓冲流仅仅提供缓冲区,而真正的读写数据还得靠基本的字节流对象进行操作。

用Buffer的输入输出流更快更省内存。

字符流

ReaderWriter是字符流所有子类的超类
InputStreamReader 继承自Reader
OutputStreamWriter继承自Writer
为什么会出现字符流:
由于字节流操作中文不方便,所以Java提供字节流
字符流=字节流 (底层还是字节流)+编码表
用字节流复制文本文件时,文本文件有中文,但是没有问题,原因是底层操作会自动将字节拼接成中文。
怎么识别字节是不是中文
汉字在存储的时候,无论选择哪种编码存储,第一个字节是负数
编码表
基础知识:
1、 计算机中存储的信息都是用二进制数表示的;我们在屏幕上看到的英文、汉字等字符是二进制数转换后的结果
2、 按照某种规则,将字符存储到计算机中,称为编码。反之,将存储在计算机中的二进制数按照某种规则解析显示出来,称为解码。

a) 强调:按照什么规则编码方式的存储,就得用什么规则解析,否则会出现乱码现象。
i. 字符编码:就是一套自然语言的字符与二进制数之间的关系规则
字符集
是一个系统支持的所有字符的集合,包括各国家文字、标点符号、图形符号等
常见的字符集由ASCII GBK Unicode

字符流写数据的5种方式
Java学习记录 课程来自黑马刘意(风清扬)19年版_第34张图片
Java学习记录 课程来自黑马刘意(风清扬)19年版_第35张图片

flush表示刷新,可以实时查看 close则在关闭之前先默认调用了一遍flush
Java学习记录 课程来自黑马刘意(风清扬)19年版_第36张图片
read方法返回的int值其实是编码表里的一个值 例如a返回的就是97
FileReader:用于读取字符文件便捷流
FileReader(String name)
FileWriter:用于写入字符文件便捷类
FileWriter(String name)
继承自InputStreamReader和OutputStreamWriter 更加便捷,但是遇到需要转换编码格式的话还是要用父类
BufferWriter和BufferReader
在这里插入图片描述

缓冲区的默认大小 8192

字符缓冲流特有功能
BufferedWriter:
void newLine():写一行分隔符,行分隔符字符串由系统属性定义
BufferedReader:
public String readLine():读一行文字。结果包含行的内容的字符串,不包含任何行的终止字符,需要手动添加换行 如果流的结尾已经到达,则为null

用BufferWriter写数据
Java学习记录 课程来自黑马刘意(风清扬)19年版_第37张图片
IO流小结
字节流小结
Java学习记录 课程来自黑马刘意(风清扬)19年版_第38张图片Java学习记录 课程来自黑马刘意(风清扬)19年版_第39张图片

字节流可以复制任意文件数据
字符流小结:
Java学习记录 课程来自黑马刘意(风清扬)19年版_第40张图片Java学习记录 课程来自黑马刘意(风清扬)19年版_第41张图片

标准输入输出流
System类中又两个静态的成员变量:
1、 public static final InputStream in:标准输入流。通常该流对对应键盘输入或由主机环境或用户指定的另一个输入源
2、 public static final PrintStream out:标准输入流。通常该流对应显示输出或由主机环境或者用户指定的另一个输出目标
自己实现键盘录入数据
InputStream in = System.in
1、 BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
写起来太麻烦 所以Java提供了一个类实现键盘输入
Scanner sc=new Scanner(System.in);
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
这两句话其实是一个意思
输出语句的本质:是一个标准的输出流

打印流
1、 PrintStream ps=System.out
2、 PrintStream类所有的方法,System.out都可以使用
所以用System.out.printLn 其实是PrintStream ps ps.printLn()
打印流
1、 字节打印流
a) PrintStream
2、 字符打印流:
a) PrintWriter

打印流的特点:
1、 只负责输出数据,不负责读取数据
2、 有自己的特有方法 Print
字节打印流
1、 PrintStream(String fileName):使用指定的文件名创建新的打印流
2、 使用继承父类的方法写数据,查看的时候会转码;使用自己特有方法写数据,查看的数据原样输出

字符打印流:
Java学习记录 课程来自黑马刘意(风清扬)19年版_第42张图片
使用第二个构造方法autoFlush值传True的时候会自动更新 不用手动添加flush

对象序列化流 ObjectOutputStream
1、 将Java对象的原始数据类型和图形写入OutputStream,可以使用ObjectInputStream读取重构对象,可以通过使用流的文件来实现对象的持久存储,如果流是网络套接字流,则可以在另一个主机上或另一个进程中重构对象。在分布式系统中,所有实体类都会实现Serializable接口的原因
在这里插入图片描述
一个对象想要被序列化,该对象所属的类必须实现Serializable接口
Serializable是一个标记接口,实现该接口,不需要重写任何方法
对象的反序列化流
Java学习记录 课程来自黑马刘意(风清扬)19年版_第43张图片

对象的序列化概述

使用流的技术将对象直接保存到文件中的过程则称为对象的序列化。
实现对象序列化操作需要使用到的流:ObjectOutputStream

对象的反序列化概述

使用流的技术从文件中读取对象的过程则称为对象的反序列化。
实现对象反序列化操作需要使用到的流:ObjectInputStream

对象序列化流
会出现的问题以及解决办法
如果我们修改了对象所属的类文件,读取数据会出现InvalidClassException异常
解决方法:在类中添加一个属性serialVersionUID
如果有某个成员变量不想被序列化
那么给变量加transient关键字修饰 那么被标记的成员不参与序列化

Properties概述

⚪是一个Map体系的集合类
⚪Properties可以保存到流中或从流中加载

主要作用是读取文件的键值对属性 和IO结合 很简单的一个案例 可以读取游戏中的文本文档参数
作为集合
Java学习记录 课程来自黑马刘意(风清扬)19年版_第44张图片
和IO流结合
Java学习记录 课程来自黑马刘意(风清扬)19年版_第45张图片

进程

从这章开始进入高级

进程之后有线程 多个线程组成进程
线程
单线程:一个进程如果只有一条执行路径,则称为单线程程序
多线程:一个进程如果有多条执行路径,则称为多线程程序

多线程的实现方式
方法1、继承Thread类
① 定义一个类MyThread继承Thread类
② 在MyThread类中重写run()方法
③ 创建MyThread类的对象
④ 启动线程
两个问题:
为什么要重写run方法?
因为run方法是用来封装被线程执行的代码
run方法和start方法的区别?
run():封装线程执行的代码,直接调用,相当于普通方法的调用
start():启动线程;然后由JVM调用此线程的run()方法

所以说要启动线程的话一定要调用start方法 而不是调用run方法
Thread类中设置和获取线程名称的方法
void setName(String name) 将此线程的名称更改为等于参数name
String getName():返回此线程的名称
也可以通过构造方法设置线程名称
需要在继承Thread的那个类中写构造方法
如何获取main()所在的线程名称?
static Thread currentThread()返回对当前正在执行的线程对象的引用
在这里插入图片描述

线程调度

1、 分时调度模型:所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间片
2、 抢占式调度模型:优先让优先级高的线程使用CPU,如果线程的优先级相同,那么就随机选择一个,优先级高的获取的CPU时间片相对多一些
Java使用的是抢占式调度模型
假如计算机只有一个CPU,那么CPU在某一个时刻只能执行一条指令,线程之间只有得到CPU才可以执行指令。所以说多线程程序的执行是有随机性,谁抢到CPU是不确定的。

线程的默认优先级是5;线程优先级的范围是1-10
也就是说线程优先级高不一定运行在最前面,也有可能被线程优先级低的抢占了。
Java学习记录 课程来自黑马刘意(风清扬)19年版_第46张图片
setDaemon 相当于守护线程 如果存在三个线程,将其中两个线程设置为守护线程,当主线程GG 那么守护的两个线程也GG 但不是立马GG 还会挣扎一下
join方法就是相当于等待线程执行完毕
sleep 睡眠一段时间
线程的生命周期
Java学习记录 课程来自黑马刘意(风清扬)19年版_第47张图片
多线程的实现方式2
① 定义一个类MyRunnable实现Runnable接口
② 在MyRunnable类中重写run()方法
③ 创建MyRunnable类对象
④ 创建Thread类的对象,把MyRunnable对象作为构造方法的参数
⑤ 启动线程
多线程的实现方案有两种
1、 继承Thread类
2、 实现Runnable接口

相比继承Thread类,实现Runnable接口的好处
1、 避免了Java单继承的局限性, 实现Runnable接口后还可以继承其他类,而Thread类则不行
2、 适合多个相同程序的代码去处理同一个资源的情况,把线程和程序的代码、数据有效分离,较好的体现了面向对象的设计思想

线程同步

同步代码块
Java学习记录 课程来自黑马刘意(风清扬)19年版_第48张图片
任意对象是一个Object类 所以我们在类中定义一个new Object 这样三个线程指向一个Object 否则在方法中使用new Object的话就会有问题 因为会有三把锁

同步的好处和弊端
1、 好处:解决的多线程的数据安全问题
2、 弊端:每个线程都会去判断同步上的锁 浪费资源 无形中会降低程序的运行效率

同步方法
Java学习记录 课程来自黑马刘意(风清扬)19年版_第49张图片
在同步方法上 正常方法的锁对象是this
而在静态方法上 锁对象是类名.class

三个线程安全的类

在这里插入图片描述
因为这三个类的方法中都加了synchronized,虽然线程安全但是执行缓慢
Vector被 ArrayList替代
StringBuffer被StringBuilder替代
Hashtable被HashMap替代

Lock锁

Lock实现提供了比使用synchoronized方法和语句更加广泛的锁定操作,可以更清晰的看到哪里加了锁和释放了锁
void lock():获得锁
void unlock():释放锁

Lock时接口不能直接实例化,采用它的实现类ReentrantLock来实例化
使用方法
使用Try finally语句块来加锁和解锁
Java学习记录 课程来自黑马刘意(风清扬)19年版_第50张图片
生产者和消费者模式概述
Java学习记录 课程来自黑马刘意(风清扬)19年版_第51张图片
wait就是等待方法 notify是唤醒操作

网络编程

计算器网络
1、 指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通线线路连接起来,在网络操作系统,网络管理及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。
2、 网络编程
a) 在网络通信协议下,实现网络互连的不同计算机上运行的程序间可以进行数据交换
网络编程三要素
1、 IP地址
a) IP地址为每台计算机指定一个标识号
2、 端口
a) 应用程序的标识号
3、 协议
a) 通信之间的规则

IP地址
IP分为两类
1、 IPV4
a) 给每个连接在网络上的主机分配一个32bit地址。按照TCP/IP规定,IP地址用二进制来表示
b) 每个地址32bit 也就是4个字节
c) 二进制IP地址 11000000 10101000 00000001 01000010
d) 将上述地址改为十进制IP地址就是192.168.1.66
2、 IPV6
a) 128为地址长度 每16个字节一组 为了解决网络地址资源数量不够的问题

常用命令
1、 ipconfig:查看本机ip地址
2、 ping IP地址:检查网络是否连通

特殊IP地址
127.0.0.1 是回送地址,可以代表本机地址,一般用来测试使用

InetAddress的使用
为了方便我们对IP地址的获取和操作,Java提供了一个类InetAddress供我们使用
此类表示Internet协议IP地址
掌握三个方法
Java学习记录 课程来自黑马刘意(风清扬)19年版_第52张图片
第一个方法getByName 返回一个InetAddress对象 在里面输入自己电脑的设主机号就可以获得address
第二个和第三个方法都是通过address来获取主机名或者IP地址

端口:
是设备上应用程序的唯一标识
端口号:
取值范围是0~65535 其中0~1023之间的端口号用于一些知名的网络服务和应用,普通的应用程序需要使用1024以上的端口号。如果端口号被另一个服务或者应用占用,会导致当前程序启动失败(端口被占用)
UDP协议
1、 用户数据报协议
2、 UDP是无连接通信,发送端不会确认接收端是否存在,就会发出数据,同时接收端也不会向发送端反馈是否受到数据。
3、 通常用来传输视频或者音乐,但是因为UDP的无连接性,不能保证数据的完整性,所以在传输重要数据时不建议使用UDP协议
TCP协议
1、 传输控制协议
2、 TCP协议时面向连接的通信协议,提供可靠无差错的数据传输。客户端和服务器发出连接请求都要经过三次握手
3、
Java学习记录 课程来自黑马刘意(风清扬)19年版_第53张图片

UDP通信原理

UDP是一种不可靠的网络协议,它在通信的两端各建立一个Socket对象没有所谓的客户端和服务器的概念
Java提供了DatagramSocket作为基于UDP协议Socket
UDP发送数据
Java学习记录 课程来自黑马刘意(风清扬)19年版_第54张图片
UDP接收数据
Java学习记录 课程来自黑马刘意(风清扬)19年版_第55张图片

TCP通信原理:

在通信的两端各建立一个Socket对象,从而在两端形成网络虚拟链路。
Java对TCP协议进行了良好的封装,使用Socket对象来代表两端的通信端口,并通过Socket产生IO流来进行网络通信
Java为客户端提供了Socket类,为服务器端提供了ServerSocket类

TCP发送数据
Java学习记录 课程来自黑马刘意(风清扬)19年版_第56张图片
TCP接收数据
Java学习记录 课程来自黑马刘意(风清扬)19年版_第57张图片
在TCP协议中,在服务端接收数据后,需要调用accept()方法

类加载

程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过类的加载类的连接类的初始化这个三个步骤来对类进行初始化
如果不出意外情况,JVM将会连续完成这三个步骤,所以有时也把这三个步骤统称类加载或者类初始化
类的加载
1、 就是指将class文件读入内存,并为之创建一个java.lang.Class对象
2、 任何类被使用时,系统都会为之java.lang.Class对象

类的连接
在这里插入图片描述
类的初始化
在这里插入图片描述
类的初始化步骤
在这里插入图片描述
类的初始化时机
Java学习记录 课程来自黑马刘意(风清扬)19年版_第58张图片

类加载器

ClassLoader:是负责加载类的对象
1、 负责将.class文件加载到内存中,并为之生成对应的java.lang.Class对象
2、 虽然我们不用过分关心类加载器机制,但是了解这个机制我们就能更好的理解程序运行。
Java运行时具有以下内置类加载器
Java学习记录 课程来自黑马刘意(风清扬)19年版_第59张图片
ClassLoader中的两个方法
在这里插入图片描述

反射

许多框架就是用的 这个机制
Java反射机制:是指在运行时去获取一个类的变量和方法信息。然后通过获取到的信息来创建对象,调用方法的一种机制。由于这种动态性,可以极大的增强程序的灵活性,程序不用在编译期间就完成,在运行期间仍然可以扩展。
获取class类的对象
我们想要通过反射去使用一个类,首先我们要获取到该类的字节码文件,也就是类型为class类型的对象,这里我们提供三种方式来获取class类型的对象
1、 通过类的.class来获取
2、 通过实例出来的类对象的.getClass()方法来获取
3、 通过Class.forName(String className); 传入字符串来获取

举例
Java学习记录 课程来自黑马刘意(风清扬)19年版_第60张图片
反射获取构造方法并使用
Class类中用于获取构造方法的方法
在这里插入图片描述
Constructor类中用于创建对象的方法
在这里插入图片描述
是用来初始化/创建对象
如果在实际开发中已经创建好相应对象的话就不用再创建了
反射获取成员变量并使用
Class类中用于获取成员变量的方法
在这里插入图片描述
Field类中用于给成员变量赋值的方法
在这里插入图片描述
反射获取成员方法并使用
Class类中用于获取成员方法的方法
在这里插入图片描述
Method类中用于调用成员方法的方法
Java学习记录 课程来自黑马刘意(风清扬)19年版_第61张图片
setAccessbale这个方法是很有用的。把私有的方法、属性、构造方法让其可创建

反射能越过泛型检查
Java学习记录 课程来自黑马刘意(风清扬)19年版_第62张图片

反射读取配置文件来运行指定程序(框架里面应该用的是这个)
Java学习记录 课程来自黑马刘意(风清扬)19年版_第63张图片
模块化
模块化概述
Java语言随着这些年的发展已经成为了一门影响深远的编程语言,无数平台,系统都采用Java语言编写,但是,伴随着发展,Java也越来越庞大,逐渐发展成为了一门臃肿的语言。无论是运行多大的程序,只要成需要运行Java中的核心模块,就要加载整个JRE环境,为了个Java瘦身,让Java实现轻量化,Java9正式提出模块化系统并允许Java程序可以根据需要选择加载程序必须的Java模块,这样就可以让Java以轻量化的方式来运行
模块不适用Java8
以上为个人学习笔记,里面难免会出错。

你可能感兴趣的:(java学习,java)