零、历史和特点

1.历史

(1)作者:James-Gosling

(2)主要发展历程

1995.5.23SUN公司  正式发布了Java语言
1996年1月    开发工具包JDK1.0
1997年2月    JDK1.1版本问世
1998年12月  JavaEE企业版
1999年6月Java第二代平台JDK1.2  细化了三个不同的小版本(不同方向)(J2SE)Java2  Standard  Edition Java第二代平台标准版   桌面级  C/S(J2EE)Java2  Enterprise Edition  Java第二代平台企业版   企业级  B/S(J2ME)Java2  Micro  Edition      Java第二代平台微型版   移动端
2000--2002JDK1.3    JDK1.4大幅度提升了Java性能
2004年5月JDK1.5版本发布   很多新的特性   Java5
2005年6月Java6   最经典的版本   留存最久的版本
2009年Oracle  并购   74亿$Java易主
2011年   Oracle   Java7
2014年   Java8
2017年   Java9

(3)环境搭建

  • JVM:Java Virtual Machine是Java虚拟机

    内存中开辟一块空间    源文件   编译   字节码Java计算机高级编程语言程序存储在哪里?-----程序就是英文----存储在一个地方(文件)我们写完的程序--计算机不认识--编译   我们写好的源文件编译成计算机识别的字节码文件最终有两个文件   源文件    字节码文件  两个文件存在哪?--硬盘上计算机的硬件组成内存(条形 8G 芯片 寻址 临时执行使用)  硬盘(矩形 1T 机械 扇区 永久性保存)硬盘上的文件  不同的格式  后缀名区分不同的格式.txt  .doc  .ppt  .xls  .mp4  .mp3  .rar  .exe  运行环境支持源文件.java(文本文档打开)  字节码.class
    
  • JRE:Java Runtime Environment是Java运行环境

    运行别人写好的java程序
    
  • JDK:Java Development Kit是Java开发工具包

    开发时需要用到的工具javac.exe 编译工具java.exe   执行工具 底层doc命令窗口中看到效果
    JDK中包含了JRE。
    

2.特点

(1)跨平台性

在不同厂商的芯片,不同版本的操作系统,均可运行。

(2)面向对象

  • 特征:封装、继承、多态、抽象

(3)简单性

省去了C++多继承,指针等

(4)健壮性(鲁棒性)

垃圾回收机制,异常处理机制

(5)多线程性

并行操作,提高执行性能。

(6)大数据开发

一、Java基础

1.基础部分

(1)基本数据类型

  • 命名规范和规约

    规范:必须要遵守的名字中可以有字母,区分大小写;数字(0-9),不能以数字开头;可以有符号_和$;中文也可以,不推荐。
    规约:要求见名知意,不做强制要求。类名字:首字母大写,后面驼峰命名。例如:SuperPerson属性/方法/变量:首字母小写,后面驼峰命名。例如:superPerson构造方法:与类名一致。例如:SuperPerson静态常量:全部字母大写,通过_分割。例如:SUPER_PERSON包名字:所有字母均小写,不要有别的字符。例如:domeone私有属性对应方法:getName,setName;均不能和Java关键字冲突。
    
  • 基本数据类型有8个

    4整型:byte,short,int,longbyte:1字节,-128到127short:2字节,-32768到32767int:4字节,-2147483648到2147483647long:8字节
    2浮点型:float,doublefloat:4字节double:8字节
    1字符型:charchar:2字节
    1布尔型:booleanboolean:1位
    

(2)常量与变量

  • 常量

    常量代表是程序运行过程中  不能再次改变的值
    1.固定不变的值:比如π=3.14。。。
    2.特殊的常量String
    3.自己定义:final int UP = 1;
    
  • 变量

    程序执行过程中可以改变的
    变量是一个内存空间(小容器)
    变量空间在创建(声明)的时候
    必须指定数据类型  变量空间的名字
    变量空间   里面只能存储一个内容(值  引用)
    变量空间内的内容可以改变
    
  • 变量创建

    float e = 3.4F;从double转化到float会有损失
    byte a = 1;
    long d = 2147483648L;-2147483648    2147483647是int类型的取值范围如果创建的常量值超过以上范围程序编译检测的时候会认为  数字太大如果我们真的需要那么大的数字  必须在后面加L告知
    char a = 'a';
    String a = "Hello";
    变量a存在栈内存中,常量1存在常量缓冲区中。
    
  • 注释

    1.单行注释://这里是注释
    2.多行注释/*这里是注释这里是注释*/
    3.文档注释/**这里是文档注释*/
    

(3)类型转化问题

  • 同种数据类型之间是可以直接进行转化的

    int a = 1;int b = a;
    float x = 3.4;float y = x;
    
  • 数据类型不同之间的转化

    基本类型----基本类型之间   可以直接转换(自动 强制)
    引用类型----引用类型之间   可以直接转换(自动 强制--上转型 下转型)
    基本类型----引用类型之间   不可以直接转换(间接--包装类/封装类)
    
  • 保证大数据类型一致的前提下

    1.都是整型或都是浮点;大空间可以直接存储小空间的数据;byte a = 1;int b = a;float x = 3.4F;double y = x;小空间想存储大空间数据,需要强制转换。int a = 1;byte b = (byte)a;double x = 3.4;float y = (float)x;
    2.整型和浮点浮点型可直接存储一个整型int a = 1;float b = a;整型想存放浮点型需要强制转换float x = 3.4F;int y = (int)x;
    3.整型和字符char x = 'a';int y = x;int x = 97;char y = (char)x;

(4)运算符号

  • 单目运算符

    ++
    --
    
  • 双目运算符

    算术运算+、-、*、/、%
    赋值运算=、+=、-=、*=、/=、%=
    关系运算>、>=、<、<=、!=、==、instance of、&、&&、|、||、!、^
    位运算&、|、^、~、>>、<<、>>>6                  -6
    原码:00000000 00000000 00000000 00000110   10000000 00000000 00000000 00000110
    反码:00000000 00000000 00000000 00000110   11111111 11111111 11111111 11111001  符号不动 其余取反
    补码:00000000 00000000 00000000 00000110  11111111 11111111 11111111 11111010  反码+1
    计算机中不管是整数还是负数 存储的形式都是以补码形式来存储
    注意 反码是一种表示形式  取反是一个计算过程(每一个位置都取反)6<<2 =2400000000 00000000 00000000 0000011000000000 00000000 00000000 00011000相当于乘以2的位移次幂6>>1==300000000 00000000 00000000 0000011000000000 00000000 00000000 00000011相当于除以2的位移次幂-6>>>111111111 11111111 11111111 11111010?11111111 11111111 11111111 1111101>>保留符号位置 1  填1>>> 不保留符号 不管是什么 都填0
    

(5)语法结构

  • 分支结构

    1.单分支结构if(boolean)...else if(boolean)...else...
    2.多分支结构switch(byte,short,int,char) 1.5enum,1.7Stringcase,default,break;
    
  • 循环结构

    for(int i = 0;i<10;i++)
    for(int i:array)
    while()
    do{}...while()
    break,continue
    

(6)数组

  • 数组的特点

    1.数组本身是一个引用数据类型
    2.数组是在堆内存中的一串连续的地址存在
    3.数组在初始化时必须指定长度
    4.堆内存的数组空间长度一旦确定  不能再次发生改变
    5.栈内存的变量中存储的是数组的地址引用
    6.数组内部存储的类型可以是基本的 也可以是引用
    
  • 数组的定义

    数据类型[] 数组名字;
    int[] a;
    String[] x;
    
  • 数组的赋值

    静态初始化:int[] a = new int[] {1,2,3};int[] a = {2,3,4};
    动态初始化:int[] b = new int[5];整型默认值:0浮点型默认值:0.0字符型默认值:'',unicode码为(’\u0000’)布尔型默认值:false引用数据默认值:null
    
  • 数组的访问遍历

    1.索引从0开始至数组长度-1int[] a = new int[10];访问a[0]-a[a.length-1]即a[0]-a[9]
    2.遍历for(int i = 0;i<a.length;i++){System.out.println(a[i]);}for(int i : a){System.our.println(i);}
    
  • 基本类型和引用类型存储空间异同

    所有的变量空间都存储在栈内存
    变量空间可以存储基本数据类型  也可以存储引用数据类型
    如果变量空间存储的是基本数据类型  存储的是值  一个变量的值改变  另一个不会跟着改变
    如果变量空间存储的是引用数据类型  存储的是引用(地址)  一个变量地址对应的值改变 另一个跟着改变
    
  • 二维数组

    int[][] a = new int[3][2];
    int[][] b = {{1,2},{1},{2,3}}
    int[][] b = new int[][]{{1,2},{1},{2,3}}
    

2.面向对象

(1)属性设计

  • 静态描述特征–特征–属性–又称成员变量

    1.基本格式如下:权限修饰符 [特征修饰符] 数据类型 属性名字 [= 值];
    private static final int age = 18;  //静态常量
    public String name;     //默认值为null
    

(2)方法设计

  • 动态动作行为–做事–方法

    1.基本格式如下:
    权限修饰符 [特征修饰符] 返回值类型 方法名字([参数列表])[抛出异常][{方法体;
    }]
    2.形参和实参形参可以理解为是方法执行时的临时变量空间  x实参可以理解为是方法调用时传递进去的参数  a方法调用时会将实参的内容传递给形参如果内容是基本类型  传递的 是值    形参改变  实参不变如果内容是引用类型  传递的 是引用  形参改变  实参跟着改变
    
  • 方法重载Overload

    1.概念:一个类中的一组方法,相同的方法名字,不同的参数列表,这样的一组方法构成了方法重载。参数列表的不同体现在哪里?参数的个数   参数的类型   参数的顺序
    2.动态参数列表,JDK1.5之后int...x,类型固定,个数可以动态,0-n均可。本质是一个数组,有length属性,有[index]动态参数列表的方法   不能  与相同意义的数组类型的方法构成方法重载  本质是一样的动态参数列表的方法 可以不传参数 相当于0个 数组的方法 必须传递参数动态参数列表在方法的参数中只能存在一份儿  且必须放置在方法参数的末尾
    

(3)构造方法和块

  • 构造方法

    1.作用用来创建当前类的对象(方法 很特殊)
    2.写法权限修饰符  与类名一致的方法名 (参数列表) [抛出异常]{一件事情  创建一个对象(当前类Person)返回对象;}
    3.用法通过new关键字调用
    4.特点1.每一个类都有构造方法,若自己在类中没有定义,系统会默认提供一个无参数的构造方法;若在类中自己定义了构造方法,则默认无参数的构造方法即被覆盖2.构造方法是否存在方法重载?----存在构造方法重载
    
  • 程序块

    1.作用跟普通方法一样 做事情的
    2.写法可以认为程序块是一个  没有修饰符 没有参数 没有返回值 没有名字的特殊方法{}
    3.用法块也需要调用才能执行 我们自己调用不到(没有名字)每一次我们调用构造方法之前   系统会帮我们自动的调用一次程序块 让他执行一遍
    4.特点没有重载概念,可以在类中定义多个程序块。块可以在里面写一些程序   我想要在创建对象之前执行
    
  • this关键字

    1.是一个关键字(指代词)  代替的是某一个对象  (当前调用属性或方法时的那个对象)
    2.this可以调用什么?  属性  方法  可以this可以调用构造方法么?  可以  在一个构造方法内可以调用另一个构造方法通过this();  省略了构造方法的名字(必须与类名一致)必须在另一个构造方法内调用  必须在程序的第一行

(4)小结

类中的四个成员1.属性 -- 静态描述特征(存值)权限修饰符 [特征修饰符] 属性类型 属性名字 [= 值];2.方法 -- 动态描述行为(做事情)权限修饰符 [特征修饰符] 返回值类型 方法名字 ([参数列表]) [抛出异常] [{方法体}]最主要的是方法设计的参数及返回值问题  传递 调用 执行 内存3.构造方法 -- 创建当前类对象(做事情 唯一的事情)权限修饰符 与类名相同的方法名 ([参数列表]) [抛出异常] {方法体}4.程序块 -- 一个特殊的方法(没名 做事情 不用我们调用 构建对象之前调用){方法体}5.this关键字的使用用来代替某一个对象可以调用一般属性或一般方法  放置在任何类成员中可以调用构造方法  只能放在另一个构造方法内 只能放在程序的第一行6.类的加载及对象的创建(内存原理 机制)

(4)类的关系

  • 泛化(继承,实现)

    继承is-a1.子类继承父类,通过一个关键字 extends2.子类的对象可以调用父类中的(public protected)属性和方法  当做自己的来用3.子类可以添加自己独有的属性和方法4.子类从父类中继承过来的方法不能满足子类需要,可以在子类中重写(覆盖)父类的方法  更多指的是内容5.每一个类都有继承类,如果不写extends关键字,默认继承Object,如果写了extends则继承后面那个父类6.Java中继承是单个存在的(单继承),每一个类只能有一个继承类(在extends关键字后面只能写一个类)可以通过传递的方式实现多继承的效果,后续还会有实现7.继承在内存中的存储方式8.this与super关键字的区别this和super都是代替对象this代替的是执行属性或方法是的当前这个对象super代替的是当前对象的父类对象this和super都可以调用一般的属性或方法,放置在类成员的任意位置方法之间是可以来回调用的(编译好用),执行时注意StackOverflowError的问题this和super都可以调用构造方法,只能放在另一个构造方法第一行  this()  super()当利用this或super调用构造方法时,他们两个不能同时出现(他们都想抢占第一行,冲突啦)
    
    • Object类

      可以理解为Object类非常重要,是任何一个引用类型的父类(直接或间接的继承Object),Object没有父类Object类中的方法hashCode()  将对象在内存中的地址经过计算得到一个int型整数public native int hashCode();equals()       用来比较两个对象的内容,Object默认效果是====可以比较基本类型(比较值),可以比较引用类型(比较地址)equals方法时Object类中继承过来的方法,默认效果比较地址如果想要改变其规则,可以进行方法重写public boolean equals(Object obj){return (this == object);}toString()     打印输出时将对象变成String字符串public String toString(){return this.getClass().getName()+"@"+Integer.toHexString(this.hashCode());}getClass()       获取对象对应类的类映射(反射)wait()     线程进入挂起等待状态notify()      线程唤醒notifyAll()     唤醒所有线程finalize()析构方法,clone()    这两个方法都是protected修饰符修饰
      
    • 重写和重载的区别

           方法重写override                    方法重载overload1.类 产生两个继承关系的类              一个类中的一组方法子类重写父类的方法2.权限  子类可以大于等父类           没有要求3.特征    final static abstract       没有要求父类方法是final  子类不能重写父类方法是static   子类不存在父类方法是abstract  子类必须重写(子类是具体必须重写,否则子类是抽象类,可以不重写)4.返回值   子类可以小于等于父类          没有要求5.名字    子类与父类一致                 一个类中的好多方法名必须一致6.参数  子类与父类一致             每一个方法的参数必须不一致(个数 类型 顺序)7.异常   运行时,编译时              没有要求如果父类方法抛出运行时异常子类可以不予理会如果父类方法抛出编译时异常子类抛出异常的个数少于等于父类子类抛出异常的类型小于等于父类8.方法体   子类的方法内容与父类不一致   每一个重载的方法,执行过程不一样
  • 包含(组合,聚合,关联)

    • 包和导包

      类的个数变多了--->需要管理类--->包package(可以理解为是一个文件夹)类的第一行会出现package关键字如果package和import同时出现先写package后写importpackage只能有一个,import可以有多个
      
    has-a   包含关系(组合,聚合,关联)从亲密程度来讲不太一样组合-->人和大脑   人和心脏的关系整体和部分的关系,不可分割,要出现都出现,要消亡都消亡聚合--->汽车和车轮子  电脑和主板整体和部分的关系   创建时有可能是分开的关联--->人有汽车 人有电脑整体和部分的关系,可以分割,后来形成在一起从Java程序来描述这样的关系,通过一个类的对象当做另一个类的属性来存储
    
  • 依赖(need-a)

    use-a(need-a)  依赖关系屠夫 杀  猪         农夫 养猪一个类屠夫可以做一件事   杀猪需要一头猪不是整体和部分的关系,某一件事情产生了关系临时组合在一起,这件事情一旦做完即解散Java程序体现的形式:一个类的方法中使用到了另一个类的对象第一个可以在方法中传递参数第二个可以在方法中自己创建
    

    设计类的关系遵循的原则:高内聚低耦合

    耦合度:紧密,继承(实现)>包含>依赖
    

3.特殊关键字

(1)修饰符

  • 描述一个类

    修饰符,特征符,class,类名{属性   权限  特征  类型  名字方法    权限  特征  返回值 名字  参数  异常  执行体构造方法 权限  名字  参数  异常  执行体程序块  执行体
    }
    
  • 修饰符

    权限修饰符public       公共的protected        受保护的默认不写        默认的private      私有的
    特征修饰符final      最终的,不可更改的static      静态的abstract     抽象的native       本地的*transient       瞬时的,短暂的--->序列化*synchronized   同步的,线程问题*volatile        不稳定的
    
    • 权限修饰符

      public       公共的 本类  同包  子类  当前项目中任意位置只要有对象都可以访问
      protected   保护的 本类  同包  子类(通过子类对象在子类范围内部访问)
      默认不写     默认的    本类  同包
      private     私有的 本类
      1.能修饰什么
      2.范围如何权限修饰符可以用来修饰,类本身,和类中的成员,除了程序块权限修饰符用来修饰类的时候只有两个可以用(public,默认不写)权限修饰符都可以用来修饰类中的其他成员
      
    • 特征修饰符

      • final

        最终的,不可更改的
        修饰变量如果在定义变量时没有赋初始值给变量一次存值的机会(因为变量在栈内存空间内,没有默认值,如果不给机会,就没法用了)一旦变量被存储了一个值,若用final修饰后,则不让再次改变--->相当于常量注意变量类型是基本类型还是引用类型如果修饰的变量是基本数据类型,则变量内的值不让更改--->常量如果修饰的变量是引用数据类型,则变量内的地址引用不让更改--->对象唯一
        修饰属性全局变量,存储在堆内存的对象空间内的一个空间属性如果没有赋值,有默认值存在的属性用final修饰后,必须给属性赋初值,否则编译报错特点与修饰变量一致注意变量类型是基本类型还是引用类型如果修饰的变量是基本数据类型,则变量内的值不让更改--->常量如果修饰的变量是引用数据类型,则变量内的地址引用不让更改--->对象唯一
        修饰方法方法是最终的方法,不可更改子类继承父类的方法,将父类的方法重写(覆盖)final修饰的方法,要求不可以被子类重写(覆盖)
        修饰类本身类是最终的,不可以更改(太监类 无后)此类不可以被其他子类继承   通常都是一些定义好的工具类Math   Scanner Integer String
        
      • static

        静态的:
        1.可以修饰:修饰属性,修饰方法,*修饰块,修饰类(内部类)
        2.特点:1.静态元素在类加载时就初始化啦,创建的非常早,此时没有创建对象2.静态元素存储在静态元素区中,每一个类有一个自己的区域,与别的类不冲突3.静态元素值加载一次(只有一次),全部类对象及类本身共享4.由于静态元素区加载的时候,有可能没有创建对象,可以通过类名字直接访问5.可以理解为静态元素不属于任何一个对象,属于类的6.内存管理,栈内存创建开始用完及回收,堆内存通过GC回收,静态元素区GC无法管理静态元素去Garbage Collection无法管理,可以粗暴的认为常驻内存7.非静态成员(堆内存对象里)中可以访问静态成员(静态区)8.静态成员中可以访问静态成员(都存在静态区)9.静态成员中不可以访问非静态成员(个数,一个出发访问一堆相同名字得东西,说不清)(静态元素属于类,非静态成员属于对象自己)10.静态元素中不可以出现this或super关键字(静态元素属于类)
        
      • native

        本地的Java源代码中看到native就已经再也看不见后续代码后续会调用其他的编程语言C++,C执行内存的操作,帮我们操作内存Object类中的一个方法   hashCode
        
      • abstract

        抽象的
        1.可以修饰什么修饰方法用abstract修饰符修饰的方法,只有方法的结构,没有方法执行体叫做抽象方法当然注意native修饰的方法虽然也没有方法体,但是不是抽象方法 ,只是执行的过程是其他语言写的,看不到修饰类用abstract修饰符修饰的类,叫做抽象类
        2.修饰后有什么特点抽象类中必须有抽象方法么?  不是必须含有抽象方法的抽象方法必须放在抽象类中么?    们目前来看必须放在抽象类中(或接口中),普通类是不允许含有抽象方法的
        3.研究一下什么叫做抽象类,抽象类有什么特点?(通常是用来描述事物的,还不是很具体)1.类里有什么 成员属性   可以含有一般的属性,也可以含有private,static,final等等;方法    可以含有一般的方法,也可以含有private,static,final等等;注意:抽象类中是允许还有抽象方法的(只有方法结构,没有方法执行体的方法)块 可以含有一般的程序块,也可以含有static程序块构造方法    可以含有构造方法,包括重载2.类如何使用,创建对象抽象类还有构造方法,但是我们不能通过调用构造方法直接创建对象抽象类只能通过子类单继承来做事为什么不让我们调用构造方法创建对象?为什么还有呢?3.类和类的关系抽象类------直接单继承------抽象类   可以抽象类------直接单继承------具体类   可以(用法通常不会出现)具体类------直接单继承------抽象类   不可以(将父类的抽象方法具体化 或 子类也变成抽象类)4.小问题抽象类中能不能没有抽象方法,全部都是具体成员 可以抽象类中能不能没有具体成员,全部都是抽象方法 可以---->抽象类抽象到极致,质的变化---->接口接口可以理解为是抽象类抽象到极致---->还是一个类的结构,不能用class修饰,改用interface修饰public interface Test {}
        5.什么是接口(通常是用来定义规则的)接口也是一个类的结构,只不过用interface修饰,替换原有的class1.有什么成员属性   不能含有一般的属性;只能含有公有的静态的常量(public static final默认不写也可以)方法   不能还有一般的方法;只能含有公有的抽象的方法(default修饰具体方法;public默认不写也可以)块    不能含有一般的程序块,也不能含有static块(块本身就是具体的,接口中不让有具体的)构造方法 不能含有构造方法2.如何使用,创建对象不能创建对象只能通过子类多实现(implements)来做事3.与别的类结构关系接口不能继承别的类   最抽象抽象类----直接多实现----接口   可以具体类----直接多实现----接口    不可以(必须将接口中的抽象方法具体化或自己变成抽象类)*接口----多继承----接口   可以
        

(2)类的加载顺序

  • 加载顺序

    存在继承关系的类,加载机制,及执行过程加载类的过程--静态元素已经加载Person person = new Person();1.加载父类2.父类会产生自己的静态空间  属性,方法,块,执行块执行静态块3.加载子类4.子类会产生自己的静态空间   属性,方法,块,执行块执行静态块
    --------------------------------------------------------------------------------------------5.开辟对象空间6.加载父类的非静态成员    属性,方法,块,构造方法7. 执行块,执行父类的构造方法8.加载子类的非静态成员    属性,方法,块,构造方法9. 执行块,执行子类的构造方法10.将对象空间的地址引用交给 变量来存储
    

(3)特殊类

  • 内部类

    成员内部类将类的定义直接放在另一个类中,与成员并列可以用任何的修饰符来修饰内部类可以直接使用外部类的成员若内部类与外部类成员重名,通过外部类.this.name如果想要使用内部类的属性和方法,必须创建对象,通过外部类对象操作Demo d = new Demo();InnerDemo id = d.new InnerDemo();注意内部类命名:外部类$内部类.class局部内部类将类的定义放在类成员中,与局部变量并列局部内部类只能用abstract和final来修饰在不同的方法中定义重名的局部内部类注意局部内部类命名:外部类$1内部类.class局部内部类可以访问外部类成员,属性内部类也能访问局部变量,要求局部变量必须为final修饰匿名内部类将类直接定义在类中,或者类成员中,成员匿名内部类,局部匿名内部类匿名内部类没有类的所有结构(名字,修饰符)只有类体通常会在抽象类或接口创建的后面使用,当然具体的类也可以有匿名子类匿名内部类没有构造方法,也不能用任何修饰符来修饰public interface Test() {public void test();}public class TestMain() {public statc void main(String[] args) {Test t = new Test(){public void test(){};}}}静态内部类只能在类中定义,作为成员静态内部类不需要外部类对象操作,可以直接创建对象静态内部类可以访问外部类的静态成员
    
  • 枚举类

    枚举类一个类中的对象,认为个数有限且固定的,可以将每一个对象一一列举出来1.试一试若没有枚举类型的时候,如何手动设计(静态常量,单例模式),Day(类,当做描述星期,7个对象)private构造方法public static final属性 = new2.JDK1.5版本之后可以直接定义enum类型我们自己定义的enum类型直接默认继承Enum(java.lang包)我们自己定义的enum类型不能再写extends,但是可以实现Enum类型有两个属性name--->枚举对象的名字,name()获取name属性ordinal--->枚举对象在类中罗列的顺序,类似index,也从0开始,ordinal()获取序号一些常用的方法valueOf()  通过给定的name获取对应的枚举对象values()  获取全部的枚举对象---->返回一个数组Day[]compareTo() 可以比较两个枚举对象   inttoString()      由于这个方法没有final修饰,可以覆盖(重写)3.switch内部判断枚举的应用Day day = Day.valueOf(key);switch(){}4.我们也可以在enum中描述自己的一些属性或方法必须在enum类中第一行,描述一下枚举的样子,最后需要分号结束可以定义自己的属性类创建的过程中,帮我们创建枚举类型的对象需要给枚举类型提供对应样子的构造方法,构造方法只能private修饰,可以重载
    
  • Scanner类

    1.所属的包java.util包,需要import导包
    2.通过一个带输入流的构造方法创建对象
    3.常用方法  nextInt(),nextFloat(),next(),nextLine()
    
  • System类

    1.所属的包java.lang包,不需要导入
    2.不需要创建对象,通过类名就可以访问
    3.有三个属性及若干的方法三个属性out in err几个方法gc() exit(0);currentTimeMillis()//返回当前时间的毫秒值
    

(4)小结

所有面向对象的编程思想如何描述类类成员四个;方法如何创建对象执行类成员类之间的关系is-a;has-a;use-a类中特征权限;特征类之间的设计问题设计模式:单例、策略、适配器类中的一些细节内部类、枚举类内存机制的问题类创建在哪儿,对象创建在哪里,继承关系,静态成员,方法执行栈内存<---Person p = new Person();--->堆内存栈内存:创建开始,用完即回收,StatckOverflowError方法区:类、常量、静态,只有一份回收不了堆内存:new创建的对象,Garbage Collection垃圾回收器Runtime类之中提供了几个管理内存的方法maxMemory      堆内存总大小totalMemory       可用的内存大小freeMemory       未用的内存大小堆内存溢出错误OutOfMemoryError:java heap spaceObject类中有一个finalize方法,如果重写也能看见对象回收GC系统提供的一个线程,回收算法
  • 内存管理

    内存管理的问题栈内存:变量空间,方法执行临时空间,从创建开始执行完毕,立即回收堆内存,我们自己new申请对象空间,垃圾回收器GC,对象空间没有任何引用指向视为垃圾方法区,常量,类模板,静态成员,有且只有一份,不回收public class test{public Person p = new Person();}Test t = new Test();Person p = t.p;p = null;t.p = bull;System.gc();
    为了能看到对象被回收的效果1.重写类中的finalize()方法,从Object继承过来的2.Runtime类,单例模式,Runtime.getRuntime();获取对象long x = maxMemory,totalMemory,freeMemoryOutOfMemoryError    堆内存溢出错误StackOverflowError   栈内存溢出错误
    

4.包装类

  • byte-Byte、short-Short、int-Integer、long-Long
    float-Float、double-Double、char-Character、boolean-Boolean
    
  • 1.八个包装类都在同一个包下,java.lang包,不要用import导包,直接使用即可。
    2.八个包装类中有六个是与数字相关,都默认继承父类Number
    3.八个包装类都实现了Serializable,Comparable
    4.八个包装类都有带自己对应类型参数的构造方法八个包装类有七个(除了Character)还有构造方法重载,带String类型new Integer(10);new Integer("10");
    5.创建对象,对象调用属性/方法new Integer("abc");  ------>NumberFormatException有六个与数字相关的类型都继承Number,xxxValue();将一个包装类型转化为对应的基本类型(拆包)toBinaryString(int i);     //转换成二进制数字toHexString(int i);       //转换成十六进制数字toOctalString(int i);        //转换成十进制数字
    6.经常在笔试中出现的问题Integer i1 = 10;Integer i2 = 10;Integer i3 = new Integer(10);Integer i4 = new Integer(10);System.out.println(i1 == i2);    //true//注:若i1和i2数字范围超过127或小于-128;则i1 == i2为falseSystem.out.println(i1 == i3); //falseSystem.out.println(i3 == i4);    //falseSystem.out.println(i1.equals(i2));   //trueSystem.out.println(i1.equals(i3));    //trueSystem.out.println(i3.equals(i4));    //true1.==与equals()的区别==可以比较基本数据类型,也可以比较引用数据类型(变量中存储的内容)如果比较基本类型,比较的是变量中存储的值如果比较引用数据类型,比较的是变量中存储的地址引用equals()是Object类中继承过来的方法,每一个引用类型都可以调用默认继承的equals()方法比较与==一致,如果想要改变比较规则,可以重写equals()方法由于Integer类就重写了equals()所以Integer比较的是数值
    2.考察Integer类加载的时候,自己有一个静态的空间空间内立即加载Integer类型的数组内存储256个Integer对象,-128~127如果我们用的对象范围在这之内Integer i1 = 10;直接去静态区中找对应的对象如果我们用的对象范围超出了这个Integer i1 = 1000;会帮我们创建一个新的Integer对象
    

5.数学相关

(1)Math

1.所属的包java.lang
2.Math构造方法是私有的,我们不能直接调用创建对象
3.由于Math中提供的属性及方法都是static,不需要创建对象
4.常用的方法abs()返回给定数字的绝对值double = ceil()向上取整double = floor()向下取整double = rint()临近的数,如果两边距离一样,则返回偶数double = round()四舍五入的整数max(a,b)    (参数int,long,float,double)min(a,b)  pow(a,b)a的b次方(参数int,long,float,double)sqrt(a)获取给定参数的平方根值random()随机产生一个 [0.0----1.0)之间的数
5.Math.random()计算小数的时候精确程度可能有些损失0-9之间的随机整数int value = (int)(Math.random()*10);5.0-10.9之间的小数(Math.random()*6)+50.0---0.99999 * 6(0.0---5.49999)+5

(2)Random

1.在java.util包中的类,需要import导入
2.没有任何继承关系,默认继承Object类
3.查找构造方法--->如何创建对象Random r = new Random();
4.类中提供的常用方法r.nextInt(); 随机产生一个int取值范围的整数,有正有负r.nextInt(int bound);   随机产生一个[0,bound)取值范围的整数注意bound必须为正数,否则会出现如下的运行时异常IllegalArgumentExceptionr.nextFloat()  随机产生一个[0.0,1.0)r.nextBoolean() 随机产生一个boolean类型的值true,false

(3)UUID

1.所属的包 java.util,需要import导入
2.没有任何继承关系,默认继承Object类
3.构造方法有,没有无参数的,通常不会创建对象UUID uuid = UUID.randomUUID();System.out.println(uuid.toString);//数据库表格主键 primary key产生一个32位的随机元素,每一个位置是一个16进制的数字

(4)BigInteger

大整数
1.所属的包java.math,需要import导入
2.继承自Number
3.如何创建对象,提供的构造方法全部都是带参数的通常利用带String参数的构造方法创建这个类的对象BigInteger bi = newBigInteger("123");
4.类中常用方法做四则运算add()  subtract()  multiplt()  divide()
5.小例子,设置一个方法,用来计算给定数字的阶乘public BigInteger factorial(int num) {BigInteger result = new BigInteger("1");for(int i = 1;i<=num;i++) {result = result.multiply(new BigInteger(i+""));}return BigInteger;}

(5)BigDecima

超过double取值范围
1.所属的包java.math,需要import导入
2.继承Number类
3.通常也是可以通过 带String参数构建对象
4.类中的常用方法做四则运算add() subtract()  multiply()  divide()两个参数 前面是保留小数点之后的位数,后面参数是设置的模式对象.setScale(2.BigDecimal.ROUND_DOWN);

(6)DecimalFormat

将小数点之前和之后的位数都能处理的类---->格式化
1.所属的包java.text
2.import导入才能使用
3.通过带String参数的构造方法创建一个格式化对象 0,#
4.调用format方法将一个小数格式化成一个字符串DecimalFormat df = new DecimalFormat("000.###");String value = df.format(123.4567);System.out.println(value); //123.457,默认为四舍五入

(7)小结

1.Math类  java.lang包所有属性和方法都是静态的不需要创建对象abs(),max(),min(),ceil(),floor(),round(),sqrt(),pow(),random()
2.Random类 java.util包需要导包,通过无参构造方法创建对象nextInt(),nextInt(int bound),nextFloat(),nextDouble(),nextBoolean()
3.UUID类 java.util包UUID uuid = UUID.randomUUID();uuid.toString();    32位,16进制的元素
4.BigInteger类,BigDecimal类,java.math包需要导包,通过带String参数的构造方法创建对象add(),substract(),multiply(),divide()Decimal对象.setScale(位数,设置格式);设置小数点之后保留的位数
5.DecimalFormat类,java.text包----->格式化导包使用,通过带String参数的构造方法创建对象,String---->一种格式DecimalFormat df = new DecimalFormat("000.###");    //# 0String value = df.format(123.4567);//给定的数字格式化成上述的效果

6.日期相关

(1)Date

1.通常使用的是java.util包
2.导包,拿来使用,构建对象
3.通常使用无参的构造方法,或者带long构造方法
4.Date类中常用的方法before();after();setTime();getTime();------>longcompareTo(); -1,1,0
5.可以处理一个Date日期的格式

(2)DateFormat

1.包java.text需要导包使用
2.此类是一个抽象类,不能创建对象,子类来使用
3.SimpleDateFormat类,是DateFormat的子类
4.调用带String参数的构造方法创建format对象DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String value = df.format(new Date());

(3)Calendar

1.所属的包java.util,需要导包
2.有构造方法,用protected修饰的,通常访问不到,通常会调用默认的getInstance();
3.常用方法after(),before();setTime(),getTime()---->DategetTimeInMillis()---->timegetTimeZone()---->TimeZoneCalendar里面包含一个date属性,可以操作date的某一个局部信息set getcalendar.set(Calendar.YEAR,2015);int year = calendar.get(Calendar.YEAR);

(4)TimeZone

1.java.util类
2.可以通过calendar对象.getTimeZone()获取或TimeZone.getDefault();
3.常用方法tz.getID();-----> Aisa/Shanghaitz.getDisplayName()----->中国标准时间

(5)小结

0.System类,java.lang包in,out对象属性,gc();exit(0);long time = System.currentTimeMillis();//获取当前系统时间--->1970-1-1 08:00:00 毫秒形式
1.Date类,java.util包(java.sql)无参数构造方法new Date(); new Date(long time);after(); before(); compareTo();setTime(); getTime();
2.SimpleDateFormat类,java.text包DateFormat类的子类带String参数的构造方法,new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String value = 对象.format(new Date());
3.Calendar类,java.util包需要通过类中的一个方法创建对象Calendar c = Calendar.newInstance();    //默认当前系统时间的一个对象after()、before()、setTime()、getTime()set(Calendar.YEAR,2015)、get(Calendar.YEAR);getTimeInMillis();getTimeZone();//获取对应的时区
4.TimeZone类,java.util包需要通过类中的一个方法创建对象TimeZone tz = TimeZone.getDefault();getID();    getDisplayName();

7.字符串

(1)String

0.常见的String笔试题== equals方法的区别==可以比较基本类型,可以比较引用类型比较基本类型比较值,比较引用类型比较地址equals只能比较引用类型(方法)默认比较地址this == obj如果相扰修改其比较规则,可以重写equals方法通常重写equals方法时会伴随着重写hashCode方法比如String类,比如Integer类*String的不可变特性   长度及内容           String与StringBuffer的区别StringBuffer与StringBuilder的区别String对象的存储"abc"---->字符串常量池new String("abc");---->堆内存"a"+"b"+"c"+"d"       //中间产生了7个对象*String中常用的方法1.存在哪儿  java.lang包没有任何继承关系,实现三个接口Serializable,CharSequence,Comparable2.实现了三个接口,Serializable,CharSequence,Comparable<String>3.如何创建对象String str = "abc"; 直接将字符串常量赋值给str(字符串常量池)String str = new String();  //String str = "";  //无参数的构造方法创建空的String对象String str = new String("abc");//String str = "abc";//有参数的构造方法创建String对象String str = new String(byte[]);  //将数组中的每一个元素转化成对应的char组合成StringString str = new String(char[]);//将数组中的每一个char元素拼接成最终的String4.String的不可变特性String类中包含一个private final char[] value;体现在两个地方,长度及内容长度---->final修饰的数组,数组长度本身不变,final修饰数组的地址也不变内容---->private修饰的属性,不能再类的外部访问在String类中包含一个数组private final char[] value;//存储String中的每一个字符final最终的不可改变的---->地址不让改变,数组的长度本身不可变private私有的当前类中---->数组的内容也不能改变    *5.常用的方法1.boolean = equals(Object obj);//继承自Object重写了,比较两个字串中的字面值是否相等2.int = hashCode();//继承自Object重写了,//将当前字符串的每一个元素拆开,//加上索引乘以31;//h0 = 0*31+char[0];h1 = h0*31+char[1];3.int = compareTo(String str);//实现自Comparable接口,实现了,按照字典索引的顺序比较4.String = toString();//继承自Object重写了,不再输出类名@hashCode,输出字符串的字面值
-----------------------------------------------------------------------------------常用方法6.char = charAt(int index);  //返回给定index对应位置的那个char值7.int = codePointAt(int index);  //返回给定index对应位置的那个char所对应的code值8.int = length();        //返回字符串的长度9.String = concat(String str);    //返回拼接后的字符串,效率比直接+连接好10.boolean = contains(CharSequence s);判断给定的字符串s是否在字符串中存在11.boolean = startsWith(String prefix);boolean = endsWith(String suffix);判断此字符串是否已xx开头/结尾12.byte[] = getBytes();------->getBytes(String charsetName);    //设置拆字符串使用的编码,避免中文乱码char[] = toCharArray();  '我' '爱' '你' '中' '国'将当前字符串转化成数组13.int index = indexOf(String/int[,int fromIndex]);找寻给定元素在字符串中第一次出现的索引位置,若字符串不存在,则返回-1int index = lastIndexOf(String/int[,int fromIndex]);找寻给定元素在字符串中最后一次出现的索引位置,若字符串不存在,则返回-114.boolean = isEmpty();判断当前字符串是否为空字符串(length是否为0)注意:与null之间的区别15.replace();    换全部匹配的字串replaceAll();   换全部匹配的字串replaceFirst(); 换第一次出现的那个字串将给定的字符串替换成为另外的字符串16.split(String regex[,int limit]);按照给定的表达式将原来的字符串拆分开17.String = substring(int beginIndex[,int endIndex]);将当前的字符串截取一部分从beginIndex开始至endIndex结束 [beginIndex,endIndex)若endIndex不写,则默认到字符串最后18.String = toUpperCase();String = toLowerCase();将全部字符串转换成大写/小写19.String = trim();去掉字符串前后的空格20.boolean = matches(String regex);regular有规律的,expression表达式正则表达式
6.常用的方法第一梯队(重写)equals()、hashCode()、compareTo()、toString()第二梯队(常用)charAt()、codePointAt()、indexOf()、lastIndexOf()substring()、split()、replace()、length()concat()、contains()、trim()getBytes()、toCharArray()、matches()第三梯队(一般)toUpperCase()、toLowerCase()startsWith()、endsWith()、isEmpty()

(2)StringBuffer和StringBuilder

1.所属的包 java.lang包
2.继承AbstractStringBuilder,间接继承Object,实现接口Serializable,CharSequence,AppendableStringBuffer/StringBuilder没有compareTo方法StringBuffer/StringBuilder含有一个String没有的方法  append();拼接
3.特性可变字符串   char[] value;
4.对象的构建//无参数构造方法,构建一个默认长度16个空间的对象  char[16]StringBuffer stringBuffer = new StringBuffer();//利用给定的参数,构建一个自定义长度空间的对象 char[20]StringBuffer stringBuffer2 = new StringBuffer(20);//利用带String参数的构造方法,默认数组长度为字符串长度+16个StringBuffer stringBuffer3 = new StringBuffer("abc");
5.StringBuilder中常用的方法最主要的方法 append() 频繁的拼接字符串的时候使用此方法,提高性能ensureCapacity(int minimumCapacity);   确保底层数组容量够用capacity();//字符串底层char[]的容量length();//字符串有效元素个数(长度)setLength();//设置字符串的有效元素个数char = charAt(int index);int = codePointAt(int index);String = substring(int start[,int end]);注意需要接受返回值,看见截取出来的新字符串效果StringBuilder = delete(int start[,int end]);StringBuilder类中独有的方法String类没有将start到end之间的字符串删掉,不用接受返回值就看到效果了StringBuilder = deleteCharAt(int index);String类中没有的方法将给定index位置的某一个字符删除掉int = indexOf(String str[,int formIndex]);int = lastIndexOf(String str[,int formIndex]);找寻给定的str在字符串中第一次出现的索引位置,带第二参数,则从某一个位置开始查询insert(int index,value);将给定的value插入在index位置之上replace(int start,int end,String str);将start和end之间的部分替换成strbuilder.replace(2,5,"6666");setCharAt(int index,char value);将index位置的字符改成给定的valuetoString()将StringBuilder对象,构建成一个string对象返回trimToSize()将数组中无用的容量去掉,变成length长度的数组,即将容量变成和length一样大

(3)正则表达式

 Regular有规律的 Expression表达式正则表达式regex一个带有一定规律的表达式匹配字符串格式的正则表达式通常的作用如下:1.字符串的格式校验       String类中提供的一个方法 boolean = str.matches("regex");2.字符串的拆分及替换  String类中提供的方法 replace,split3.字符串的查找      Pattern模式   Matcher匹配器如下的所有都用来描述字符的信息[abc]      abc其中的一个字符[^abc]        除了abc之外的一个字符[a-zA-Z]        表示必须是这两个范围内的其中一个字符[a-z&&[^def]] 表示a-z中除了def之外的其中一个字符    |       或者.代表任意一个字符\d  digit数字  [0-9]\D  非数字        [^0-9]\s   space留白  一个空格,一个回车,一个换行、、、\s   非留白 \w  word单词  [0-9a-zA-Z[_]]\W 非单词        [^0-9a-zA-Z[_]]如下的所有都用来描述字符出现的次数?   出现0或1次* 出现0或n次+ 出现1次以上{n}   出现n次{n,}    出现n次以上{n,m} 出现n-m次字符串的查找//1.利用Pattern类创建一个模式,理解为是一个正则表达式对象Pattern pattern = Pattern.compile("\\d{6}");//2.需要提供一个字符串String value = "123456sfsa666666ldfjglj888222";//3.利用pattern对象创建一个匹配器Matcher matcher = pattern.matcher(str);//4.寻找字符串中出现满足上述格式的字串while(matcher.find()) {System.out.println(matcher.group());}

(4)小结

知识总结
1.StringBuilder类不一定需要,是为了避免String频繁拼接修改字符串信息的时候才用的底层数组是可变的,提高了性能
2.常用方法与String类不同的独有方法append(),insert(),delete(),deleteCharAt(),reverse()与String类相同的方法length(),charAt(),codePointAt(),indexOf(),lastIndexOf()substring,replace()名字相同,用法不一致不是很常用的方法ensureCapacity(),capacity(),setLength(),trimToSize(),setCharAt()
3.String家族笔试中经常容易考察的知识点1.String所属的包,继承关系,实现接口java.lang,继承Object,接口Serializable,CharSequence,Comparable2.String构建方式常量,构造方法3.String对象内存结构字符串常量区,new堆内存对象== equals()区别"a"+"b"+"c"4.String不可变特性长度及内容5.String中常用方法---与StringBuilder的区别concat(),toUpperCase();6.String和StringBuilder区别 | String和StringBuffer区别String不可变字符串JDK1.0有一个接口Comparable不可变体现在长度及内容有一些方法StringBuilder没有 concat(),compareTo,toUpperCase()StringBuilder可变字符串JDK1.5有一个接口Appendable可变字符串,没有final修饰,底层可以进行数组扩容有一些方法String没有,append(),insert(),delete(),reverse()7.StringBuffer和StringBuilder的不同StringBuffer早期版本1.0StringBuilder后来的版本1.5早期版本 线程同步     安全性比较高  执行效率相对较低后期版本 线程不同步   安全性比较低  执行效率相对较高

8.集合

Collection:存储的都是value|-List:有序可重复|-Vector:ArrayList早期版本|-ArrayList:集合|-Stack:栈|-LinkedList:链表|-Queue:队列,先进先出|-Set:无序无重复|-HashSet|-TreeSet
Map:存储的是以key-value形式存在,key无序无重复,value无序可重复|-HashMap:key无序无重复,value无序可重复|-TreeMap:自然有序,按照Unicode编码自然有序

(1)ArrayList

底层就是一个数组所属的包 java.util如何创建对象无参数构造方法,带默认空间的构造方法,带collection参数的构造方法常用的方法--->小容器存 add取 get删 remove改 set个数 size清除 clearadd(E e)         add(int index,E e)addAll(Collection c)  并集  addAll(int index,Collection c)clear();  将集合内的全部元素清除boolean = contains(Object);  找寻某一个给定的元素是否在集合中拥有ensureCapacity(int mincapacity);E = get(int index);int = indexOf(Object obj);int = lastIndexOf(Object obj);boolea = isEmpty();iterator();//迭代器,1.5之后增强forremove(int index)  remove(Object obj);removeAll(); 差集retainAll();  交集E = set(int index,E value);int = size();List = sublint(2,4);Object[] Array = toArray();toArray(new Integer[list.size()]);trimToSize();//变成有效元素个数那么长
  • 泛型

    关于泛型的问题:由于ArrayList底层是一个Object[]  什么类型都可以存进去取出来的时候多态的效果,需要自己造型,显得用起来非常的麻烦JDK1.5之后---->泛型用来规定数据类型的,定义的时候用一个符号代替某种类型在使用的时候用具体的数据类型,将定义的那个符号替换掉ArrayBox<T>泛型可以用在哪里?1.泛型类类定义的时候描述某种数据类型,集合的使用就是这样2.泛型接口与泛型类的使用基本一致public interface Test<X>{public X value;}public class Son<X> implements Test<X>{}3.泛型方法方法调用是传参数,方法的泛型与类无关,带有泛型的方法可以不放在带有泛型的类中4.高级泛型,规范边界,extends,super
    

(2)LinkedList

1.java.util包
2.底层使用双向链表的数据结构形式来存储适合于插入或删除,不适合遍历轮询
3.构建对象无参数构造方法,带参数的构造方法(Collection)ArrayList<String> arrayList = new ArrayList<String>();LinkedList<String> linkedList = new LinkedList<String>(array);
4.常用的方法增删改查 add();remove();set();get();size();      offer();poll();peek();addAll();addFirst();addLast();clear();contains();element();getFirst();getLast();indexOf();lastIndexOf();.......
5.插入删除的特性是否像想象的那样对比ArrayList,LinkedList

(3)Set

  • Set:无序无重复

    1.具体的实现类HashSetTreeSet
    2.基本的使用
    3.无序    无重复无序:我们使用集合存放元素的顺序,集合内取出来的顺序不一致
    
  • HashSet

    1.java.util
    2.如何创建对象,无参数,有参数
    3.集合容器的基本使用增删改查boolean = add(value);addAll(Collection c);retainAll(Collection c);removeAll(Collection c)boolean = remove(Object);没有修改方法iterator()   获取一个迭代器对象size()
    4.无重复的原则首先通过String类型和Person类型存储大概猜测,无重复的原则,利用equals方法进行比较如果我们想要让Person对象的name一致,认为是同一个对象我们可以重写equals方法重写了equals方法,发现还没有产生无重复的效果证明可能原则不止equals一个方法这么简单还有另一个规则同时起着作用 hashCode方法,int五个Person对象只剩一个,第一次存储的,还是最后一次存储的?set集合是发现重复的元素,拒绝存入,存储的是第一个
    
  • TreeSet

    无序无重复 java.util无参数构造方法,带Collection构造方法基本常用方法add(E e),iterator(),remove(E e),没有修改,size()无重复的规则是如何实现的?treeSet集合本身有顺序,我们值得无序存入的和取出来的不一致comparaTo---->String类,按照字母的自然顺序排布(Unicode)如果想要把自己写的类型,比如Person对象存入TreeSet集合里不能随意的存储,需要让自己写的类先实现Comparable接口
    

(4)Map

  • Map

    映射   通过某一个key可以直接定位到一个value值存储的方式以  键值对 存储,key-valuekey无序无重复,value无序可重复key无序还是一样,指的是存入顺序与取得顺序不一致key无重复当然指的是,元素不能一致
    
  • HashMap

    1.包 java.util
    2.如何创建对象
    3.基本方法增删改查value = put(key,value);putAll(Map);存放一组映射关系   key-value1.key存储的顺序与取得的顺序不同2.不同的key可以存储相同的value3.key若有相同的,则将原有的value覆盖而不是拒绝存入(跟set刚好相反)value = remove(key);boolean = remove(key,value);按key删除或按映射删除put(key,value1);    put(key,value2);E = replace(key,newValue);replace(key,oldValue,newValue);按照key或映射进行修改E = get(key);按照key值查询得到value遍历map集合?获取到所有的key,遍历key,通过key获取valueSet = keySet()获取全部的keySet<> set = map.kaySet();Iterator it = set.iterator();while(){}Set<Entry> = entrySet();获取全部的entry对象Set<Map.Entry<,>> entrys = map.entrySet();Iterator<Map.Entry<,>> it = entrys.iterator();while(it.hasNext()){Map.Entry<,> entry = it.next();Integer key = entry.getKey();String value = entry.getValue();System.out.println(key+"----"+value);}size();4.除了上述几个常用的方法外,其他API中提供的方法clear();containsKey(key);containsValue(value);getOrDefault(key,defaultValue);如果key存在,就返回对应的value,若没有找到key,则返回defaultValueisEmpty();putAll(map);putIfAbsent(key,value);如果key存在,则不存入;如果key不存在,则存入映射5.map集合在什么情形下用?1.想要存储一组元素数组or集合    如果存储的元素以后长度不变用数组,如果长度以后不确定,用集合2.如果发现长度以后不确定----->集合List Set MapList家族有序的,存储有顺序用这个ArrayList(vector)        更适合额遍历轮询LinkedList      更适合插入和删除Stack           LIFOSet家族无重复,存储元素希望自动去掉重复元素用这个Hash   性能更高Tree    希望存进去的元素在自动去重复,同时还能自动排序Map家族k-v,通过唯一的k快速找寻v用这个Hash    性能更高Tree    希望存进去的的元素key自动排序6.登录小程序能体会每一个不同集合的特点7.HashMap底层的数据结构存储散列表的形式    数组+链表Person对象存入HashMap中?可以hashCode方法---->不同的对象,可以产生相同的hashCode码的不同的hashCode码---->不同的对象
    
  • TreeMap

    TreeMap       自然有序,按照Unicode编码自然有序1.java.util包2.构造方法无参数,带map参数3.常用方法put,get,remove,replace,size4.底层数据结构的存储红黑二叉树
    

(5)小结

  • ArrayList

    1.底层是利用(动态)数组形式实现    1.52.ArrayList特点适合遍历轮询,不适合插入删除3.如何创建一个ArrayList对象无参数构造方法,带默认容量构造方法4.ArrayList中常用的方法增删改查 add(E e),remove(index),set(index,value),get(index),size()类中其他常用的方法addAll并集  removeAll()差集   retainAll()交集indexOf()  lastIndexOf()  contains()  List=subList()isEmpty()  clear()  ensureCapacity()  iterator();迭代器toArray(T[] x);  trimToSize();  5.泛型用来规定数据类型注意:泛型,造型在类或接口描述的时候,可以通过某种符号来表示一个未知的类型在类型使用的时候,需要一个具体类型来代替注意:泛型需要使用引用数据类型类代替1.泛型类  2.泛型接口  3.泛型方法  4.方法参数泛型限制
    
  • Vector

    Vector类1.java.lang包2.是ArrayList集合的早期版本 (StringBuffer早期和StringBuilder后来)Vector底层也是利用(动态)数组的形式存储Vector是线程同步的(synchronized)  安全性高  效率低3.扩容方式与ArrayList不同默认是扩容2倍,可以通过构造方法创建对象时修改这一机制4.构造方法5.常用方法
    
  • Stack

    栈
    1.java.util包
    2.构造方法只有一个无参数
    3.除了继承自Vactor类的方法外,还有几个特殊的方法push(E e)将某一个元素压入栈顶(add())E = pop()将某一个元素从栈顶去除并删掉(E = remove())E = peek()查看栈顶的一个元素,不删除(E = get())boolean = empty()判断栈内元素是否为空(isEmpty())int search()查找给定的元素在栈中的位置(indexOf())
    4.中国象棋  悔棋栈中存储每一次操作的步骤撤销功能
    
  • Queue

    1.java.util     通常子类LinkedList,ArrayDeque
    2.通常无参数构造方法创建
    3.一般方法add()element()----->get()remove()boolean = offer(E e);//相当于add(),不会抛异常E = peek();//相当于element()方法E = poll();//剪短----->相当于remove()
    4.双十一零点秒杀所有进入秒杀系统的人进入队列
    
  • LinkedList

    1.java.util包
    2.底层使用双向链表的数据结构形式来存储适合于插入或删除,不适合遍历轮询
    3.构建对象无参数构造方法,带参数的构造方法(Collection)ArrayList<String> arrayList = new ArrayList<String>();LinkedList<String> linkedList = new LinkedList<String>(array);
    4.常用的方法增删改查 add();remove();set();get();size();      offer();poll();peek();addAll();addFirst();addLast();clear();contains();element();getFirst();getLast();indexOf();lastIndexOf();.......
    5.插入删除的特性是否像想象的那样对比ArrayList,LinkedList
    
  • Set

    Set特点 无序无重复无序:添加的顺序,获取的顺序不一致(不是集合本身是否有序,Tree自然有序)无重复:添加的元素不能一致(如果出现重复元素,只存第一个,不再存入)HashSet(HashMap--->数据存储结构 散列表)TreeSet(TreeMap)--->数据存储结构 二叉树)set集合家族的基本使用增删改查add(E e)  remove(E e)  没有修改  iterator迭代器(增强for) size();hasNext();E = next();set集合的无重复特性HashSet  无重复原则有两个方法同时起作用equals() hashCode()默认比较的是两个对象的地址,若第二个对象地址与之前的一致,不再存入如果想要改变其比较的规则,可以重写上述两个方法TreeSet  无重复原则有一个方法起作用compareTo上述这个方法不是每一个对象都有的若想要将某一个对象存入TreeSet集合中,需要让对象所属的类实现接口Comparable接口实现接口后将compareTo方法重写,返回值int,负数靠前排布,正数排列靠后
    
  • Map

    Map以key-value形式存储HashMap1.java.util包2.构造方法创建对象,无参数,带默认容量的,带Map参数的构造方法3.特点(数组+链表)底层散列表形式存储,key无序无重复,value无序可重复找寻某一个唯一元素的时候建议使用map,更适合于查找唯一元素4.常用方法增删改查put(key,value);remove(key);replace(key);---->put()map集合第二次存储相同的key,则会覆盖之前的valueget(key);keySet();获取全部的key,entrySet();获取全部的entry(Node);对象,Map$Entrysize();-----------------------clear,containsKey,containsValue,isEmpty,putAllE value = getOfDefault(key,default);若key存在就返回value,若不存在就返回defaultputIfAbsent(key,value);key若不存在就存入,若存在就放弃
    ======================================================================================
    TreeMap     自然有序,按照Unicode编码自然有序1.java.util包2.构造方法无参数,带map参数3.常用方法put,get,remove,replace,size4.底层数据结构的存储红黑二叉树
    

9.错误与异常

Throwable|-Error|-StatckOverflowError:栈内存溢出异常|-OutOfMemoryError:堆内存异常|-Exception|-RuntimeException:运行时异常

(1)错误

通常是一些物理性的,JVM虚拟机本身出现的问题,程序指令是处理不了的

(2)异常

通常是一种认为规定的不正常现象,通常是给定的程序指令产生了一些不符合规范的事情
  • 异常的分支体系

    • 运行时异常(非检查异常)

      Error和RuntimeException都算作运行时异常javac编译的时候,不会提示和发现在程序编写时不要求必须做处理,如果我们愿意可以添加处理手段(try throws)要求大家出现这样的异常的时候,知道怎么产生及如何修改1.InputMismatchException        输入类型不匹配int value = input.nextInt();//abc2.NumberFormateException        数字格式化异常Integer.parseInt("sfa");3.ArrayIndexOfBoundsException    数组索引越界int array[] = {1,2,3};int i = array[array.length];4.NegativeArraySizeException        数组长度负数int[] array = new int[-2];    5.NullPointerException      空指针异常;空对象调用方法int[][] array = new int[3][];array[0][0] = 10;Person p = null;p.getName();6.ArithmeticExcetipn     算数异常        除以010/0         整数不允许除以0;Infinity小数除以0会产生无穷7.ClassCastException      对象铸型异常  对象无继承关系情况转型Person p = new Teacher();Student t = (Student)p;8.StringOutOfIndexException      字符串索引越界String str = "sdfa";char c = str.charAt(str.length);9.IndexOutOfBoundsException  集合越界List家族ArrayList list = new ArrayList();list.add();list.add();list.get(list.size());10.IllegalArgumentException      非法参数异常ArrayList list = new ArrayList(-1);
      
    • 编译时异常(检查异常)

      除了Error和RuntimeException以外其他的异常javac编译的时候,强制要求我们必须为这样的异常做处理(try或throws)因为这样的异常在程序运行过程中极有可能产生问题异常产生后后续的所有执行就停止了1.InterruptExceptiontry{Thread.sleep(5000);}catch(Exception e) {}后续还会有更多的编译时异常
      
  • 异常的处理手段

       添加处理异常的手段try{}catch{}[finally{}]1.try不能单独的出现2.后面必须添加catch或finally3.catch有一组括号(NullPointException)目的是为了捕获某一种异常4.catch可以有很多个存在捕获的异常之间没有任何的继承关系捕获的异常需要从小到大进行捕捉5.finally不是必须存在的若存在finally结构,则必须执行引申一个小问题:final,finally,finalize区别final  特征修饰符  修饰变量,属性,方法,类修饰变量:基本类型,值不能改变;引用类型,地址不能改变,如果没有初值,给一次赋值的机会。修饰属性:特点与修饰变量类似(要求必须给属性赋初始值,否则编译报错)修饰方法:不能被子类重写修饰类:不能被其他的子类继承finally 处理异常手段的一部分try{}catch{}后面的一部分这个部分可有可无,如果有只能含有一份,且必须执行finalize  是Object类中的一个protected方法对象没有任何引用指向的时候---会被GC回收当对象回收得时候,默认调用finalize()方法若想看到对象回收的效果,可以重写 public void finalize(){}6.处理异常放在方法内部,可能还会有小问题如果在方法内部含有返回值不管返回值return在哪里,finally一定会执行完毕返回值的具体结果,看情况
    
  • throws抛出异常

    throws抛出异常1.异常只能在方法上产生的,属性是不能处理异常的2.方法,构造3.方法可以抛出不止一个异常,通过逗号","隔开4.抛出的异常与多个catch类似,要么没关系,要么先抛出小异常
    

(3)小结

     ThrowableError          Exception   错误          异常通常是一些物理性错误    认为规定的不正常现象StackOverflowError            运行时RuntimeExceptionOutOfMemoryError         编译时Error和RuntimeException这一类的异常,运行时,javac变异的时候不检测不需要主动添加处理异常的手段,当然我们愿意的话,也可以添加除了上述以外的其他的异常都需要做检测,要求我们必须添加处理异常的手段,编译不过去处理异常的手段try{}catch{}finally{}1.try不能单独出现,后面必须跟着其他的一个结构,catch或finally都可以2.catch可以出现很多个,要么多个catch捕获的异常没有继承关系,要么先捕获小,再捕获大3.finally可有可无,若添加了这个结构,则必须执行,即便是放在方法中,之前有return,也执行4.注意方法内部返回值问题5.finally可能会出现一个笔试题,final,finally,finalize区别throws1.之能在方法和构造方法结构上存在(抛出异常)2.谁调用此方法,谁处理异常3.抛出的异常也可以有多个,用,隔开,小到大自定义1.写一个类,继承Exception,RuntimeException2.类中可以写带String参数的构造方法,可以做细致的说明3.通过throw关键字,new一个异常的对象

10.输入输出流

         InputStream     OutputStreamReader          Writer文件流低级字节型  FileInputStream FileOutputStream字符型 FileReader  FileWriter缓冲字节型 BufferedInputStream BufferedOutputStream字符型 BufferedReader      BufferedWriter数组流byte数组     ByteArrayInputStream    ByteArrayOutputStreamchar数组     CharArrayReader     CharArrayWriter数据流DataInputStream       DataOutputStream字符串流StringInputStream       StringOutputStream对象流ObjectInputStream      ObjectOutputStream

(1)File

1.什么叫文件一种电脑的存储形式文件有不同的格式     .txt  .doc  .ppt  .mp4  .jpg  .rar ...文件夹?File---->与电脑上的文件或文件夹产生一一对应的映射关系
File是一个类1.java.io包中2.文件或目录路径名的抽象表示形式3.File与真实硬盘中的文件或文件夹   不是一个东西File是在内存中的一个对象<----映射---->硬盘上的文件或文件夹4.File类中常用的方法boolean = canExecute();  文件是否可执行boolean = canRead(); 文件是否可读boolean = canWrite(); 文件是否可写boolean = isHiddden();    文件是否隐藏boolean = isFile();        文件是否是文件boolean = isDirectory(); 文件是否是文件夹long = length();        文件的字节长度long = lastModified();   文件的最后修改时间String = getAbsolutePath();    得到文件的绝对路径绝对路径<---->相对路径绝对路径可以通过完整的字符串,定位盘符,文件夹,文件相对路径没有盘符的写法,当前工程(项目所在的位置找寻)String = getName();     得到文件的名字boolean = createNewFile();       创建一个新文件boolean = mkdir();       创建一个新文件夹boolean = mkdirs();     创建新的文件夹,外层没有,可以自动创建String = getParent();  获取当前file的父亲的file名字Fine = getParentFile();   获取当前file的父亲的file对象String[] = list();        获取当前file的所有儿子名字File[] = listFiles();        获取当前file的所有儿子对象boolean = delete();      删除文件或空的文件夹,不能删除带元素的文件夹File file = new File(String path);file对象,不是真正的文件,是堆内存中,创建出来的一个对象空间路径是看创建的对象,是否能与硬盘中的一个真实文件产生对应的映射关系通过文件流去读文件的内容,硬盘上的文件名字是不区分大小写,内存中的File对象,变量名区分大小写文件本身的一些属性2.什么叫文件流?做什么?读取文件中的内容           向文件中写内容文件输入流            文件输出流字节型文件输入流           字节型文件输出流字符型文件输入流            字符型文件输出流

(2)字节型流

  • 字节型文件输入流:FileInputStream

    1.包  java.io
    2.了解一下继承关系,InputStream类,字节型输入流的父类
    3.创建对象调用一个带File类型的构造方法new FileInputStream(File);调用一个带String类型的构造方法new FileInputStream(String);
    4.常用方法int code = read();        每次从流管道中读取一个字节,返回字节的code码,若没有读到,返回-1int count = read(byte[]);   每次从流管道中读取若干个字节,存入数组内,返回有效元素个数int count = available(); 返回流管道中还有多少个缓存的字节数long = skip(long n);       跳过n个字节,再读取,返回n多线程---->利用几个线程同时读取文件10000字节,5个小人同时读取1-2000,2001-4000,4001-6000,6001-8000,8001-10000D当做服务器,E当做客户端close();           将流通道关闭---必须要做,最好放在finally里,注意代码的健壮性,判断严谨性
    
  • 字节型文件输出流:FileOutputStream

    FileOutputStream
    1.java.io
    2.继承OutputStream,所有字节型输入流的父类
    3.创建对象
    调用一个带File参数(默认覆盖写入),还有File boolean重载(boolean参数设置是否追加写入)
    new FileOutputStream(File);/new FileOutputStream(File,true);
    调用一个带String参数(默认覆盖写入),还有String boolean重载(boolean参数设置是否追加写入)
    new FileOutputStream(String);/new FileOutputStream(String,true);
    4.常用方法
    write(int code); 将给定的code对应的字符写入文件
    write(byte[]); 将数组中的全部字节写入文件,String.getByte();
    flush(); 将管道内的字节推入(刷新)文件
    close(); 注意在finally中关闭流

(3)字符型流

只能操作纯文本文件(文件右键打开方式,记事本打开能看懂)

  • FileReader

    1.java.io包
    2.继承 InputStreamReader  Reader
    3.构造方法
    4.常用read();read(char[]);
    
  • FileWriter

    1.java.io包
    2.继承OutputStreamWriter  Writer
    3.构造方法带file参数,带file,boolean带String参数,带String,boolean
    4.常用方法write(int);write(char[]);writer(String);flush();close();
    

(4)缓冲流

在流管道内增加缓存的数据
让我们使用流读取的文字更加的流畅
高级流-->创建通过低级流
  • BufferedInputStream/BufferOutputStream

    1.构建方式,使用低级流构建 BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
    2.基本使用与低级流的方法完全一致read();skip();available();close();
    3.构建方式,使用低级流构建   BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));//注意,缓冲流构建的时候没有boolean类型的参数
    4.基本使用与低级流的方法完全一致write();flush();close();
    
  • BufferedReader/BufferWriter

    BufferedReaderString value = readLine();
    BufferedWriterwrite(String);newLine();
    

(5)其他流

         InputStream     OutputStreamReader          Writer文件流低级字节型  FileInputStream FileOutputStream字符型 FileReader  FileWriter缓冲字节型 BufferedInputStream BufferedOutputStream字符型 BufferedReader      BufferedWriter数组流byte数组     ByteArrayInputStream    ByteArrayOutputStreamchar数组     CharArrayReader     CharArrayWriter数据流DataInputStream       DataOutputStream字符串流StringInputStream       StringOutputStream对象流ObjectInputStream      ObjectOutputStream
  • 对象的序列化和反序列化

    1.为什么要有文件?文件永久性的保存信息  将很多的数据直接存入文件---数据持久化
    2.如果按照以行为单位写信息好处在于每一行记录的信息都是相关的信息我们可以读取出来,直接看懂文件不好在于第一不安全,直接看懂不好在于第二只能记录String信息,不能记录一些动作(方法)
    3.读取出来的信息 String--->Person
    4.如果能将对象拆分成字节码,直接写入文件将对象直接存入文件中----->对象流对象的序列化/反序列化对象的序列化指的是将一个完整的对象,拆分成字节碎片,记录在文件中对象的反序列化指的是将文件中记录的对象碎片,反过来组合成一个完整的对象如果想要将对象序列化到文件中需要让对象实现Serializable接口是一个示意型接口同时为了让对象可以反序列化需要让对象中多存在一个属性 private long serialVersionUID = 任意值;如果想要将对象反序列化需要给对象提供一个序列化的版本号 1.7---->String  1.8---->String
    

(6)小结

  • 字符集

    字符集字符  文字和符号总称(Character)不同国家的数字和符号是一样的,字母不同国家的文字,中文, 日文,韩文计算机最早产生是按照英语单词,单个字符设计的字母,数字,符号---->1字节,8bit,256如果计算机想要处理除了上述字母符号以外的其他字符---比如中文2字节需要将中文进行字符编码---->拆分和组合拆分和组合的规则---所谓的字符编码常见的字符编码ASCII American Standard Code for Information InterchangeISO-8859-1GB2312  GB18030 GBK BIG5UnicodeUTF-8    UTF-16平台(操作系统)默认字符集GBK  Linux(MacOS)默认字符集UTF-8编程序使用的开发环境(IDE)   Idea-->UTF-8 Eclipse-->GBKHTML--->浏览器解析文字使用的字符集注意在用技术本存储文字,流操作纯文本形式的时候字符的形式采用UTF-8String s = "你我他";byte[] = s.getBytes("UTF-8");new String(byte[],"UTF-8");
    

11.线程

程序可以理解为是一组静态的代码
进程正在进行的程序,静态的代码,运行起来
线程正在执行程序中的小单元
1.主线程,系统线程
2.用户线程,main
3.守护线程(精灵线程)      GC线程-----操作系统级别  CPU
如何在Java中创建线程,让线程执行,多线程
掌握每一个线程的几种不同状态,及状态之间如何切换
new         start()     CPU分配run()  wait()       exception  over
创建线程-----就绪状态-----执行状态-----等待/挂起-----异常/消亡notify/notifyAll

(1)线程基础

  • 实现线程的过程

    方式一:1.自己描述一个类2.继承父类Thread3.重写run方法4.new一个线程对象,调用start()方法,让线程进入就绪状态
    方式二:1.自己描述一个类2.实现一个父接口Runnable3.重写run方法4.new一个线程对象,需要创建Thread将自己的对象包起来,然后调用start()
    

(2)锁

  • synchronized

    特征修饰符synchronized   同步  一个时间点只有一个线程访问线程安全锁两种形式写法1.将synchronized关键字,放在方法的结构上public synchronized void get(){}锁定的是调用方法时的那个对象2.将synchronized关键字,放在方法(构造方法,块)的内部(性能比第一种好)public void get(){好多代码;synchronized(对象){好多代码;}好多代码;好多代码;}3.我们觉得return不是很好应该让线程的不同状态来回切换执行  等待   执行  等待wait() Object类中的方法对象.wait();对象.wait();不是当前的这个对象wait访问当前这个对象的线程waitnotify() notifyAll()    Object类中的方法sleep();run();start();notify();notifyAll();p.setPriority(10);     p.getPriority();产生一个类似假死状态所有的线程都进入等待状态,没有线程做事4.通过上述的生产消费者模型做一个非常完整而且安全的模型1.利用线程安全锁,特征修饰符synchronized两种不同的写法不管怎么写,锁定的永远是对象2.利用方法控制线程状态的来回切换wait();notify(); notifyAll();3.Thread类中的方法sleep方法,静态方法(参数long  毫秒值)setPriority(10);   getPriority(10);设置/获取线程的优先级 1-10数字越高优先级越高,更加容易获取CPU分配的资源碎片4.笔试题程序  进程  线程  概念的区别线程的创建方式线程的几种状态,如何切换sleep()方法  wait()方法的区别1.类  Thread类     Object类2.调用 静态 类名       对象3.理解  那个位置调用  对象调用方法那个线程等待    访问对象的其他线程等待4.锁  不会释放锁   等待后会释放锁5.join方法,Thread类中的方法让多个线程同步执行,变成单个线程6.死锁
    

(3)小结

1.生产消费者模型可能产生多线程并发带来的安全隐患----抢夺资源
2.如何解决线程安全的问题synchronized   特征修饰符,同步的线程锁,锁定的是对象1.放置在方法的结构上public synchronized void test(){好多代码;好多代码;好多代码;}对象.test();  对象被某一个访问他的线程锁定2.放置在方法(构造,块)的内部(看起来是包含着一堆代码)public void test(){好多代码;synchronized(对象){执行代码;}好多代码;}
3.线程相关的一些方法sleep(); run();  start();    setPriority();wait();   notify();   notifyAll();注意wait方法,notify方法,使用对象.wait();对象调用wait方法,不是对象等待访问此对象的线程进入等待状态
4.笔试中经常考察的关于线程的问题程序,进程,线程概念如何实现线程线程的几种状态如何切换几种状态wait();   sleep();方法的区别

12.反射

(1)概述

反射  reflect面向对象的编程思想类        从很多对象中抽取出来的公有的特征行为,抽象描述,用来描述一组对象对象        现实生活中,先存在了好多对象,很多相同特征,相同行为类是用来描述一组对象反射机制认为是用来描述一组类可以与之前学习File对比着学习Class        用来描述类本身Package      用来描述类所属的包Field      用来描述类中的属性Method     用来描述类中的方法Constructor    用来描述类中的构造方法Annotation   用来描述类中的注解@Override,注解可以放在(类上面,属性上面,方法上面,构造方法上,参数前)

(2)获取Class

如下三种方式Class clazz = Class.forName("包名.类名");Class clazz = 类名.class;Class clazz = 对象引用.getClass(); //Object类中的方法

(3)Class中的常用方法

1.int modifiers = getModifiers();        获取类的修饰符//每一个修饰符,用一个整数来进行表示 0 2 4 8 16 32 64 128 256 512//0默认不写,1public,2private,4protected,8static,16final,//32synchronized,64volatile,128transient,256native,512interface,1024abstract
2.String name = getName();      获取类全名,包名加类名
3.String simpleName = getSimpleName();  获取类名,简单名
4.Package p = getPackage();     获取包对象String packageName = p.getName();  获取包名
5.Class sclazz = getSuperClass();   获取超类(父类)
6.Class[] classes = getInterfaces();    获取类实现的所有的接口
---------------------------------------------------------------------------------------------------
7.Object obj = getConstructor().newInstance();      默认利用无参构造方法创建对象getConstructor(int.class).newInstance(6666);  利用带参数的构造方法创建对象
8.Field f = getField("属性名");        根据对象属性名获取对象的属性对象Field[] fields = getFields();       得到所有的属性对象如上的两个方法只能获取公有的属性,但是包含继承过来的父类属性
9.getDeclaredField("属性");getDeclaredField();如上的两个方法能获取公有和私有的属性,但是只能获取本类中的属性
10.Class[] = getClasses()       获取所有内部类
  • 操作类中的方法和构造方法

    Class类中的方法
    操作类中的方法Method = getMethod("方法名"[,参数列表.class]);      获取一个方法(公有的,父类+自己类)Method[] = getMethods();               获取全部的方法(公有的,父类+自己类)          Method = getDeclaredMethod("方法名"[,参数列表.class]); 获取一个方法(公有的,私有的,自己类)Method[] = getDeclaredMethods();           获取全部的方法(公有的,私有的,自己类)
    操作类中的构造方法Constructor = getConstructor([参数列表.class]);        获取一个构造方法(公有的,父类+自己类)Constructor[] = getConstructors();           获取全部的构造方法(公有的,父类+自己类)Constructor = getDeclaredConstructor([参数列表.class]); 获取一个构造方法(公有的,私有的,自己类)Constructor[] = getDeclaredConstructors();       获取全部的构造方法(公有的,私有的,自己类);
    

(4)Field类中常用的方法

1.int = getModifiers();  得到属性的的修饰符
2.Class = getType();        得到属性的类型
3.String = getType().getName(); 得到属性的类型的名字
4.String = getName();       得到属性的名字
5.操作属性,向里面存值set(对象,值);
6.操作属性,从里面取值值 = get(对象);
7.field.setAccessible(true);    设置私有属性可修改对象 = new();    创建对象空间,当前对象空间里有自己的一套元素(属性,方法)对象.属性 = 值;属性 = 类.getField("属性名");对象.属性 = 值;属性.set(哪个对象,值);值 = 对象.属性值 = 属性.get(那个对象);String str = new String("abc");Class clazz = String.class; 得到String类Field field = clazz.getDeclaredField("value");得到String类中私有属性valuefield.setAccessible(true);    设置私有属性可修改byte[] temp = (byte[])field.get(str);得到私有属性对象,并转型temp[0] = (byte)'A';       重新赋值temp[1] = (byte)'B';temp[2] = (byte)'C';System.out.println(str);    打印新的值

(5)Method类中常用方法

int = getModifiers();        获取方法的修饰符(权限+特征)
Class = getReturnType();        获取返回值数据类型
String = getName();         获取方法的名字
Class[] = getParameterTypes();  获取方法参数列表的类型
Class[] = getExceptionTypes();      获取方法抛出异常的类型
如何操作方法,调用方法,让他执行一次Object = (造型)invoke(对象);        利用对象执行无参的方法,返回方法的返回值Object = (造型)invoke(对象,参数列表);    利用对象执行有参的方法,返回方法的返回值
若方法是私有的方法,不允许操作setAccessable(true);          设置方法使用权,准入

(6)Constructor类中的常用方法

int = getModifiers();        获取方法的修饰符(权限)
String = getName();         获取方法的名字
Class[] = getParameterTypes();  获取方法的参数列表的类型
Class[] = getExceptions();      获取方法抛出异常的类型
如何操作构造方法,执行一次,创建对象Object = newInstance([参数列表]);   创建对象
若构造方法是私有的,不允许操作setAccessable(true);          设置方法使用权,准入

13.注解

(1)概述

1.注解的写法@xxx[(一些信息)]
2.注解放置在哪里类的上面、属性上面、方法上面、构造方法上面、参数前面
3.注解的作用1.用来充当注释的作用(仅仅是一个文字的说明)  @Deprecated2.用来做代码的检测(验证)           @Override3.可以携带一些信息(内容)         文件.properties  .xml  注解
4.Java中有一些人家写好的注解供我们使用@Deprecated       用来说明方法是废弃的@Override     用来做代码检测,检测此方法是否是一个重写@SuppressWarnings(信息)    String[]    {"",""} 如果数组内的元素只有一个元素,可以省略大括号unused     变量定义后未被使用serial     类实现了序列化接口,不添加序列化UID号rawtypes     集合没有定义泛型deprecation 方法已经废弃过时unchecked   出现了泛型的问题,可以不检测all         包含了以上所有(不推荐)
5.注解中可以携带信息,可以不携带信息不能随便写,信息的类型只能是如下的类型1.基本数据类型2.String类型3.枚举类型enum4.注解类型@5.数组类型[]  数组的内部需要是如上的四种类型

(2)定义注解

如何自己去描述一个注解类型1.通过@interface关键字定义一个新的注解类型2.发现写法与接口非常相似(可以利用接口的特点来记忆注解)公有的静态的常量属性  public static final的属性,比较少见可以描述公有的抽象的方法  方法要求返回值必须有,返回值是如上的那些3.我们自己定义的注解如果想要拿来使用光定义还不够,还需要做很多细致的说明(需要利用Java提供好的注解来说明)元注解(也是注解,不是拿来使用的,是用来说明注解的)@Target       用来描述当前的这个注解可以放置在哪里写的@Retention  描述当前的这个注解存在什么作用域中的源代码文件---->编译---->字节码文件---->加载---->内存执行SOURCE              CLASS       RUNTIME@Inherited   描述当前这个注解是否能被子类对象继承@Document 描述当前这个注解是否能被文档所记录4.自己使用自己描述的注解问题1.在注解里面描述了一个方法,方法没有参数,方法是有返回值String[]使用注解的时候,让我们传递参数理解为,注解的方法做事,将我们传递给他的参数,搬运走了,给了别人问题2.使用别人写好的注解不用写方法名,我们自定义的方法需要写名字如果我们自己定义的注解,只有一个方法,方法的名字叫value在使用的时候就可以省略方法名如果传递的信息是一个数组,数组内只有一个元素,可以省略{}如果方法是两个以上,注解使用时,每一个方法必须写名字

(3)反射解析注解

 1.获取Class2.获取类中的成员,类,属性,方法,构造方法3.Annotation a = 成员.getAnnotation(注解类型.class);4.注解对象,执行方法获取返回结果Class clazz = Person.class;Field field = clazz.getDeclaredField("name");Annotation a = field.getAnnotation(MyAnnotation.class);Class aclazz = a.getClass();Method amethod = aclazz.getMethod("value");String[] values = amethod.invoke(a);System.out.println(values[0]);for(String value : values) {System.out.println(value);}

(4)解析Properties文件

Properties类的使用java.util包继承HashTable使用方式像是map集合   value = getProperty(key)方法读取的信息是文件文件的后缀名.properties文件里面key = value
2.使用方法Properties pro = new Properties();pro.load(new FileReader(new File("pro.properties")));System.out.println(pro.get("key1"));@SuppressWarnings("unchecked")Enumeration<String> en = (Enumeration<String>) properties.perpertyNames();while(en.haMoreElements()) {String key = en.nextElement();String value = (String) properties.get(key);System.out.println(key+"--"+value);}

(5)小结

1.注解写法@XXXX(信息)
2.注解放置在哪里写类 方法  属性  构造  变量  参数(前面)
3.Java中定义好的注解@Deprecated        废弃的@Override        检测方法是否重写@SuppressWarning        去掉程序中的警告(尽量不要用,尽量通过编写代码去掉警告)unused   serial   rawtypes   deprecation   unchecked   all
4.如何自己去定义注解描述一个自己的类 @interface类的上面通过元注解来描述@Target       作用域@Retention   生命周期@Inherited  是否可被继承@Document 描述当前这个注解是否能被文档所记录想要携带一些信息   自定义注解类型,添加方法方法要求必须有返回值,返回值类型,基本,String,枚举,注解,数组方法的作用将我们传递的信息,搬走了,交给别人
5.注解的作用充当注释 仅仅是一个文字说明代码检测   @Override*携带信息
6.如何访问到注解对象@XXX如何获取里面的信息(需要反射机制)
7.注解在开发中应用的场景

二、MySql

1、DDL数据定义语言

Data Definition Language
用来定义数据库中的对象
create创建,drop删除,alter修改

(1)创建数据库

Java英文字母区分大小写;
MySQL英文字母,不区分大小写(关键字,表格名字,列名字)

create database 数据库名;
create database 数据库名 [default character set = 'utf8'];
  • 查询数据库信息

    --可以通过如下语句来进行查询
    --select 列 from 表 where 数据库 = 名字;
    --查询数据库默认字符集:
    select schema_name,default_character_set_name from information_schema.schemata  where schema_name ='自己的数据库名';
    

(2)创建表

  • 数据库中的数据类型

    存储数据的方式来分类分为三类数值型整数:tinyint、smallint、mediumint、*int 4、bigint小数:*float 4、*double 8、decimal、numeric字符串char(4) 字符串(固定长度,长度不够补),a 4字节,ab 4字节varchar(4) 可变字符串,a 1字节,ab 2字节text正常字符大文本数据库里面所有的字符串类型,使用'a','abc'binary二进制varbinary可变二进制blob二进制大文本日期/时间*date日期,time时间,*datetime日期&时间,timestamp时间戳
    
  • 创建一个表格

create table 表格名字('列名' 类型(长度),'列名' 类型(长度),'列名' 类型(长度),'列名' 类型(长度)
) [character set utf8] [collate utf8_general_ci]
--设置字符集和排序规则
--排序规则:utf8_general_ci;默认 性能比较高,可能不太精确,俄罗斯
--排序规则:utf8_unicode_ci;性能比较低,扩展型好
  • 查看表的信息

    show table status from 数据库名 like '表名';
    

(3)修改表

  • 修改表名字

    alter table 原表名 rename [to] 新表名;
    
  • 修改原有的列

    alter table 原表名 change 原列名 新列名 新类型 新长度;
    
  • 新增一个列

    alter table 原表名 add [column] 新列名 新类型 新长度;
    
  • 删除一个原有的列

    alter table 原表名 drop 原列名;
    

(4)删除

drop table 表格名字;
drop database 数据库名字;

2、DML数据操作语言

*DML数据操作语言操作的是表格中的数据信息写入信息(数据库中的信息发生了真实的改变)新增insert 删除delete 修改update读取信息(数据库中的信息没有发生改变,读取信息展示出来) DQL查询select

(1)新增记录

insert into 表名(列名,列名,列名) values(,,);

(2)查询记录

select 列名,列名,列名 from 表名;
select * from 表名;
select * from 表名 [where ...];

(3)删除记录

delete from 表名 [where ...]

(4)修改记录

update 表名 set='值'[,='值'] [where ...];

3、关键字

(1)where

条件筛选

1.除了insert以外的其他三个语句都可以做筛选where是一个关键字 拼接在除了insert语句以外的其他语句基本结构之后delete from 表 where.....;update 表 set 列=值 where...;select 列 from 表 where...;
2.筛选用来筛出符合条件的记录行数并不是控制显示的列
3.按照某一个列或者是某一些条件进行筛选列,满足一定条件
  • where后面可以连接什么

    1.比较运算符 > >= < <= != =
    2.算术运算符 + - * /
    3.逻辑运算符 and or not如果and和or同时出现,and优先级别更高
    4.[not] between...and...包含前后两端的值
    5.[not] in (v1,v2,v3);如下的条件满足一个就可以
    6.[not] like 模糊查询查询像什么一样,模糊查询% 用来代替0-n个字符_ 用来代替1个字符(有且只有一个)
    float(m,n);  总共可以存储m位数字,小数点之后有n位m取值范围1-65    n取值范围是0-30默认:m=10    n=0
    
  • 数据库底层做的事情

    select * from student where chinese>=95 and english>=95;
    
    1.解析SQL
    2.从表格中全部数据都读取出来,放在数据库缓存,集合List
    3.将list集合做一个循环遍历,每一次拿到一个元素(一行记录),条件假设我们的表格有7条记录如果只写了一个where条件执行7次循环就可以比较出来啦如果有and连接不止一个条件先按照第一个条件先筛选7次循环,5条满足>95再按照第二个条件在筛选5次循环,2条满足
    4.如果以后在语句中使用了and尽量将条件苛刻的写在前面,提高执行效率
    

(2)order by

连接在查询语句之后

order by 列
升序排列 asc 默认就是升序,可以省略不写
降序排列 desc
order by 列名 asc,列名 desc;

(3)函数

函数----数据库定义好的(Java API中的方法)1.可以理解为函数就是以前我们Java中定义的方法2.函数需要调用才能执行,没有对象,函数直接放置在语句中相当于调用3.函数可以放置在什么位置上查询中用来显示的部分----->select 函数(列) from 表格;条件筛选的后面 ------>select 列 from 表格 where sal > 函数(值);
  • 比较函数

    isnull(值);  是空值返回1,不是空值返回0
    
  • 数学函数

    abs绝对值
    floor向下取整
    mod(5,2)取余数
    pow求次方
    round();四舍五入
    
  • 日期和时间

    now();
    year(date);
    month();
    day();
    week();
    
  • 控制流程函数

    if(条件,值1,值2);  如果条件满足,值1,否则为值2
    ifnull(值,v);    如果值为null,则值改为v
    
  • 字符串函数

                            String str = "abc";str.length();
    length(str)             length();
    concat()                concat();
    substr()                substring();
    instr(str,'a')索引从1开始    str.indexOf("a");
    replace(str,'a','A')        replace();
    upper()                 toUpperCase();
    lower()                 toLowerCase();
    ltrim()  rtrim()            trim();
    lpad()  rpad()
    lpad(str,10,'*');长度不够就在左边补*
    rpad(str,length(str)+4,'*');在str的右边加4个*
    reverse()
    
  • 分组函数+分组条件

    分组函数
    count()
    max()
    min()
    avg()
    sum()
    分组条件
    group by 列
    

(4)distinct

去重复 distinctdistinct 列  如果有一样的列信息,将一样的信息合并行数会减少,查询的每一个列,行数个数需要一致distinct 列,列,如果有两个以上的列,将两个或多个列的组合当做整体如果整体有一样的信息,才会去重复,否则就全部显示

(5)group by

分组函数+分组条件
分组函数count()max()min()avg()sum()
分组条件group by 列
如果先进行条件筛选,后分组    where group by
如果先进行分组,后进行筛选    group by having
如果分析之后还需要进行排序   order by最后处理

(6)in,any,some,all

in(),not in():满足查询自己中的某一个即可  默认=比较in后面的子集内,可以是常量固定值也可以是通过另一条sql语句查询出来的结果
如下的三个使用起来与in类似,查询是否满足后面子集中的条件
关键字的后面不允许写固定值,只允许写sql语句(只能通过嵌套来获取子集)any:满足查询子集中的某一个即可>any <any =any(结果与in一致) !=any(有一个不满足即可)some       与any完全一致all     满足查询子集中>all <all =all !=all(结果和not in)

(7)union

结合,合并

有两张表格,学生信息,老师信息
我们的学校想要召开运动会
学校想要给所有的老师和同学都准备统一的服装
这时候就需要统计全学校的所有人的信息select tid,tname,tsex from teacher union select sid,sname,ssex from student;
1.要求前后两个查询子集的列数是一致
2.类型没有要求
3.拼接后显示的列名是前一个子集默认的列名
4.注意union和union all的区别union合并后做去重复的处理,性能比较慢如果产生重复元素,记录的是第一次出现的那一行union all将两个查询的字节直接做合并不作任何处理,性能比较快建议以后尽量使用union all来进行合并处理

(8)limit

分页查询

limit a,b;
--注意:与函数使用区分 instr(ename,'A');   1第一个出现 0没有
--a为想要显示的起始行索引(第一行索引为0),包括此行,(偏移量)
--b为想要显示的行数

4、约束

(1)列的约束

a.主键约束

  • 设置主键约束

    --每一个表格内,只能有一个列被设置为主键约束
    --主键约束通常是用来标记表格中数据的唯一存在
    --主键约束要求当前的列,不能为null值
    --要求值是唯一存在的,不能重复
    --alter table 表名 add constraint 约束名字 约束类型 (列);
    alter table myclass add constraint pk_myclass primary key (classid);
    --也可以简写如下
    alter table 表名 add primary key (classid);
    
  • 查看约束

    --description 描述
    desc 表名;
    show keys from 表名;
    
  • 添加主键自增

    alter table myclass modify classid int(4) auto_increment;
    alter table myclass change classid classid int(4) auto_increment;
    
  • 取消主键自增

    alter table myclass modify classid int(4);
    
  • 设置自增起始值

    --默认为1
    alter table myclass auto_increment = 10;
    
  • 删除主键约束

    alter table myclass drop primary key;
    --删除后,不重复特性没了,但还需要删除非空约束
    alter table myclass modify classid int(4) null;
    alter table myclass change classid classid int(4) null;
    

b.唯一约束

  • 添加唯一约束

    --可以为表格中的某一个列添加唯一约束,约束与主键类似
    --唯一约束表示的列的值,不能重复,可以为null
    --唯一约束在表格中可以存在多个列
    --alter table 表名 add constraint 约束名 约束类型 (列);
    alter table myclass add constraint uk_myclass_cname unique [key] (loc);
    --简写如下
    alter table myclass add unique [key](loc);
    
  • 删除唯一约束

    alter table myclass drop index 约束名;
    

c.非空约束

  • 添加非空约束

    --在表格中的某一个列上添加非空约束
    --当前列的值不能为null
    --alter table 表名 modify 原列名 原列类型 not null;
    --alter table 表名 change 原列名 新列名 新列类型 not null;
    alter table myclass modify cname varchar(20) not null;
    alter table myclass change cname cname varchar(20) not null;
    
  • 删除非空约束

    --取消非空约束,即可以为null
    --alter table 表名 modify 原列名 原列类型 null;
    --alter table 表名 change 原列名 新列名 新列类型 null;
    alter table myclass modify cname varchar(20) null;
    alter table myclass change cname cname varchar(20) null;
    
  • 为非空约束添加默认值

    alter table myclass modify cname varchar(20) not null default 'xxx';
    alter table myclass change cname cname varchar(20) not null default 'xxx';
    

d.外键约束

  • 添加外键约束

    --表格中可以有多个列被设置为外键约束
    --当前列的值可以为空,可以重复
    --当前列的值不能随便的填写,值去另外一张表格内寻找
    --外键是当前列的值受到另外一张表格某一个列的影响
    --另外一张表格的列,是唯一约束(主键唯一)
    alter table 表名字 add constraint fk_当前表_关联表 foreign key() references 另一个表();
  • 查看外键约束

    show keys from 表名;
    desc 表名;
    show create table 表名字;
    --PRI UNI MUL---->multiple(多样,并联)
    
  • 删除外键约束

    alter table 表名字 drop foreign key 约束名字;
    show create table 表名字;  查看创建表时的语句--注意:通过上述语句其实已经将外键约束删掉了--自动在当前表格内添加了一个新的key--需要再次手动将这个生成的key删掉,外键约束才真的删除干净
    alter table 表名字 drop key 约束名字;alter table student add foreign key() references 另一个表();--注意:如果是简写的效果添加外键,外键的名字不是默认列名,
    alter table student drop foreign key 外键名;
    alter table student drop key 约束名;
    

e.检查约束

--检查约束SQL(Check)(MySQL中不起作用)
--列在存值的时候做一个细致的检查,范围是否合理
alter table 表名字 add constraint 约束名 check(检查约束条件);

f.小结

--表格中列的约束--1.主键约束--2.外键约束--3.唯一约束--4.非空约束--5.检查约束--添加
alter tableadd constraint 约束名字 约束类型 列 [references 表 列];
alter tablemodify 列 类型 长度 not null;
--删除
alter tabledrop 类型(primary key | index key | foreign key | key);
alter tablemodify 列 类型 长度 null;

5、DQL数据库操作语言

(1)表格之间的关系

0.列的约束主键 *外键 唯一  非空  检查
1.表格之间的关系一对多    一端保证一个主键    多端保证有一个晚间关联关系多对多    两个一对多合并在一起,中间表,中间表记录着两边的对应关系一对一   在一对多的基础上,将多端设置成唯一约束(多端外键-->唯一)(多端主键-->外键)

(2)联合查询

a.等值连接

--等值连接--广义笛卡尔积--->进行条件筛选--->等值连接--广义笛卡尔积将两张表格或多张表格,进行无条件的拼接--在拼接后的一张大表格的基础上进行了where的筛选--任何表格都能进行拼接
select * from A,B where 条件;
select * from A a,B b where 条件;  //给表格取别名

b.外连接

--外连接
select * from A left/right [outer] join B on 条件;
--1.两张表格A和B,取决于谁的数据在左边显示--A表格先出现,A左边显示--B表格后出现,B右边显示
--2.left和right来控制以哪一个表格的数据作为基准--作为基准的表格数据必须全部显示出来--非基准的表格按照on条件与之拼接--若找到条件拼接,则正常显示,若找不到满足条件的则 null
--3.外连接查询结果可能比等值连接的最终结果多一部分数据
--4.因为外连接是分为左外,右外,可以省略outer关键字
--5.外连接不写on关键字是不能进行拼接

c.内连接

--内连接(自连接)(建议用内连接替代等值连接)
select * from A inner join B on 条件;
--在当前表格中再次查询当前表格的信息
select e1.empno,e1.ename,e1.mgr,e2.empno,e2.ename from emp e1,emp e2 where e1.mar = e2.empno;
select e1.empno,e1.ename,e1.mgr,e2.empno,e2.ename from emp e1 inner emp e2 on e1.mgr = e2.empno;
--1.查询出的结果与等值连接的结果一致
--2.内连接不分左右,不能省略inner关键字
--3.A和B是可以不同的两张表格
--4.A和B也可以是相同的一张表格--必须给表格起别名--可能还需要当前表格有一定的设计

d.行列互换

 wname   winventory  wmonth仓库名称  仓库库存        月份A 100     一月份B    1000        一月份C    10      一月份A    200     二月份B    2000        二月份C    20      二月份A    300     三月份B    3000        三月份C    30      三月份要求变成如下效果仓库名称 一月份 二月份 三月份A        100     200     300         A组三个值,每一个月份对应一个库存B       1000    2000    3000        B组三个值,每一个月份对应一个库存C       10      20      30          C组三个值,每一个月份对应一个库存
--一旦使用group by分组条件
--可以select 显示的列,只有两种(分组条件,分组函数)
select wname,max(if(wmonth='一月份',winventory,0)) as '一月份',max(if(wmonth='二月份',winventory,0)) as '二月份',max(if(wmonth='三月份',winventory,0)) as '三月份'
from warehouse
group by wname;

6、DCL数据库控制语言

(1)查询所有用户信息

--管理员可以操作其他普通用户的权限
--通过root账号查看mysql数据库中的user表格
--记录着所有用户信息
select user,host,authentication_string from user;

(2)创建一个新的用户

--database table user
--create user '用户名'@'IP' identified by '密码';
create user 'lwy'@'localhost' identified by '123456';
--用户被创建成功啦(只有一个默认的权限 Usage 只允许登录,不允许做其他事情)
--通过这个语句查看权限:
show grants for '用户名'@'IP';

(3)给新的用户赋予权限

--grant 权限 on 数据库名.表 to '用户名'@'IP';
grant all on *.* to 'lwy'@'localhost';
--赋予权限之后最好刷新一下
flush privileges;

(4)注销root,用新用户登录

exit;
mysql -u lwy -p
123456

(5)回收用户权限

--Usage
--revoke 权限 on 数据库名.表名 from '用户名'@'IP';
revoke all on *.* from 'lwy'@'localhost';

(6)修改用户的密码

--update user set authentication_string = password('123') where user = 'lwy';
--alter user '用户名'@'IP' identified by '新密码';
alter user 'lwy'@'localhost' identified by '123';
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '123456';

(7)删除用户

--drop user '用户名'@'IP';
drop user 'lwy'@'localhost';

(8)常用权限

 数据库/数据表/数据列权限:Create         建立新的数据库或数据表Alter            修改已存在的数据表(例如增加/删除列)Drop         删除数据表或数据库Insert         增加表的记录Delete            删除表的记录Update            修改表中已存在的记录Select            显示/搜索表的记录----------------------------------------------------------------------------References     允许创建外键Index         建立或删除索引Create View      允许创建视图Create Routine        允许创建存储过程和包Execute           允许执行存储过程和包Trigger           允许操作触发器Create User      允许更改、创建、删除、重命名用户和收回所有权限全局管理MySql用户权限:Grant Option        允许向其他用户授予或移除权限Show View     允许执行SHOW CREATE VIEW语句Show Databases        允许账户执行SHOW DATABASES语句来查看数据库Lock Table      允许执行LOCK TABLE语句来锁定表File            在MySQL服务器上读写文件Process           显示或杀死属于其他用户的服务线程Reload          重载访问控制表,刷新日志ShutDown     关闭MySQL服务特别的权限:All           允许做任何事(和root一样)Usage            只允许登录,其他什么也不允许做

7、TPL事务处理语言

(1)范式

1NF数据的原子性每一个表格的每一个列都是不可分割的(行列交叉点的单元格内只存储一个数据)每一个表格必须有主键约束(快速查询某一行记录)
2NF在满足第一范式的前提下不允许出现部分依赖型(非主键列不能受到主键列或主键的一部分影响)
3NF在满足前两个范式的前提下不允许出现传递依赖(非主键列不能受到非主键列或非主键的一部分影响)

(2)事务

a.概念

SQL语句使我们给数据库发送了指令,让数据库帮我们做事情1.事务可以理解为是让数据库做的事情2.有些时候事情之内不止一条sql,存在多个组成单元比如:银行系统 转账 张三 100 ---->李四update atm set abalance = 原来-100 where aname = 张三;update atm set abalance = 原来+100 where anem = 李四;登录 查询余额 存款 取款 转账 开户 销户.txt文件 I/O缓存Map commit();  MVC分层思想 IO 缓存3.一件事情中的所有操作应该是统一的要么都成功,要么都失败4.事务的本质可以理解为多线程并发操作同一张表格可能带来的安全问题

b.特征

事务的四大特性(ACID)
A:Atomicity---->原子性一个事务中的所有操作是一个整体,不可再分事务中的所有操作要么都成功,要么都失败
C:Consistency---->一致性一个用户操作了数据,提交以后另一个用户看到的数据与之前的用户看到的效果是一致的
*I:Isolation---->隔离性----->(事务隔离级别)指的是多个用户并发访问数据库时一个用户操作数据库,另一个用户不能有所干扰多个用户之间的数据事务操作需要互相隔离
D:Durability---->持久性指的是一个用户操作数据的事务一旦被提交(缓存--->文件)他对数据库底层真实的改变是永久性的,不可返回

c.实现

 mysql数据库事务管理默认的效果可以更改autocommit变量 = on;show variables like '%commit%';show variables like 'autocommit';set autocommit = off;    设置自动提交关闭1.开启一个事务每一次执行的一条sql语句之前mysql数据库都会默认的开启begin;    start transaction;2.执行操作insert,update,deleteselect可能不止一条语句3.事务的处理提交/回滚/保存还原点commit;rollback;mysql数据库会默认的执行提交事务

d.隔离级别

 事务的隔离性可能会产生多线程并发操作同一个数据库表格的问题1.脏读一个人读到了另外一个人还没有提交的数据A B在操作同一张表格A修改了数据,还没有提交,B读取到了A不提交了,回滚回来,B刚刚读取到的那些数据就是无用的---脏数据2.不可重复读A B在操作同一个表格A先读取了一些数据,读完之后B此时将数据做了修改/删除A再按照之前的条件重新读一遍,与第一次读取的不一致3.幻读(虚读)A B在操作同一个表格A先读取一些数据,读完之后B此时将数据做了新增A再按照之前的条件重新读一遍,与第一次读取的不一致会带来数据的安全隐患需要考虑事务的隔离级别Serializable        最高 可以避免所有出现的问题,性能很慢Repeatable Read       可重复读        (可以避免脏读和不可重复读)Read Committed        读已提交        (避免脏读)Read UnCommitted  读取未提交   (所有的效果均无法保证)MySQL数据库提供的默认隔离级别   Repeatable ReadOracle数据库提供默认隔离级别        Read Committed可以修改数据库中的隔离级别set session transaction isolation level xxx;如果不放心可以查看select @@tx_isolation;

8、JDBC

(1)步骤

通过java利用JDBC的桥梁操作MySQL数据库
JDBC六部曲1.导包(将找到的这个jar文件包导入到Java工程里)在我们的工程里创建一个文件夹lib将mysql-connector-java.jar复制到当前工程lib文件夹内做一个设置File-->Project Structure--->Libraries点击中间的+,选择Java,选择jar文件路径2.加载驱动类  Driver,Class.forName("com.mysql.jdbc.Driver")3.获取连接----可以理解为以前的Socket,DriverManager4.创建状态参数(流)--可以理解为是以前socket.getInputStream socket.getOutputStream5.执行数据库操作写DML--->insert,delete,update   (对数据库进行更新)读DQL---->select            (数据库没有发生变化,我需要处理结果)6.关闭

(2)实现

//        1.导包(将找到的这个jar文件包导入到Java工程里)
//        2.加载驱动类  Driver
String className = "com.mysql.jdbc.Driver";
try {Class.forName(className);       //加载类,雷钟德静态元素就执行啦//        3.获取连接----可以理解为以前的Socket,DriverManagerString url = "jdbc:mysql://localhost:3306/test";    //jdbc:mysql://ip:port/database名String user = "root";String password = "root";Connection connection = DriverManager.getConnection(url,user,password);//        4.创建状态参数(流)--可以理解为是以前socket.getInputStream socket.getOutputStreamStatement statement = connection.createStatement();//        5.执行数据库操作//        写DML--->insert,delete,update (对数据库进行更新)//        读DQL---->select           (数据库没有发生变化,我需要处理结果)//            String sql = "insert into emp(empno,ename) values(9999,'zzt')";//            String sql = "update emp set ename = 'lwy' where empno = 9999";String sql = "delete from emp where empno = 9999";statement.executeUpdate(sql);System.out.println("执行完毕!!");//        6.关闭statement.close();connection.close();
} catch(Exception e) {//异常处理
}

(3)查询操作

ResultSet rs = executeQuery(String sql);    Set<Map<String,Object>>
if(rs.next()) {int empno = rs.getInt("empno");String ename = rs.getString(2);
}
//rs.getString();   可以接受任何一个列的值,自动转化
//rs.getInt();  不能接受其他类型,比如String

(4)其他问题

a.版本问题

1.导包 8.x  5.x  版本不一致,有问题
2.加载驱动类的时候如果5.x版本   com.mysql.jdbc.Driver如果8.x版本    com.mysql.cj.jdbc.Driver
3.获取链接的时候8.x  5.x版本不一致,有问题如果5.x版本    url---->jdbc:mysql://ip:port/database名url---->jdbc:mysql://ip:port/database名?useSSL=true如果8.x版本   url---->jdbc:mysql://ip:port/database名?serverTimezone=CSTString url = "jdbc:mysql://localhost:3306/test?serverTimezone=CST";

b.加载驱动问题

//1.通过反射机制Class.forName("类全名");---->类中的静态成员//static特征修饰符 属性 方法 块 内部类
//2.通过DriverManager静态方法注册驱动DriverManager.registerDriver(new Driver());
//3.通过直接创建驱动对象new Driver();
//4.通过System类中设置属性值来加载System.setProperty("jdbc.driver","com.mysql.cj.jdbc.Driver");

c.操作事务

//1.JDBC默认的开启事务,默认的自动提交事务
//2.可以自己设计手动提交事务conn.setAutoCommit(false);    false表示手动提交 true默认,表示自动提交
//3.可以设置事务的隔离级别conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
//4.事务最终的处理操作conn.commit();conn.rollback();
//5.设置还原点Savepoint s = conn.setSavepoint("x");conn.rollback(s);

d.SQL注入

跟字符串拼接有关
1.SQL注入所谓的SQL注入意思就是通过SQL命令,拼接其他的字符串让其他的那些字符串来改变原有的SQL语句的执行最终达到欺骗服务器的效果
2.问题产生的原因1.判断不严谨导致的2.SQL语句问题,允许拼接字符串,认为用户很不安全3.可以利用PreparedStatementStatement 和   PreparedStatement普通的状态参数        预处理的状态参数创建时不需要SQL   创建时就需要预先加载SQL语句此时没有执行       此时没有执行,但底层预先处理SQL需要查询的结果,性能高可以利用动态化进行参数的处理,利用?代替,数据类型及值好处1.增强SQL可读性2.可以参数动态化3.防止SQL注入4.提高执行性能
PreparedStatement使用方式与之前的Statement类似通过连接获取  PreparedStatement pstat = conn.prepareStatement(sql);在创建对象时需要预先接在SQL,需要一个String参数SQL语句为了防止注入的问题,可以使用动态化参数处理,可以利用?代替 值和类型SQL语句的可读性就增强   并且提高了执行效率注意:sql语句上面的问号需要在执行操作之前赋值pstat.setXXX(parameterIndex.value);

e.模糊查询

模糊查询 like %_ 方式一Sql语句正常写 select * from emp where ename like ?pstat.setString(1,"%"+letter+"%");方式二Sql语句稍微改变一下    select * from emp where ename like "%"?"%";sql语句对于Java程序来说就是一个字符串String sql = "select * from emp where ename like \"%\"?\"%\"";pstat.setString(1,letter);sql语句本身的双引号和String类型的双引号冲突可以利用转义字符来帮忙
分页查询    limit 起始行索引,每页几个

三、协议、网络

1.计算机

冯诺依曼式计算机–冯诺依曼(计算机之父)

  • 运算器:CPU,GPU(显卡)
  • 存储器:
    • 内存:断电数据清空,读写速度快
    • 硬盘:辅存,数据可以持久化,读写速度相对较慢
  • 控制器:主板上的一些器件
  • 输入设备:键盘,鼠标,麦克风,网口
  • 输出设备:显示器,耳机,网口

2.IP地址

(1)格式

IP地址分为四个段:xxx.xxx.xxx.xxx

每个段0-255,每个段都是由8个0或1组成的

(2)分类

一个IP地址分为两个部分:网络ID,主机ID。

A类:0.0.0.0—127.255.255.255
B类:128.0.0.0—191.255.255.255
C类:192.0.0.0—223.255.255.255
D类:多播地址
E类:

3.域名和DNS解析

www.baidu.com 域名

(1)解析

用域名和IP形成对应关系

首先,计算机是不知道域名对应的IP的。
问路由器,如果路由器认识这个域名,就返回一个IP,然后计算机访问这个IP;
如果路由器不认识,他就问上一层路由器;
如果问到了城市这个级别的路由器的时候,DNS服务器。
如果DNS服务器不认识这个域名,继续向上级DNS服务器查找。

互联网建立的时候,13台总的DNS服务器。

(2)URL解析

当向浏览器的地址栏中输⼊⼀个url按回⻋之后,⽹络中都会发⽣什么?例如:123.xyz

1.看浏览器的缓存。本机host找到文件:C:windows/system32/drivers/etc/host寻找对应IP地址:127.0.0.1 localhost 0.0.0.0
2.如果找不到,则从家⾥路由器里找
3.如果找不到,再向上级路由、城市的LDNS服务器
4.继续向上级的DNS服务器找。
gDNS服务器。

4.网络模型

由上到下:应用层、运输层、网络层、数据链路层、物理层

(1)应用层

HTTP协议、DNS协议

a.HTTP协议

请求:Request

响应:Response

请求方式:Post,Get

(2)运输层

TCP协议、UDP协议

a.TCP/IP协议

对方的IP,自己的IP,对方的端口

(3)网络层

IP地址—IP协议

(4)数据链路层

mac地址

(5)物理层

5.请求方式

Get和Post方式

1.没有前提的情况下,GET和POST几乎没什么区别,只有名字不一致。
2.语法相同,语义不同,GET是为了获取数据,POST是为了发送数据。
3.GET的数据在URL是可⻅的。POST请求不显示在URL中。
4.GET对⻓度是有限制的,POST⻓度是⽆限的。
5.GET请求的数据可以收藏为书签,post请求到的数据不可收藏为书签。
6.GET请求后,按后退按钮、刷新按钮⽆影响,post数据会被重新提交。
7.GET编码类型:application/x-www-form-url,post的编码类型:有很多种。encodeapplication/x-www-form-urlencoded multipart/form-data
8.GET历史参数会被保留在浏览器⾥,psot不会保存在浏览器中的。
9.GET只允许ASCII.post没有编码限制,允许发⼆进制的。
10.GET与POST相⽐,GET安全性较差,因为所发的数据是URL的⼀部分。

6.Cookie和Session

  • Cookie

    1.存放在浏览器里,可以长期存储
    2.不安全,登录成功后,每次请求带着存有ID的Cookie,就能免登录。
  • Session

    1.存储在后端,比较安全
    2.用户多的时候,资源消耗大

7.结构

  • B/S结构

    Browser/Server——Browser只负责内容的展示,Server负责提供内容。
    
  • C/S结构

    Client/Server——Client只负责内容的展示,Server负责提供内容。
    

8.跨域

答案:
1. 即使跨域了(协议,域名,端⼝号有不⼀样的),请求也可以发出。
2. 服务器端也是可以接收的。
3. 服务器端也是可以正常处理的。
4. 服务器端也是可以正常返回数据。
5. 浏览器也能接收到这些数据。
6. 接收到之后,发现当前⻚⾯的域和请求的域不同,所以判定为跨域。
7. 我们的代码在这等着结果呢,但是因为浏览器判定跨域了,不会把结果传递给我们的代码。
虽然跨域了,但是我们依然需要这个数据,怎么办?
解决跨域问题:
1. 后端(别⼈家的)配合我们进⾏跨域。pan.baidu.com ——> zhidao.baidu.com(1)JSONP(正常的情况,返回的数据都是JSON格式。JSONP是⼀种特殊的格式。)(2)后端设置Access-Control-Allow-Origin属性以⽀持跨域。(聊天机器⼈课讲,因为需
要nodejs)
2. 后端不配合我们进⾏跨域。(3)iframe(只能显示,不能控制)(4)通过后端代理(⾃⼰的后端)(后⾯聊天机器⼈讲,因为需要nodejs)

四、J2EE

1.请求与响应

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5dJYOYbW-1616603856878)(C:\Users\Administrator\Desktop\MarkDown\渡一后端\我的程序员笔记.assets\1616589996186.png)]

2.Servlet

(1)Tomcat

  • 简介
web容器-----服务器(硬件 软件)Tomcat   Apache组织开源免费容器
Jetty
Resin   Caucho公司一个产品
JBoss    WebLogic    WebSphereTomcat是Apache组织的一个开源免费的容器用来管理web项目     Servlet   JSP   HTML+CSS+JavaScript
了解一下历史及各种版本Tomcat6  JDK5     Servlet2.x  JSP2.x   EL2.xTomcat7  JDK6     Servlet3.x  JSP2.x   EL2.xTomcat8  JDK7     Servlet3.x  JSP2.x   EL3.xTomcat9  JDK8     Servlet4.0  JSP2.3   EL3.0
  • 安装和配置
1.下载一个Tomcat容器www.apache.org下载之后直接解压缩就可以使用啦
2.了解一下Tomcat容器的所有文件夹结构bin文件夹        服务器启动相关*conf文件夹 配置文件    web.xml(请求相关)    server.xml(容器自身的信息 比如端口)lib文件夹     jar形式的包logs文件夹  日志信息temp文件夹 临时文件*webapps文件夹 用来存放部署在容器内的项目资源的*work文件夹    用来存放解析JSP后形成的java文件
3.将Tomcat和IDEA集成在一起   便于开发调试Run---> Edit  Configurations左上角+号   Tomcat Server  Local若没有 证明IDEA中缺少相关的插件(File--Settings--Plugins--Installed)搭建一个集成环境完毕如果运行Tomcat后  IDEA控制台出现乱码的问题 解决一下1.修改一下IDEA安装目录bin文件夹中的配置文件D:\JetBrains\IntelliJ IDEA 2018.3\binidea.exe.vmoptionsidea64.exe.vmoptions记事本形式打开   添加一行    -Dfile.encoding=UTF-8如果不好用   另外再添加一行   -Dconsole.encoding=UTF-8
2.在配置Tomcat容器的时候做参数处理server选项卡VM options处添加   -Dfile.encoding=UTF-8如果还不好用Startup/Connection选项卡勾选 Pass  environment  variables手动添加JAVA_OPTS      -Dfile.encoding=UTF-8JAVA_TOOL_OPTIONS  -Dfile.encoding=UTF-8
4.创建web项目
5.访问web项目

(2)请求和响应

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-633jhqem-1616603856882)(C:\Users\Administrator\Desktop\MarkDown\渡一后端\我的程序员笔记.assets\1616590339953.png)]

  • 实现步骤

    *如何访问一个Servlet类对象
    1.自己写一个类   通常叫XXXController          (Servlet  Action)
    2.继承一个父类HttpServlet
    3.重写一个方法service        (doPost  doGet)
    4.方法里有两个参数HttpServletRequest    HttpServletResponse
    5.方法还有两个异常ServletException         IOException
    6.方法是没有返回值    void类型
    7.需要告知Tomcat有一个自己定义类需要帮忙管理  web文件夹  WEB-INF文件夹需要配置web.xml   请求名字----真实类全名   映射关系<servlet><servlet-name>用来配对的名字</servlet-name><servlet-class>真实类全名</servlet-class></servlet><servlet-mapping><servlet-name>用来配对的名字</servlet-name><url-pattern>/请求名字</url-pattern></servlet-mapping>
    8.浏览器发送请求
    

(3)项目布署

第一个问题,WEB项目如何导入外部的.jar包深入理解项目的部署以及运行的过程在IDEA编辑器中写完的这个项目  存在硬盘上 C:用户/账号名/IdeaProject(存储真实的代码文件)创建的是一个web项目   执行需要Tomcat容器帮我们管理需要将web项目部署在Tomcat内部   (webapps文件夹内)  D:tomcat9/webapps/部署的过程本质上是I/O文件读写  必然会耗费很多时间(IDEA)编辑器觉得耗费时间  默认的效果没有将真实的文件写入Tomcat 而是写了一个映射关系项目修改了部署的路径  现在我们的项目存在了Tomcat内部的webapps内我们原来的真实文件代码有两个主要的部分   src web发现部署之后的文件只含有web文件夹的内容 src丢掉了src不是真的丢掉了  src中存储的.java文件进行编译 .class才能用web文件夹下  WEB-INF文件夹  classes文件夹(后来生成)项目部署之后HTML文件资源 直接读取内容 内容做响应Servlet类 可以通过参考web.xml文件 获取类全名 通过反射 从而执行最终方法JSP(HTML+Java)   解析---形成一个为了JSP解析而生成的Java类   Tomcat内部 (work文件夹内)解析形成的新文件默认也是存在IDEA内的  为了减少耗费的时间

(4)请求乱码处理

浏览器发送请求的时候 如果携带了中文的信息

控制层接受的时候产生了文字乱码的问题请求发送时的方式get    在浏览器输入URL点击回车    <a href="">     <form method="get">post    <form method="post">两种不同请求的区别getURL看起来很复杂  请求后面会有?拼接一些参数只有协议头   没有协议体  只能讲参数拼接在URL上面postURL看起来很简单  只有请求资源名  没有?拼接有协议头和协议体两部分  协议头传递资源名  协议体传递参数信息发送请求--->请求Tomcat--->Tomcat有一个默认处理字符集Tomcat的配置文件中存储 ISO-8859-1老版本UTF-8新版本(Tomcat8之后)
  • get请求

    get请求的处理方式发送请求的时候  请求名字 携带的参数信息都在协议头中浏览器解析的时候  <meta charset="UTF-8">如果Tomcat是老版本 get请求需要如下处理String aname = request.getParameter("aname");byte[] value = aname.getBytes("ISO-8859-1");String newString = new String(value,"UTF-8");如果Tomcat是新版本 可以不处理
    
  • post请求

    post请求的处理方式发送请求的时候  请求名字 协议头中请求的参数信息是在协议体中(协议体只能传递字节)浏览器解析的时候  <meta charset="UTF-8">控制层接受的时候已经组合成一个String字符串发送请求的时候按照UTF-8形式   拆开字节接受的时候request对象直接给我组合(按照平台默认的字符集)成一个String在request组合之前告知 按照哪一种字符集进行组合request.setCharacterEncoding("UTF-8");
    

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ktocNYzu-1616603856884)(C:\Users\Administrator\Desktop\MarkDown\渡一后端\我的程序员笔记.assets\1616591294050.png)]

(5)管理机制

1.Servlet类的对象是单例设计模式(对象是唯一的)采用生命周期托管的方式实现的Tomcat底层有一个类似ServletController的类管理着我们的对象
2.单例对象的产生立即加载(Tomcat启动的时候 底层集合内就存在对象啦)延迟加载(Tomcat启动的时候没有对象产生 什么时候发送请求需要用到这个对象 才会创建)Tomcat启动的时候   web.xml文件如果写错了   服务器启动会报错证明Tomcat在启动的时候  就读取了我的web.xml配置文件web.xml文件配置的目的  存储请求名字---真实资源类名的对应关系Servlet对象的创建和销毁---->Servlet对象的生命周期问题Tomcat为了更好的管理对象的产生和销毁提供了三个方法---->标识Servlet对象的生命周期init();  service();  destroy();    重新部署项目
3.默认效果是一个延迟加载的机制
web.xml文件(如果配置错误 启动Tomcat时候就产生问题)说明Tomcat启动的时候读取了我们的配置文件---->请求  真实类名启动时候可能会有很多的Servlet对象   如果是立即加载的话  内存压力很大
4.如果想要改变对象的加载  从延迟的方式变成立即的方式(Tomcat启动的时候就创建对象)在web.xml文件中添加一个配置就可以啦<servlet><servlet-name><><servlet-class><><load-on-startup>整数0</load-on-startup></servlet><servlet-mapping></servlet-mapping>
5.如果对象是立即加载的 可能当前对象对于整个项目的执行非常重要有些时候通常会携带一些重要的信息<servlet><servlet-name><><servlet-class><><init-param><param-name>key1</param-name><param-value>value1</param-value></init-param><load-on-startup>整数0</load-on-startup></servlet><servlet-mapping></servlet-mapping>可以在init方法内使用带ServletConfig的参数读取String value = config.getInitParameter("key");//某一个key对应的valueEnumeration en = config.getInitParameterNames();//获取全部的keyString name = config.getServletName();//获取当前Servlet类名ServletContext application = config.getServletContext();//获取全局上下文对象
public class ServletController{//请求名字和真实类名字对应关系private static HashMap<String,String> controllerNameMap = new HashMap<>();            //请求名字和类对象的关系private static HashMap<String,HttpServlet> objMap = new HashMap<>();public void findController(request,response){String content = request.getContent();//请求的名字HttpServlet obj = objMap.get(content);//通过请求名字去第二个集合找真实对象if(obj==null){String realControllerName = 读取配置文件获取类全名(缓存)Class clazz = Class.forName(realControllerName);//找类HttpServlet obj = clazz.newInstance();objMap.put(content,obj);//}Class ControllerClazz = obj.getClass();Method method = clazz.getMethod("service",request,response);method.invoke(obj,request,response);}
}
  • Servlet类的继承关系
Servlet类的继承关系我们自己的类继承HttpServlet(抽象类)HttpServlet又继承了一个类GenericServlet(抽象类)GenericServlet又实现了三个接口Servlet接口    ServletConfig接口   Serializable接口ServletConfig接口里面只有四个方法(抽象的)String = getInitParameter(String var1);Enumeration<String> = getInitParameterNames();String = getServletName();ServletContext = getServletContext();Servlet接口里面有五个方法(抽象的)void init(ServletConfig var1) throws ServletException;void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;void destroy();ServletConfig getServletConfig();String getServletInfo();GenericServlet抽象类为什么实现接口?????-----体现出来的是缺省适配器设计模式9个接口中的方法都添加过来将其中的8个方法都进行了方法重写----添加具体实现{}多添加了一个init()无参数的方法只留下了一个方法是没有具体实现的service方法(留给用户必须添加)多了一些自己独有的方法init()  log()HttpServlet抽象类的存在目的????-----具体化的说明和体现  肯定是跟HTTP协议有关添加了很多具体的属性   都与协议有关  get  post  。。。添加了很多具体的与请求方式对应的方法doGetdoPost添加了几个自己独有的方法   getLastModifer   set   getAllDeclaredMethods保留了上面service方法 但将这个方法添加具体实现方法内部将两个没有协议的参数  强制类型转化成带HTTP协议的参数添加了一个独有的service方法   最终真正执行的那个方法内部先通过request.getMethod();获取请求的方式get/post找寻对应请求方式的方法执行  doPost   doGet我们自己的类继承 HttpServlet重写了service方法根据请求的方式找寻对应的doXXX方法请求发送过来  服务器底层通过反射就找service方法我们如果重写了service  正常执行我们的如果我们没有重写service 找HttpServlet类中的service方法HttpServlet类中的service方法 调用了doPost或doGet 其中的一个doPost或doGet方法不会做事 判断请求是正常的HTTP协议 返回405(没有方法执行)建议大家类中重写doPost或doGet其中的一个 更清晰的体现出请求的过程了

(6)小结

1.Servlet对象是单例的2.才用生命周期托管的方式实现的单例模式3.Servlet对象是延迟加载的方式4.Servlet对象是有一个生命周期    有三个方法可以看出生命周期对象创建时      init()  init(ServletConfig config)对象每次使用    service(HttpServletRequest,HttpServletResponse)对象被回收        destroy()       重新部署项目   关闭Tomcat5.可以通过修改web.xml配置文件  改变Servlet对象的加载方式   从默认延迟加载----->立即加载<servlet><load-on-startup>0</load-on-startup>   0开始的整数  整数越小加载越早</servlet>6.在Servlet对象创建时,可以通过配置携带一些信息,就可以让Servlet对象读取到<servlet><init-param><param-name>key</param-name><param-value>value</param-value></init-param></servlet>在Servlet对象的init方法中进行读取   通常利用带ServletConfig参数的方法String value = config.getInitParameter("key");Enumeration = config.getInitParameterNames();String = config.getServletName();ServletContext application = config.getServletContext();//获取全局上下文对象7.Servlet继承的关系????自己写一个类--->继承抽象类HttpServletHttpServlet--->继承抽象类GenricServletGenricServlet-->实现了三个接口  Servlet    ServletConfig   SerializableServlet接口含有5个方法init(ServletConfig config);service(ServletRequest,ServletResponse);destroy();ServletConfig = getServletConfig();String = getServletInfo();ServletConfig接口含有4个方法String value = config.getInitParameter("key");Enumeration = config.getInitParameterNames();String = config.getServletName();ServletContext application = config.getServletContext();GenricServlet抽象类体现出了缺省适配器模式将上述两个接口中的8个方法全部添加了实现只留下一个service抽象方法    需要用户自己填写逻辑还添加了两个独有的方法   init(){} 无参数  log(){}HttpServlet体现了对于协议的具体化将父类service方法实现了目的是将两个跨协议的参数强制转化成HTTP协议自己添加了一个protected修饰的service方法(参数HttpServletRequest)独有service方法的目的是通过请求发送的方式get/post找寻对应具体的执行方法doGet   doPost8.从今以后如何使用???1.自己写一个类   类名字通常XXXController2.继承HttpServlet   当然我们也可以继承GenricServlet  当然也可以直接实现Servlet接口3.重写方法doPost/doGet/service    请求的方式更加的清晰4.方法参数HttpServletRequest    HttpServletResponse5.方法修饰符和返回值       protected/public 返回值void6.方法异常ServletException   IOException7.工程内web文件夹中WEB-INF文件夹web.xml配置文件    目的      请求---真实Controller类全名对应关系8.浏览器发送请求   访问操作资源404   没有找到资源  检查xml文件   检查Controller类405  没有找到执行方法    检查Controller类中的方法重写

3.JSP

(1)基本使用

 1.JSP----JS区别JS----JavaScript   基于对象和事件驱动的脚本语言JSP--Java Server Page Java服务器页面   Java服务页原来我们是在Java中的Servlet类中   用out.write("<>");JSP为了服务Servlet的    拼接响应信息的部分   相当于换了一个拼接的位置JSP融合了    HTML  +  Java2.JSP从写法上看似是个文件.java     .html       .jspJSP看似是个文件    因为文件中存有HTML+Java代码    最终浏览器展示的时候不认识JSP实际上应该是一个操作资源(JSP本质就是Servlet)所以底层想要执行看见JSP中的内容  需要Tomcat支持   浏览器访问3.如何创建一个JSP文件创建JSP以后  需要在第一行填写一个描述信息<%@page 属性=值%>contentType="text/html;charset=UTF-8";//告知浏览器language="java"//用来说明JSP中可以含有除了HTML形式的其他语言pageEncoding="UTF-8"//用来说明Tomcat在进行JSP编译的时候文件中的内容   如果是正常的HTML标签   正常写如果想要在JSP中写Java    <%%>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FtqMkQGO-1616603856886)(C:\Users\Administrator\Desktop\MarkDown\渡一后端\我的程序员笔记.assets\1616592813188.png)]

(2)执行原理

 浏览器发送请求1.请求文件资源.html底层Tomcat参考自己的web.xml直接找到文件资源  文件中的内容(String <>)读取出来   直接响应回浏览器2.请求操作资源Servlet底层Tomcat参考我们工程内自己的web.xml配置文件  servlet  servlet-mappint通过反射找到我们自己写的XXXController类  反射找执行方法  service  doPost  doGet方法执行完毕   是自己out.write("<>");响应的   直接回浏览器有可能产生请求转发的 forward(req,resp);JSP      xxx.jsp底层Tomcat参考它自己的web.xml 找寻一个JSP解析引擎  JSPServlet解析引擎 负责读取JSP的内容 将内容重新拼接组合 将新的内容写入一个java文件java文件的名字叫    xxx_jsp.java   文件内容是out.write("");java文件还需要进行编译  形成一个   xxx_jsp.classclass文件执行  回浏览器这两个生成的文件默认存储在IDEA自己的文件夹下C:\Users\Administrator\.IntelliJIdea2018.3\system\tomcat\Tomcat_9_0_19_TestJSP\work\Catalina\localhost\TestJSP\org\apache\jsp3.为什么JSP是一个Servlet从请求的配置文件可以看出从真正生成的java类   方法也能看出    _jspInit()    _jspDestroy()    _jspService();4.JSP中的内置对象    9个   _jspService(request response){方法内部sessionapplcationoutpagepageContextconfig}

(3)JSP标签

<%@   %>   做说明  通常放在头部
<%!  %>   写Java代码 _jspService方法外部,作为成员存在,通常用来定义属性,方法
<%   %>   写Java代码 _jspService方法内部,方法内的局部,通常是写逻辑
<%=  %>   写Java代码 _jspService方法内部,通常用来赋值或者打印输出

a.指令标签

<%@ xxx %> 通常放置在JSP头部   做说明性质的描述
<%@ page %>contentType="text/html;charset=UTF-8"   告知浏览器解析时遵循的规则language="java"       告知JSP中含有的语言(默认)pageEncoding="UTF-8" 告知Tomcat解析JSP时遵循的字符规则Tomcat将JSP解析成Java文件---->   pageEncoding   charset   Tomcat默认浏览器解析class文件回写的消息-->    charset    pageEncoding  浏览器默认import=""  在JSP中导入的Java文件的包isErrorPage="true"  设置当前JSP作为一个异常页  exceptionerrorPage="xxx.jsp"
<%@ taglib %> Jsp   Standard   Tag  Library   JSTLuri="http://java.sun.com/jsp/jstl/core" prefix="c"
<%@ include%> 用来在当前JSP中引入已经写好的资源      .jsp    .htmlinclude标签引入一个JSP资源正常(不会出现中文乱码的问题 脚本也同时好用)include标签引入一个HTML资源(产生中文乱码 即便是设置了charset也不好用)解决上述HTML乱码问题需要配置一个文件 web.xml主要配置page-encoding就可以了<jsp-config><jsp-property-group><description>JSPConfiguration</description><display-name>JSPConfiguration</display-name><url-pattern>*.jsp</url-pattern><el-ignored>false</el-ignored><page-encoding>UTF-8</page-encoding><scripting-invalid>false</scripting-invalid></jsp-property-group><jsp-property-group><description>HTMLConfiguration</description><display-name>HTMLConfiguration</display-name><url-pattern>*.html</url-pattern><el-ignored>false</el-ignored><page-encoding>UTF-8</page-encoding><scripting-invalid>false</scripting-invalid></jsp-property-group></jsp-config>

b.动作标签

<jsp:xxx>
替代之前Java程序 创建对象 对象赋值取值  请求转发 携带参数<jsp:include page=""><jsp:useBean id="atm" class="domain.Atm" scope="request"></jsp:useBean><jsp:setProperty name="atm" property="*"></jsp:setProperty>      //当atm属性名与表单参数名一致时使用<jsp:setProperty name="atm" property="aname" param="aname"></jsp:setProperty>   //设置单个atm属性值时使用<jsp:getProperty name="" property=""></jsp:getProperty><jsp:forward page=""><jsp:param name="" value=""></jsp:param></jsp:forward>

c.小结

1.技术最早是ModelOne模式只有Servlet   VC+MVC在一起的  拼接响应信息V  很麻烦
2.技术稍微革新了一下ModelTwo模式JSP+Servlet    V+CV  C分开   M
3.JSP技术出现以后   写法比较简单   更像是一个文件资源而且这个文件中还能直接写Java程序JSP--->V        JSP--->Servlet运行性能就有问题   不安全   管理起来也不方便JSP2.0   动作标签    替代对象创建  赋值  请求转发
4.JSP展示时候会出现一些逻辑的问题所有JSP的标签风格不统一EL+JSTLExpression  LanguageJsp  Standard  Tag  Library
5.新的模板语言产生JSP三个指令标签 <%@page%>  <%@taglib%>  <%@include%>
JSP六个动作标签   <jsp:>   useBean  setProperty  getProperty  forward  param  include
JSP四个作用域    page(pageContext)   request    session     application
JSP九个内置对象   request  response  session  application  out  page  pageContext  config  exception

(4)内置对象

-HttpServletRequest      request
-HttpServletResponse    response
-HttpSession        session
-ServletContext     application
JSPWriter           out
Object          page
PageContext     pageContext
-ServletConfig      config
Exception           exception

a.HttpServletRequest

request

1.用来获取请求携带的参数信息String value = request.getParameter("key");
2.用来设置接受请求参数时的字符集(POST)request.setCharacterEncoding("UTF-8");
3.存储某一个自己产生的数据  业务逻辑方法的结果request.setAttribute("key",Object);
4.获取之前一次请求中request对象存储的数据Object = request.getAttribute("key");
5.用来设置转发的资源位置RequestDispatcher rd = request.getRequestDispatcher("path");rd.forward(request,response);//真正的转发
6.获取请求携带参数全部的keyEnumeration = request.getParameterNames();
7.获取key一致的一组value值  通常用作复选框String[] = request.getParameterValues("key");
8.Uniform   Resource  Locator统一资源定位器StringBuffer = request.getRequestURL();//http://localhost:8080/JSPBuiltInObject/index.jsp
9.Uniform   Resource    Identifier统一资源标识符String = request.getRequestURI();/JSPBuiltInObject/index.jsp
10.获取协议头传递的信息   国际化request.getHeader("Accept-Language");
11.HttpSession = request.getSession();
12.Cokie[] = request.getCookies();
  • 协议头

    GET    /index.jsp     HTTP/1.1
    Host: localhost:9999
    Connection: keep-alive
    Upgrade-Insecure-Requests: 1
    User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
    Accept-Encoding: gzip, deflate, br
    Accept-Language: zh-CN,zh;q=0.9
    Cookie: Webstorm-2f8f75da=1b88d886-30e2-4089-abc9-af9030089775
    

b.HttpServletResponse

response

1.response.setCharacterEncoding("UTF-8");
2.PrintWriter pw = response.getWriter();pw.write();
3.获取状态响应码int statusNumber = response.getStatus();
4.设置响应码response.setStatus(int statusNumber);
6.response.addCookie();new Cookie("key","value");
7.用来做请求重定向response.sendRedirect("path");

转发和重定向

 forward                     sendRedirect
1.类不一样RequestDispatcher类            HttpServletResponse类
2.调用方式不一样request.getRequestDispatcher("path");  response.sendRedirect("path");rd.forward(req,resp);
3.转发或重定向请求都是在服务器端产生的转发是在服务器内部发起的    重定向是在服务器内部发起的在服务器内部转发          告知浏览器需要重新定位新的资源浏览器不知道                浏览器被动的发起一个新的请求   浏览器知道一次请求               相当于产生了新请求
4.浏览器URL地址栏是否会发生改变???转发的时候浏览器URL不会改变       重定向的时候浏览器的URL会发生改变
5.请求时候是否传递参数??? req  resp传递了req resp        没有传递req resp可以获取之前请求携带的参数   不能获取之前请求携带的参数
6.转发只能在当前服务器的当前工程内部     重定向可以发送给新的服务器或新的工程
  • 转发

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Zkruvp5k-1616603856888)(我的程序员笔记.assets/1616596815977.png)]

  • 重定向

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ldAEsUVx-1616603856889)(我的程序员笔记.assets/1616596833468.png)]

c.HttpSession

session

session.setAttribute("key",Object);
Object = session.getAttribute("key");
session.removeAttribute("key");
Enumeration en = session.getAttributeNames();//获取全部的key
  • 作用域

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GnpT1NdZ-1616603856890)(我的程序员笔记.assets/1616597186090.png)]

d.ServletContext

application

1.application.setAttribute("key",Object);
2.Object = application.getAttribute("key");
3.application.removeAttributer("key");
4.Enumeration en = application.getAttributeNames();5.String value = application.getInitParameter("key");
6.Enumeration en = application.getInitParameterNames();
<context-param><param-name>testParam</param-name><param-value>testValue</param-value>
</context-param>7.application.getRequestDispatcher("").forwar(req,resp);
8.String realPath = application.getRealPath("/");

e.JSPWriter

out

write();
println();

f.Object

page

当前页对象

g.PageContext

pageContext

页面对象上下文

pageContext.setAttribute();
pageContext.getAttribute();
pageContext.removeAttribute();

g.ServletConfig

config

String value = config.getInitParameter("key");
Enumeration en = config.getInitParameterNames();
String name = config.getServletName();
ServletContext application = config.getServletContext();

h.Exception

exception

可以写一个新的jsp   比如error.jsp
在error.jsp头信息上设置     isErrorPage="true"
在正常的jsp中设置头信息   errorPage="error.jsp"
404没有找到资源  不是异常

4.EL+JSTL

(1)EL

Expression Language

  • 简介
EL*1.代替原来Java程序取值的过程 request.getParameter();  request.getAttribute();2.能处理一些简单的计算(算数 逻辑 比较)3.调用方法(通常是有返回值)---->不常见
  • 用法
1.代替JSP中Java程序获取域对象中的信息page(pageContext) request session  applicationsetAttribute("key",objcet);(造型)getAttribute("key");
2.取值的不同类型基本数据类型+包装类类型+String类型${xxxScope.key}对象类型${xxxScope.key.属性}----->拥有对应的get方法${xxxScope.key.方法()}数组类型集合类型
3.EL有几个自己的作用域对象(EL内置隐式对象)*${param.xxx}${paramValues.xxx)*${requestScope.xxx}*${sessionScope.xxx}${applicationScope.xxx}${pageScope.xxx}${initParam.testParamName1}      web.xml配置文件  <context-param> ${cookie}${header["accept-language"]}
4.做简单的计算算数运算    + - * /  % mod比较运算  >gt  >=ge  <lt  <=le  !=ne  ==eq逻辑运算    &&(and)  ||(or)  !(not)

(2)JSTL

JavaServerPage Standard Tag Library

  • 简介
JSTL*1.控制流程   if   for   switch   out2.处理字符串   String(方法)3.格式化(日期 时间)
需要下载两个外部的jar包jstl.jar   standard.jar

a.核心标签库

1.将两个.jar文件导入项目可以在工程内web文件夹的WEB-INF文件夹内创建自己的文件夹lib也可以直接将两个jar文件导入Tomcat中的lib文件夹
2.启动idea编辑器创建一个新的web工程设置新导入的jstl包关联
3.创建一个新的JSPJSP中描述一个头信息  目的是为了告知JSP有新的标签可以用<%@ taglib uri="http://java.sun.com/jsp/jstl/xxxx" prefix=""%>核心标签core   前缀c<c:out value=""></c:out>    可以写字符串   可以写表达式语言<c:if test=""></c:if>  表达式语言<c:choose><c:when test=""></c:when><c:otherwise></c:otherwise></c:choose><c:forEach begin="1" end="5" step="1" varStatus="i">${i}<br>${i.index}<br></c:forEach><c:forEach begin="0" end="${requestScope.userList.size()}" step="1" items="${requestScope.userList}" var="user" varStatus="i">${i.index}--${user}<br></c:forEach><c:forEach var="user" items="${requestScope.userList}">${user}<br></c:forEach>只能遍历   数组  List集合  Set集合  Iterator  Enumeration<c:forEach var="xxx" items="${requestScope.Name}">${xxx}如果遍历map集合<c:forEach var="key" items="${requestScope.map.keySet()}">${requestScope.map.key}begin  end   step   varStatus(是一个对象  index属性索引)var    items<c:forTokens var="value" items="a-b-c"delims="-">

b.函数标签库

用来处理字符串可以理解为是以前Java中的String类常用方法1.需要在JSP上进行描述<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>2.通常在业务层已经处理掉了字符的所有信息  通常不怎么用3.写法与核心标签不太一样${fn:xxx()}

c.格式化标签库

用来处理日期  实现格式化可以理解为是以前的Date类型      SimpleDateFormat1.在JSP进行描述<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%>2.写法与之前的核心标签一样<fmt:xxx><fmt:formatDate value="${requestScope.date}" pattern="yyyy-MM-dd kk:mm:ss">

(3)自定义标签

a.自定义函数

1.自己描述一个类
2.类中描述自己的方法方法必须是静态的方法通常有返回值public class MyFunctions {public static int add(int a, int b) {return a + b;}}
3.配置一个"说明书"----->xxx.tld当前工程下web文件夹中的WEB-INF文件夹下创建一个新的xx.tld文件1.先描述两个重要的东西  uri   short-name<short-name>myFn</short-name><uri>http://www.duyiedu.com</uri><function><name>add</name><function-class>myfn.MyFunctions</function-class><function-signature>int add(int,int)</function-signature></function>
4.在JSP中声明头信息<%@ taglib uri="http://www.duyiedu.com" prefix="myFn"%>${myFn:add(99,900)}

b.自定义标签

每一个标签都是一个单独的类
1.创建一个类(用来描述一个标签)实现一个Tag接口  重写里面的方法
2.细致的看一下这些方法public void setPageContext(PageContext pageContext)、public void setParent(Tag parent)、两组对应的get/set  自己补全   并添加响应的私有属性还有一个单独的release方法   回收对象doStartTagdoEndTag
3.在两个方法内添加自己的逻辑
4.描述一个"说明书" tld先描述uri和short-name<short-name>myTag</short-name><uri>http://www.duyiedu.com/myTag</uri>再描述标签及标签内部的属性<tag><name>out</name><tag-class>mytag.MyOut</tag-class><body-content>JSP</body-content><attribute><name>value</name><required>true</required><rtexprvalue>true</rtexprvalue></attribute></tag>
5.创建JSP  声明头信息

5.文件上传

(1)简介

文件上传
1.本质 : I/O读写客户端(浏览器)发送文件    HTTP协议    文件的内容写出去   客户端本地输入流  内容   网络输出流服务器(Web容器)接受文件    协议文件的内容读过来    网络输入流   内容    服务器本地输出流
2.可以使用别人写好的包来进行文件上传常用的是apache组织提供的一个包commons-fileupload.jarcommons-io.jar去官方网站下载www.apache.org下拉至最下面  点击commons选择下载fileupload和io

(2)浏览端配置

1.写一个jsp/html做展示(选择某一个文件)
2.必须通过表单提交
3.必须使用post方式规定:ServletFileUpload类中一个属性  post字节数:get没有限制,肯定通过URL拼串儿每一个不同浏览器对于URL处理长度有所不同IE 2048+35  IE 4076Google  8182    FireFox 65535Safari   80000    Opera 190000post没有限制,需要web容器的支持,跟容器的处理性能有关比如Tomcat,没有限制,可以通过配置文件server.xml   <Connector port="8080" maxPostSize="0">
4.以前的表单只有两个属性  action  method="post"如果想要做文件上传  表单中必须再添加一个属性enctype="multipart/form-date"
5.必须使用<input type="file">通过这个组件让用户选择上传的文件不仅仅能得到文件名   将文件的内容读出来

(3)服务端配置

1.引入文件上传需要的jar包commons-fileupload-1.4.jarcommons-io-2.6.jar
2.使用一个DiskFileItemFactory对象DiskFileItemFactory factory = new DiskFileItemFactory();使用一个ServletFileUpload对象   包含一个factoryServletFileUpload upload = new ServletFileUpload(factory);使用upload对象解析request   得到一个List<FileItem>List<FileItem> itemList = upload.parseRequest(request);
3.自己的业务逻辑通过遍历集合可以获取每一个item元素FileItem item 元素可能是一个普通组件   可能是一个文件item.isFormField();方法可以判断是否是一个普通文件如果item是一个普通的组件注意:不能用原生的方式获取参数request.getParameter();使用如下方式获取String = item.getFieldName();获取组件的name属性String = item.getString();获取组件的value属性注意:不能使用原生的方式处理中文request.setCharacterEncoding();使用如下方式处理String value = item.getString("UTF-8");如果item判断后是一个文件获取真实文件名item.getName();读取文件的内容item.getInputStream();    item.write(File file);
4.配置文件大小产生临时文件   为了防止丢包默认情况下存在tomcat的temp文件夹中factory.setSizeThreshold(1024000); //设置缓冲区大小      默认10240factory.setRepository(new File("路径"));  //设置缓冲区位置还可以设置上传文件本身的大小upload.setFileSizeMax();       //单个上传文件的大小 1Mupload.setSizeMax();      //上传文件的总大小      3M
  • 监督文件上传的进度

    upload.setProgressListener(new ProgressListener(){public void update(long l, long l1, int i) {//  第一个参数表示 已经上传的字节个数   4096个字节//  第二个参数表示 上传文件的总字节数//  第三个参数表示 正在上传第几个组件System.out.println("正在上传第"+i+"个组件,已经上传"+((((double)l/(double)l1)*100))+"%");try {Thread.sleep(300);} catch (InterruptedException e) {e.printStackTrace();}}
    });
    

(4)小结

小总结文件上传需要注意的事情1.浏览器端需要满足三个条件 form表单    post请求     enctype属性    file组件(多个)2.服务器端需要满足      factory工厂对象    upload对象    解析request方法   List<FileItem>3.上传文件保存的路径放在一个固定的位置D://test   可移植性不好放在当前工程的根目录下String path = this.getServletContext().getRealPath("/");根目录4.最好限制一下文件上传的大小 单个   总体   缓冲区5.如果文件上传出现文件名冲突的问题?原来名字+用户+时间.原来后缀1_zzt_date.jpg用一个随机产生的名字当做保存在服务器中的文件名1.jpg--->xxxxx.jpg        1   xxxxx    路径    用户   上传时间一个随机名字创建一个文件夹1.jpg放在文件夹里        用户   路径   文件夹名6.有些时候可能上传的文件需要控制类型自己设计一个方法

6.文件下载

(1)简介

5.文件下载浏览器端   发送请求的按钮<a href="download?fileName=xxxx"></a>服务器端1.接受需要下载的文件名2.找到文件并创建输入流读取内容3.处理一下响应时的中文字符4.设置响应内容类型和状态5.response创建输出流将内容响应回浏览器

(2)代码实现

//1.获取请求传递的文件名
req.setCharacterEncoding("UTF-8");
String fileName = req.getParameter("fileName");
//2.通过fileName找到一个服务器中的真实文件(固定位置,当前工程内部)
//找到文件需要一个输入流读取文件中的内容
InputStream inputStream = new FileInputStream("D://upfile/" + fileName);
//3.如果文件名还有中文,通过以下方式处理
fileName = URLEncoder.encode(fileName, "UTF-8");
//4.设置响应的contentType
//String atta = FileUploadBase.ATTACHMENT;  //静态常量
resp.setContentType("application/x-msdownload");
resp.setHeader("Content-disposition", "attachment;fileName=" + fileName);
//5.将内容响应回浏览器
OutputStream outputStream = resp.getOutputStream();
byte[] b = new byte[1024];
int length = inputStream.read(b);
while (length != -1) {outputStream.write(b, 0, length);outputStream.flush();length = inputStream.read(b);
}

7.Filter

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-z7UtzQ98-1616603856891)(我的程序员笔记.assets/1616602064733.png)]

(1)基本使用

Filter过滤器1.是Tomcat提供的一个组件2.他是一个特殊的Servlet特殊在可以放行   有一个多的参数FilterChain3.基本使用自己创建一个类继承HttpFilter(Tomcat9以后的)      Tomcat9之前 直接实现Filter接口重写方法doFilter             init     doFilter     destroydoFilter方法中有三个参数    HttpServletRequest   HttpServletResponse   FilterChain可以抛出两个异常  ServletException   IOException配置web.xml    4.基本的使用用户认证事务的处理字符集处理

(2)管理机制

继承或实现的关系接口Serializable序列化接口接口FilterConfiggetFilterName();getServletContext();String value = getInitParameter("key");Enumeration = getInitParameterNames();接口Filterdefault void init(FilterConfig filterConfig) throws ServletException {}void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;default void destroy() {}抽象的父类GenericFilter目的是一个缺省适配器模式将大部分的抽象方法都添加了实现还增加了init方法重载抽象的父类HttpFilter做一个参数类型的转化  将无协议的参数强制转化成Http协议的参数我们自己写的类对象的创建    生命周期filter对象是一个单例的filter对象的单例模式   采用生命周期托管的方式实现的filter对象是一个立即加载的方式    不能通过配置load-on-startup来进行修改生命周期也可以通过init   doFilter   destroy方法重写看

(3)链的执行

1.Filter拦截请求处理请求     直接给予响应    转发    重定向    放行浏览器出发的请求会经过Filter服务器内部的请求转发  请求重定向   是否会经过Filter从浏览器发送出来的请求都会经过filter  前提是配置从服务器发送出来的请求转发forward   默认是不经过filter的从服务器发送出来的请求重定向sendRedirect   是经过filter的如果是同一次请求    默认是不经过filter如果是一次新请求    是经过filter如果想要让所有的请求都经过filter过滤做一个xml配置<filter><filter-name>one</filter-name><filter-class>filter.FilterOne</filter-class><init-param><param-name>key</param-name><param-value>value</param-value></init-param></filter><filter-mapping><filter-name>one</filter-name><url-pattern>/*</url-pattern><dispatcher>REQUEST</dispatcher><dispatcher>FORWARD</dispatcher></filter-mapping>2.Filter处理请求好多真实资源之前的一个操作    用户认证通常拦截pattern    /*      *.xxx多个filter都匹配同一个pattern   执行顺序?多个filter都会执行看起来是按照我们的web.xml的配置顺序来执行????

(4)责任链模式

  • 过滤器链

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NS1Oz2Fx-1616603856892)(我的程序员笔记.assets/1616602519099.png)]

  • 请求与转发和链的关系

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZVp2n25C-1616603856893)(我的程序员笔记.assets/1616602592414.png)]

  • 链表与责任链模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A3wTrDi8-1616603856894)(我的程序员笔记.assets/1616602641944.png)]

 链表结构Node类(节点)   每一个对象 管理一个值0.属性    Node    prev   (找到上一个责任人在哪里)1.属性    Object  value  (存值)2.属性    Node    next   (找到下一个责任人在哪里)过滤器链(责任链设计模式)Chain of Responsbility PatternFilter类    每一个filter对象  管理当前filter做的事情doFilter方法

(5)小结

 1.Filter    Tomcat提供的一个组件2.Filter是一个特殊的Servlet3.基本使用创建一个类    继承HttpFilter(Tomcat9之后)   实现Filter接口(Tomcat9之前)重写方法doFilter方法三个参数HttpServletRequest   HttpServletResponse   FilterChain配置xml文件4.管理机制继承或实现的关系filter对象是单例   生命周期托管的方式   立即加载的方式发送请求   从浏览器出发   会经过filter从服务器内部出发   转发默认是不经过filter(设置)   重定向经过filter5.过滤器链好多个filter对象    都处理相同的请求  /*我们经过filter不是目的   找到真实的资源经过的filter会在真实资源执行之前做些事情   之后也会做事情

8.Listener

Listener监听器  (观察者设计模式)
1.监听域对象产生和销毁的
2.监听域对象存值  修改  删除request   session   applicationsetAttribute();   removeAttribute();3.自定义类实现接口:ServletRequestListenerServletRequestAttributeListenerHttpSessionListenerHttpSessionAttributeListenerServletContextListenerServletContextAttributeListener
4.配置web.xml文件<listener><listener-class>listener.TestRequestListener</listener-class></listener><listener><listener-class>listener.TestSessionListener</listener-class></listener>
5.什么场景用
在线人数  监听session对象产生 销毁

9.XML

(1)DTD规则

XMLEXtensible  Markup  Language可扩展标记(标签)语言创建这个XML的宗旨不是为了HTML进行扩展  关注的非展示更多的是关注数据的存储和传输---->关注的是数据存储和传输1.写法创建一个文件   .xml建议在文件的第一行   头信息<?xml  version="1.0" encoding="UTF-8" >2.规则结构良好的     有规则  标签对应 <xxx></xxx>结构有效的      在结构良好的基础上遵循很多规则(写什么标签 名字叫什么 属性叫什么 几个 顺序)如果想要让写完的xml遵循结构有效的需要单独再写一个xml文件--->用来描述规则(类似元注解的作用).tld   Tag  Library  Definition  用来描述标签的.dtd  Document  Type  Difinition 文档类型描述.xsd  Xml  Schema  Definition   用来描述xml文档内容.xml  eXtensible  Markup  Language   用来存储数据的文档3.基本xml文件写法为了让xml文件中的内容遵循某些规则自定义dtd第一可以写在当前的xml文件中第二可以写在一个外部的文件中  引入描述根标记<!DOCTYPE school [规则]>描述根标记中的其他标记<标签><!ELEMENT 元素名 类别|(元素里面的内容) >类别  通常是EMPTY元素内容  (其他标签,其他标签)标签内部没有标签  是普通的文字    PCDATAPCDATA    Parsed  Character  DATA(通常用来描述标签中间的文字<>xxx<>)可以被解析的字符数据   支持实体  &xxx;  &gt;大于   &lt;小于   &amp;与符号   &quot;双引号   &apos;单引号正常情况下 描述标签内部的子标签时候  默认认为是一个还需要在子标签基础上增加一个  对于个数的说明*符号    0-n个    ?符号  0-1个   +符号  1-n个,符号  都有    |符号  a或b其中的一个每一个标记中还需要有属性<!ATTLIST>   attribute list<!ATTLIST 标签名 属性名 什么类型 值>通常类型的描述CDATA   Character DATA 原封不动 (通常用来描述属性名)(t1|t2|t3) 来描述通常值的描述默认值  "xxx"值的说明  (是否是必须 固定的。。)#REQUIRED必须   #IMPLIED非必需   #FIXED value固定的如果想要描述实体<!ENTITY 实体名字 "实体的值"><!ENTITY spring "this is spring"><div>&spring;</div><!--外部引入-->
<!DOCTYPE school SYSTEM "myxml.dtd"><!--内部配置-->
<!--<!DOCTYPE school [-->
<!--        <!ELEMENT school (class*)>-->
<!--        <!ELEMENT class (teacher*,student*)>-->
<!--        <!ELEMENT teacher (sex*)>-->
<!--        <!ELEMENT student (sex*)>-->
<!--        <!ELEMENT sex (#PCDATA)>-->
<!--        <!ATTLIST school-->
<!--                id CDATA #IMPLIED-->
<!--                name CDATA #IMPLIED-->
<!--                loc CDATA #IMPLIED-->
<!--        >-->
<!--        <!ATTLIST class-->
<!--                id CDATA #IMPLIED-->
<!--                name CDATA #IMPLIED-->
<!--                loc CDATA #IMPLIED-->
<!--        >-->
<!--        <!ATTLIST teacher-->
<!--                id CDATA #IMPLIED-->
<!--                name CDATA #IMPLIED-->
<!--                age CDATA #IMPLIED-->
<!--        >-->
<!--        <!ATTLIST student-->
<!--                id CDATA #IMPLIED-->
<!--                name CDATA #IMPLIED-->
<!--                age CDATA #IMPLIED-->
<!--        >-->
<!--        <!ENTITY spring "this is spring">-->
<!--]>-->
 XMLEXtensible  Markup  Language扩展标记语言<><>更多的关注数据的存储和传输  HTML(关注展示)结构良好的    遵循标签的结构  成对出现  满足嵌套  标签名字随意结构有效的   在结构良好的基础上   遵循很多规则用来定义规则的也是一个xml形式的文件     dtd   xsd    tld(定义标签)描述一个dtd规则创建一个文件   普通的xml  想要记录数据数据基础上添加一个规则   写在xml文件的里面   写在另一个xml文件中 引入<!DOCTYPE 根标记 [规则]><!DOCTYPE 根标记 SYSTEM/PUBLIC "文件"><!ELEMENT 标签名 类型><!ELEMENT 标签名 (子标签*,子标签?,子标签+)>通配符不是必须    +(1-n)   ?(0-1)   *(0-n)<!ATTLIST 标签名 属性名 类型 值><!ENTITY 实体名字 "值">   &实体名字;

(2)DOM解析XML文件

  • 简介
解析XML文件内容本质就是文件内容的读取Input解析XML文件两种方式DOM解析(Document Object Model)树结构处理方式将文档全部解析  形成一个树结构   节点---标签优点  编程容易  缺点 必须将整个文档全部处理完毕(慢)SAX解析(Simple Api for Xml)-----扩展类似流媒体方式基于事件的模式  解析时候触发一系列事件当某一个tag标签被解析的时候  激活后续的方法优点 快(不需要将所有文档都一次性处理完)缺点 编写很麻烦(复用性也不强)JDOM(Java-based Document Object Model)外部jar包  基于DOM方式 底层提升了性能DOM4J(Document Object Model for Java)外部jar包  基于JDOM方式 底层提升了性能
  • 代码实现
package testxml;import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.InputStream;public class Dom {public static void main(String[] args) {try {//采用DOM方式//1.需要一个工厂(建造工人)DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();//2.利用工厂创建工人DocumentBuilder builder = factory.newDocumentBuilder();//3.工人创建一个document对象(需要一张图纸 xml文件)File file = new File("src/testxml/school.xml");//InputStream inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("textxml/school.xml");Document document = builder.parse(file);//4.解析xml文件//获取根标签对象(school)//方式一Element school = document.getDocumentElement();//方式二//            Element school = document.getElementById("duyi"); //需要dtd规则//方式三//            NodeList rootList = document.getElementsByTagName("school");//            Element school = rootList.item(0);//school标签中的属性String schoolId = school.getAttribute("id");String schoolName = school.getAttribute("name");String schoolLoc = school.getAttribute("loc");System.out.println(schoolId + "--" + schoolName + "--" + schoolLoc);//school标签中的子标签//方式一NodeList classList = document.getElementsByTagName("class");//方式二//            NodeList classList = school.getElementsByTagName("class");//方式三//            NodeList classList = school.getChildNodes();for (int i = 0; i < classList.getLength(); i++) {Element classElement = (Element) classList.item(i);String classId = classElement.getAttribute("id");String className = classElement.getAttribute("name");String classLoc = classElement.getAttribute("loc");System.out.println("\t" + classId + "--" + className + "--" + classLoc);//class标签的子标签 teacher//方式一Element teacher = (Element) classElement.getElementsByTagName("teacher").item(0);//方式二//Element teacher = (Element) classElement.getFirstChild();//需要有dtd规则String teacherId = teacher.getAttribute("id");String teacherName = teacher.getAttribute("name");String teacherAge = teacher.getAttribute("age");Element sex = (Element) teacher.getElementsByTagName("sex").item(0);String teacherSex = sex.getTextContent();System.out.println("\t\t" + teacherId + "--" + teacherName + "--" + teacherAge + "--" + teacherSex);//class标签的子标签 studentNodeList studentList = classElement.getElementsByTagName("student");for (int j = 0; j < studentList.getLength(); j++) {Element student = (Element) studentList.item(j);String studentId = student.getAttribute("id");String studentName = student.getAttribute("name");String studentAge = student.getAttribute("age");sex = (Element) student.getElementsByTagName("sex").item(0);String studentSex = sex.getTextContent();   //获取标签中的文本内容System.out.println("\t\t" + studentId + "--" + studentName + "--" + studentAge + "--" + studentSex);}}} catch (Exception e) {e.printStackTrace();}}
}

(3)JDOM和DOM4解析XML文件

  • JDOM实现
public class JDOM {public static void main(String[] args){try {System.out.println("以JDOM形式进行解析 需要一个jdom.jar外部包");//获取builder对象   自己创建SAXBuilder builder = new SAXBuilder();File file = new File("src/testxml/school.xml");//工人创建document对象Document document = builder.build(file);//读取school.xml中的根标记  schoolElement school = document.getRootElement();//获取school标签中的属性String schoolID = school.getAttributeValue("id");String schoolName = school.getAttributeValue("name");String schoolLOC = school.getAttributeValue("loc");System.out.println(schoolID+"--"+schoolName+"--"+schoolLOC);//获取school标记的子元素 好几个classList<Element> classList = school.getChildren("class");for(Element classEle : classList){//获取classEle中的属性String classID = classEle.getAttributeValue("id");String className = classEle.getAttributeValue("name");String classLOC = classEle.getAttributeValue("loc");System.out.println("\t"+classID+"--"+className+"--"+classLOC);//获取class中的子元素 teacherElement teacher = classEle.getChild("teacher");String teacherID = teacher.getAttributeValue("id");String teacherName = teacher.getAttributeValue("name");String teacherAge = teacher.getAttributeValue("age");Element teacherSexEle = teacher.getChild("sex");String teacherSex = teacherSexEle.getText();System.out.println("\t\t"+teacherID+"--"+teacherName+"--"+teacherAge+"--"+teacherSex);//获取class中的子元素 好多studentList<Element> studentList = classEle.getChildren("student");for(Element student : studentList){String studentID = student.getAttributeValue("id");String studentName = student.getAttributeValue("name");String studentAge = student.getAttributeValue("age");String studentSex = student.getChildText("sex");System.out.println("\t\t"+studentID+"--"+studentName+"--"+studentAge+"--"+studentSex);}}} catch (Exception e) {e.printStackTrace();}}
}
  • DOM4J解析
public class DOM4J {public static void main(String[] args){try {System.out.println("利用DOM4J形式解析 需要以来外部dom4j.jar");//创建一个解析对象SAXReader reader = new SAXReader();//理解为是之前的builder对象//提供一个文件File file = new File("src/testxml/school.xml");//让解析对象读取file并产生一个document对象Document document = reader.read(file);//获取根元素Element school = document.getRootElement();//获取school中的属性String schoolID = school.attributeValue("id");String schoolName = school.attributeValue("name");String schoolLOC = school.attributeValue("loc");System.out.println(schoolID+"--"+schoolName+"--"+schoolLOC);//获取school中的子元素 classList<Element> classList = school.elements("class");for(Element classEle : classList){//获取class中的属性String classID = classEle.attributeValue("id");String className = classEle.attributeValue("name");String classLOC = classEle.attributeValue("loc");System.out.println("\t"+classID+"--"+className+"--"+classLOC);//获取class中的子元素(一个teacher)Element teacher = classEle.element("teacher");String teacherID = teacher.attributeValue("id");String teacherName = teacher.attributeValue("name");String teacherAge = teacher.attributeValue("age");Element teacherSexEle = teacher.element("sex");String teacherSex = teacherSexEle.getText();System.out.println("\t\t"+teacherID+"--"+teacherName+"--"+teacherAge+"--"+teacherSex);//获取class中的子元素(好多student)List<Element> studentList = classEle.elements("student");for(Element student : studentList){String studentID = student.attributeValue("id");String studentName = student.attributeValue("name");String studentAge = student.attributeValue("age");String studentSex = student.elementText("sex");System.out.println("\t\t"+studentID+"--"+studentName+"--"+studentAge+"--"+studentSex);}}} catch (Exception e) {e.printStackTrace();}}
}

(9)Session

(10)Cookie

(11)ThreadLocal

(12)WEB注解

(13)AJAX

(14)JSON

五、JQuery

六、算法

七、MyBatis

八、Spring

九、SpringMVC

十、Maven

十一、Git-SVN

十二、SpringBoot

十三、模板引擎

十四、数据库连接池

十五、Redis

十六、Linux

十七、Nginx

十八、Structs2

十九、Hibernate

二十、Netty

二十一、Dubbo

二十二、设计模式

一共有23种设计模式

1.创建型模式(5种)---->用于解决对象的创建的过程
单例模式,工厂方法模式,抽象工厂模式,建造者模式,原型模式

2.结构性模式(7种)---->把类或对象通过某种形式结合在一起,构成某种复杂或合理的结构
适配器模式,装饰者模式,代理模式,外观模式,桥接模式,组合模式,享元模式

3.行为性模式(11种)---->用来解决类或对象之间的交互,更合理的优化类或对象之间的关系
观察者模式,策略模式,模板模式,责任链模式,解析器模式,迭代子模式,
命令模式,状态模式,备忘录模式,访问者模式,中介者模式

Java_Web笔记汇总_火热更新中。。。相关推荐

  1. while循环中指针会自动释放吗_C++】C++常见面试题汇总_持续更新中...

    1:指针(*).引用(&).解引用(*).取地址(&).的概念和区别 概念: 指针指向一块内存,指针保存的是内存的地址:引用是变量的别名,本质是引用该变量的地址. 解引用是取指针指向的 ...

  2. Cisco 产品下载链接汇总 2023 持续更新中

    Cisco 产品链接汇总 2023 持续更新中 IOS-XE, IOS-XR, NX-OS & FXOS based on linux kernel 请访问原文链接:https://sysin ...

  3. 有关树的常见算法汇总【持续更新中】

    关于数据结构中--树的算法汇总[持续更新中] 0.树的顺序和链式存储结构 [完成] 1.树的前序遍历(递归和非递归java实现) [完成] 2.树的中序遍历(递归和非递归java实现) [完成] 3. ...

  4. 软件工程毕业设计 题目汇总 【不断更新中】

    软件工程毕业设计 题目汇总 [不断更新中] 微信小程序 校园表白墙微信小程序  [地址:程序地址] 房屋租赁管理系统 [地址:程序地址] 航空售票管理系统 高校会议室管理系统 高校就业管理系统 失物招 ...

  5. 《LeetCode 热题 HOT 100》Java答案汇总版---持续更新中

    <LeetCode 热题 HOT 100>Java答案汇总版-持续更新中 个人认为<LeetCode 热题 HOT 100>中的题目特别适合算法新手进行一个入门的刷题,而且作者 ...

  6. 清华2021计算机学院复试,清华大学2021年硕士研究生复试名单汇总(持续更新中)...

    清华大学2021年硕士研究生复试名单汇总已出来,下面金程考研小编整理了:清华大学2021年硕士研究生复试名单汇总 (持续更新中),希望对同学有帮助~ 加小助手微信(备注网校)jckyyxm领取历年考研 ...

  7. 开源工业缺陷数据集汇总,持续更新中(已更新28个)

    欢迎大家关注我的公众号:一刻AI 本文目前汇总了常见的28个开源工业缺陷数据集,持续更新中 (欢迎大家留言补充,共同建设一个为大家提供便利的文章) 东北大学热轧带钢表面缺陷数据集 官方链接:Visio ...

  8. C++学习资源汇总(持续更新中)

    以下收集汇总一些C++的学习资料(持续更新中) 网站和论坛: http://www.csdn.net/ http://www.iteye.com/ http://www.bccn.net/  编程中国 ...

  9. STM32 之十五 奇怪问题处理及驱动库 BUG 汇总(持续更新中)

      在使用 STM32 的 MCU 开发过程中,难免遇到各种各样的奇葩问题.或许是开发环境的问题,或许是 MCU 使用的问题,也或许是驱动库的 BUG 等等.这些问题可能不局限于某一种具体型号的 MC ...

最新文章

  1. 跟随光标下划线导航插件
  2. python做算法题优势_Python语言在科学算法中的优势
  3. t oracle删除吗,Oracle 11g 手工建库与删库
  4. python滚动条变小,python处理滚动条
  5. 3s新闻周刊第9期,本期策划:电子地图的出路
  6. 中国水银矿石行业市场供需与战略研究报告
  7. python dll注入监听_DLL注入和API拦截
  8. win10 html字体设置,IT之家学院:如何解决Win10屏幕字体缩放模糊问题
  9. Navicat Premium 注册出现 No All Pattern Found! File Already Patched 处理方法(亲测有效)
  10. python微信刷屏_微信偷偷更新,这功能彻底没了
  11. c语言求自然数1 10之和,C程序计算自然数之和
  12. 2017暴雪php,动视暴雪2017Q4财报 开启全新里程碑
  13. 痞子衡嵌入式:我被邀请做贸泽电子与非网联合推出的《对话工程师》节目嘉宾...
  14. SQL 两行两列显示一行四列或一行两列
  15. 啊哈添柴挑战Java1016. 反向输出一个三位数
  16. 【Android 系统】--- 下载 Android源码
  17. 关于xpe和wes2009
  18. 关联分析(Apriori算法) 面包 牛奶 尿布 啤酒 ...
  19. Remove Duplicate
  20. 分析ERP在中小企业中的应用(最新市场洞析)

热门文章

  1. 学生买蓝牙耳机多少钱?平价蓝牙耳机排行榜10强!
  2. 原生js-购物车案例(三)已选商品添加和删除
  3. BigDecimal精度丢失问题
  4. 【学员心得】如何三招通关云计算HCIE认证
  5. 手动搭建webpack5 + ts + vue3项目
  6. 求整数的位数及各位数字之和
  7. 从普通程序员到身价过百亿:追求长期价值的耐心,决定了你能走多远 原
  8. W ndows7有线网络连接,七仔教你学Windows7:如何连接网络 爱问知识人
  9. 软件工程与实践(第3版)课后习题(二)
  10. 一学就会的无代码RPA,让“高效”成为你的竞争优势