学习目标及进程

1.工具的统一

mysql,idea 2019.2 ,tomcat 8 ,jdk 1.8

2.学习内容

java基础语法(变量,结构化,oop) java内存模型 java数据结构 jdbc jsp/servlet

3.学习资料

学习文档 学习视频推荐 基础代码一份 项目代码一份 开发工具

4.学习笔记

有道云

5.项目验收

学籍管理系统: https://blog.csdn.net/qq_37787333/article/details/83541909

实现登录,学籍crud即可

6.学习进度 第一周 java基础语法 java内存模型 java数据结构 基础代码敲一遍 第二周 jdbc jsp/servlet

完成项目编写 https://blog.csdn.net/u014653854/article/details/937642

java学习笔记

一.java安装

1.下载安装

http://ftp-new-pc.pconline.com.cn/e8107d13d2cca79e80d5d69abb54a5dc/pub/download/201903/pconline1552198052014.zip

2.环境变量配置

用户变量->新建->JAVA_HOME->C:\Program Files\Java\jdk1.8.0_181

用户变量->编辑PATH->添加->%JAVA_HOME%\bin

​ ->%JAVA_HOME%\jre\bin

用户变量->新建->CLASSPATH->%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar

二.apache-tomcat安装

1.下载安装

http://mirror.bit.edu.cn/apache/tomcat/tomcat-8/v8.5.43/bin/apache-tomcat-8.5.43-windows-x64.zip

2.环境变量配置

用户变量->新建->CATALINA_HOME->D:\wnmp\apache-tomcat-8.5.43

用户变量->编辑PATH->添加->%CATALINA_HOME%\bin

​ ->%CATALINA_HOME%\lib

3.安装服务

cd D:\wnmp\apache-tomcat-8.5.43\bin

​ ./service.bat install

三.java运行原理及过程

1.Java程序运行原理

在Java中引入了虚拟机(JVM,Java Virtual Machine)的概念,即在机器和编译程序之间加入了一层抽象的虚拟的机器。虚拟机在任何平台上都提供给编译程序一个的共同的接口。

编译程序只需要面向虚拟机,生成虚拟机能够理解的字节码(ByteCode)(class文件的内容),然后由解释器来将虚拟机代码转换为特定系统的机器码执行,每一种平台的解释器是不同的,但是实现的虚拟机是相同的。

Java源程序经过编译器编译后变成字节码,字节码由虚拟机解释执行,虚拟机将每一条要执行的字节码送给解释器,解释器将其翻译成特定机器上的机器码,然后在特定的机器上运行。

java编译器 (javac)(编译) → 虚拟机(jvm)(解释执行) → 解释器(翻译) → 机器码

2.Java程序运行过程

1).创建 HelloWorld.java文件

public class HelloWorld {

​ public static void main(String[] args) {

​ System.out.println(“Hello World”);

​ }

}

2).在命令行中输入以下代码

javac HelloWorld.java

java HelloWorld

Hello World #输出的内容

3).ide中完成编写代码,运行即可输出内容

3. JDK、JRE、JVM三者间的关系

JDK(Java Development Kit)是针对Java开发员的产品,是整个Java的核心,包括了Java运行环境JRE、Java工具和Java基础类库。

JRE(Java Runtime Environment)是运行JAVA程序所必须的环境的集合,包含JVM标准实现及Java核心类库。

JVM(Java Virtual Machine)(Java虚拟机)是整个java实现跨平台的最核心的部分,能够运行以Java语言写作的软件程序。

JDK中包含JRE,在JDK的安装目录下有一个名为jre的目录,里面有两个文件夹bin和lib,在这里可以认为bin里的就是jvm,lib中则是jvm工作所需要的类库,而jvm和 lib和起来就称为jre。  

SE(J2SE),standard edition,标准版,是我们通常用的一个版本,从JDK 5.0开始,改名为Java SE。

EE(J2EE),enterprise edition,企业版,使用这种JDK开发J2EE应用程序,从JDK 5.0开始,改名为Java EE。

ME(J2ME),micro edition,主要用于移动设备、嵌入式设备上的java应用程序,从JDK 5.0开始,改名为Java ME。

三.java基础知识

1.基础语法

大小写敏感:Java 是大小写敏感的,这就意味着标识符 Hello 与 hello 是不同的。

类名:对于所有的类来说,类名的首字母应该大写。如果类名由若干单词组成,那么每个单词的首字母应该大写,例如 MyFirstJavaClass

方法名:所有的方法名都应该以小写字母开头。如果方法名含有若干单词,则后面的每个单词首字母大写。

源文件名:源文件名必须和类名相同。当保存文件的时候,你应该使用类名作为文件名保存(切记 Java 是大小写敏感的),文件名的后缀为 .java。(如果文件名和类名不相同则会导致编译错误)。

主方法入口:所有的 Java 程序由 public static void main(String []args) 方法开始执行。

2.变量

1).命名:

由字母、数字、下划线、$组成,不能以数字开头(注意:此处的字母还可以是中文,日文等)

大小写敏感

不得使用java中的关键字和保留字

别用Java API里面的类名作为自己的类名。

2).基本类型

char、boolean、byte、short、int、long、float、double

注意:单双引号不同

常量

final double PI = 3.1415927;

3).变量作用域

类变量(静态变量):独立于方法之外的变量,用 static 修饰。

实例变量:独立于方法之外的变量,不过没有 static 修饰。

局部变量:类的方法中的变量,使用前必须初始化值。

4).变量操作

算术运算符(+ 、— 、* 、/ 、%)

赋值运算符(= 、+=、-=、*=、/=,、%=)

关系运算符(>、>=、<、<=、!=)

条件运算符(&&、||、!&、|、^)

位运算符(&、|、^、~、»、«、«<、»>)

三目运算符(x ? y : z)

5).变量转换

小转大,自动!自动类型转换(也叫隐式类型转换)

大转小,强转!强制类型转换(也叫显式类型转换)

3.结构化

1).顺序结构

2).选择结构

if(条件表达式){

​ 执行语句;

}else if (条件表达式){

​ 执行语句;

}else{

​ 执行语句;

}

switch(expression){

​ case value :

​ //语句

​ break; //可选

​ case value :

​ //语句

​ break; //可选

​ //你可以有任意数量的case语句

​ default : //可选

​ //语句

}

3).循环结构

while(条件表达式值为true)

{

​ 执行语句;

}

do{

​ 执行语句;

}while(条件表达式值为true);

for(初始化表达式(1);循环条件表达式(2);循环后的操作表达式(3))

{

​ 执行语句;(4)

}

**4.**修饰符

**1).**访问控制修饰符

default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。

private : 在同一类内可见。使用对象:变量、方法。 注意:不能修饰类(外部类)

public : 对所有类可见。使用对象:类、接口、变量、方法

protected : 对同一包内的类和所有子类可见。使用对象:变量、方法。 注意:不能修饰类(外部类)

2).访问控制和继承

父类中声明为 public 的方法在子类中也必须为 public。

父类中声明为 protected 的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private。

父类中声明为 private 的方法,不能够被继承。

3).static 修饰符

**静态变量:**无论一个类实例化多少对象,它的静态变量只有一份拷贝。 静态变量也被称为类变量。局部变量不能被声明为 static 变量。

**静态方法:**静态方法不能使用类的非静态变量。静态方法从参数列表得到数据,然后计算这些数据。

4).final 修饰符

**final 变量:**final 表示"最后的、最终的"含义,变量一旦赋值后,不能被重新赋值。被 final 修饰的实例变量必须显式指定初始值。final 修饰符通常和 static 修饰符一起使用来创建类常量。

final 方法: 类中的 final 方法可以被子类继承,但是不能被子类修改。声明 final 方法的主要目的是防止该方法的内容被修改。

5).abstract 修饰符

**抽象类:**抽象类不能用来实例化对象,声明抽象类的唯一目的是为了将来对该类进行扩充。

一个类不能同时被 abstract 和 final 修饰。如果一个类包含抽象方法,那么该类一定要声明为抽象类,否则将出现编译错误。

抽象方法: 抽象方法是一种没有任何实现的方法,该方法的的具体实现由子类提供。

抽象方法不能被声明成 final 和 static。

5**.对象和类**

对象:对象是类的一个实例(对象不是找个女朋友),有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。

:类是一个模板,它描述一类对象的行为和状态。

public class Dog{

String breed;

int age;

String color;

public Dog(){

​ //构造方法的名称必须与类同名,一个类可以有多个构造方法

}

public Dog(String name){

​ // 这个构造器仅有一个参数:name

​ System.out.println(“小狗的名字是 : " + name );

}

void barking(){

​ System.out.println(“小狗是黑色的” );

}

public static void main(String[] args){

​ // 下面的语句将创建一个Dog对象

​ Dog myDog = new Dog( “tommy” );

​ /* 访问类中的变量 */

​ myDog.age;

​ /* 访问类中的方法 */

​ myDog.barking();

}

}

源文件声明规则

一个源文件中只能有一个public类

一个源文件可以有多个非public类

源文件的名称应该和public类的类名保持一致。例如:源文件中public类的类名是Employee,那么源文件应该命名为Employee.java。

如果一个类定义在某个包中,那么package语句应该在源文件的首行。

如果源文件包含import语句,那么应该放在package语句和类定义之间。如果没有package语句,那么import语句应该在源文件中最前面。

import语句和package语句对源文件中定义的所有类都有效。在同一源文件中,不能给不同的类不同的包声明。

5.String类

定义: String “strVar” 注意:只能用双引号

连接: 字符串 + 字符串 或 字符串.concat

长度: 字符串.length()

格式化: String.format() 或 System.out.printf()

6.数组

1).声明数组变量

dataType[] arrayRefVar; // 首选的方法 dataType arrayRefVar[]; // 效果相同,但不是首选方法

double[] myList; // 首选的方法

double myList[]; // 效果相同,但不是首选方法

2).创建数组

dataType[] arrayRefVar = new dataType[arraySize];

dataType[] arrayRefVar = {value0, value1, …, valuek};

public class TestArray {

public static void main(String[] args) {

​ // 数组大小

​ int size = 3;

​ // 定义数组

​ double[] myList = new double[size];

​ myList[0] = 5.6;

​ myList[1] = 4.5;

​ myList[2] = 3.3;

​ // 计算所有元素的总和

​ double total = 0;

​ for (int i = 0; i < size; i++) {

​ total += myList[i];

​ }

​ System.out.println(“总和为: " + total);

}

}

3).处理数组

数组长度: myList.length

循环: For-Each

public class TestArray {

public static void main(String[] args) {

​ double[] myList = {1.9, 2.9, 3.4, 3.5};

​ // 打印所有数组元素

​ for (double element: myList) {

​ System.out.println(element);

​ }

}

}

4). 数组作为函数的参数

####5).数组作为函数的返回值

6).多维数组

type[][] typeName = new type[typeLength1][typeLength2];

String s[][] = new String[2][];

s[0] = new String[2];

s[1] = new String[3];

s[0][0] = new String(“Good”);

s[0][1] = new String(“Luck”);

s[1][0] = new String(“to”);

s[1][1] = new String(“you”);

s[1][2] = new String(”!");

7).arrays类

java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的。

具有以下功能:

给数组赋值:通过 fill 方法。

对数组排序:通过 sort 方法,按升序。

比较数组:通过 equals 方法比较数组中元素值是否相等。

查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作。

public void useArraysUtil(){

​ int[] arrVar = new int[5];

​ Arrays.fill(arrVar,1);

​ printArray(arrVar);

​ int[] arrVar2 = {1,3,2,4,5};

​ Arrays.sort(arrVar2);

​ printArray(arrVar2);

}

7.方法

1).命名规则

方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符。例如:addPerson

2).方法的定义

修饰符 返回值类型 方法名(参数类型 参数名){

​ …

​ 方法体

​ …

​ return 返回值;

}

**修饰符:**修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型。

返回值类型 :方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void

**方法名:**是方法的实际名称。方法名和参数表共同构成方法签名。

**参数类型:**参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数。

**方法体:**方法体包含具体的语句,定义该方法的功能。

3).方法调用

public class TestMax {

/** 主方法 */

public static void main(String[] args) {

​ int i = 5;

​ int j = 2;

​ int k = sum(i, j);

​ System.out.println( k );

}

public static int sum(int num1, int num2) {

​ int result;

​ result = num1 + num2

​ return result;

}

}

4).可变参数(double… numbers)

public class VarargsDemo {

​ public static void main(String args[]) {

​ // 调用可变参数的方法

​ printMax(34, 3, 3, 2, 56.5);

​ printMax(new double[]{1, 2, 3});

​ }

​ public static void printMax( double… numbers) {

​ if (numbers.length == 0) {

​ System.out.println(“No argument passed”);

​ return;

​ }

​ double result = numbers[0];

​ for (int i = 1; i < numbers.length; i++){

​ if (numbers[i] > result) {

​ result = numbers[i];

​ }

​ }

​ System.out.println(“The max value is " + result);

​ }

}

8. Character类

char[] charArray ={ ‘a’, ‘b’, ‘c’, ’d', ‘e’ };

Character ch = new Character(‘a’);

转义字符:前面有反斜杠(\)的字符代表转义字符,它对编译器来说是有特殊含义的。

9. Number & Math 类

public class Test {

​ public static void main (String []args)

​ {

​ System.out.println(“90 度的正弦值:” + Math.sin(Math.PI/2));

​ System.out.println(“0度的余弦值:” + Math.cos(0));

​ System.out.println(“60度的正切值:” + Math.tan(Math.PI/3));

​ System.out.println(“1的反正切值: " + Math.atan(1));

​ System.out.println(“π/2的角度值:” + Math.toDegrees(Math.PI/2));

​ System.out.println(Math.PI);

​ }

}

10.日期时间

Date(long millisec)

import java.util.Date;

public class DateDemo {

public static void main(String args[]) {

​ // 初始化 Date 对象

​ Date date = new Date();

​ // 使用 toString() 函数显示日期时间

​ System.out.println(date.toString());

}

}

四.oop(面向对象)

###1.继承

1).什么是继承

将多段代码中相同的部分提取出来组成 一个父类,提高代码复用性,可维护性

2).继承的类型

单继承: B继承A

多重继承: C继承B,B继承A

不同类继承同一个类: B继承A,C继承A

多继承: 不支持

3).继承的特性

子类拥有父类非 private 的属性、方法。

子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。

子类可以用自己的方式实现父类的方法。

Java 的继承是单继承,但是可以多重继承,这是 Java 继承区别于 C++ 继承的一个特性。

提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。

4).继承的关键字

extends:类的继承是单一继承,也就是说,一个子类只能拥有一个父类,所以 extends 只能继承一个类

public class Animal { private String name; private int id; public Animal(String myName, String myid) { //初始化属性值 } public void eat() { //吃东西方法的具体实现 } public void sleep() { //睡觉方法的具体实现 } } public class Penguin extends Animal{ }

5). implements关键字

使用 implements 关键字可以变相的使java具有多继承的特性,使用范围为类继承接口的情况,可以同时继承多个接口(接口跟接口之间采用逗号分隔)。

public interface A {

​ public void eat();

​ public void sleep();

}

public interface B {

​ public void show();

}

public class C implements A,B {

}

6). super 与 this 关键字

super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。

this关键字:指向自己的引用。

class Animal {

void eat() {

​ System.out.println(“animal : eat”);

}

}

class Dog extends Animal {

void eat() {

​ System.out.println(“dog : eat”);

}

void eatTest() {

​ this.eat(); // this 调用自己的方法

​ super.eat(); // super 调用父类方法

}

}

7). final关键字

final 关键字声明类可以把类定义为不能继承的,即最终类;或者用于修饰方法,该方法不能被子类重写

声明类:final class 类名 {//类体}

声明方法:修饰符(public/private/default/protected) final 返回值类型 方法名(){//方法体}

8). 构造器

子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)

如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表。

如果父类构造器没有参数,则在子类的构造器中不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器。

2. 重写(Override)与重载(Overload)

1).重写(Override)

重写是子类对父类的允许访问的方法的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!

重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

2).方法的重写规则

参数列表必须完全与被重写方法的相同。

返回类型与被重写方法的返回类型可以不相同,但是必须是父类返回值的派生类(java5 及更早版本返回类型要一样,java7 及更高版本可以不同)。

访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为 public,那么在子类中重写该方法就不能声明为 protected。

父类的成员方法只能被它的子类重写。

声明为 final 的方法不能被重写。

声明为 static 的方法不能被重写,但是能够被再次声明。

子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。

子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。

重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者比被重写方法声明的更广泛的强制性异常,反之则可以。

构造方法不能被重写。

如果不能继承一个方法,则不能重写这个方法。

**3).**super调用父类的被重写方法,this调用重写后的方法

class Animal{

public void move(){

​ System.out.println(“动物可以移动”);

}

}

class Dog extends Animal{

public void move(){

​ super.move(); // 应用super类的方法

​ System.out.println(“狗可以跑和走”);

}

}

public class TestDog{

public static void main(String args[]){

​ Animal b = new Dog(); // Dog 对象

​ b.move(); //执行 Dog类的方法

}

}

4).重载(Overload)

重载(overloading) 是在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。

每个重载的方法(或者构造函数)都必须有一个独一无二的参数类型列表。

最常用的地方就是构造器的重载。

重载规则:

被重载的方法必须改变参数列表(参数个数或类型不一样);

被重载的方法可以改变返回类型;

被重载的方法可以改变访问修饰符;

被重载的方法可以声明新的或更广的检查异常;

方法能够在同一个类中或者在一个子类中被重载。

无法以返回值类型作为重载函数的区分标准。

public class Overloading {

​ public int test(){

​ System.out.println(“test1”);

​ return 1;

​ }

​ public void test(int a){

​ System.out.println(“test2”);

​ }

​ //以下两个参数类型顺序不同

​ public String test(int a,String s){

​ System.out.println(“test3”);

​ return “returntest3”;

​ }

​ public String test(String s,int a){

​ System.out.println(“test4”);

​ return “returntest4”;

​ }

​ public static void main(String[] args){

​ Overloading o = new Overloading();

​ System.out.println(o.test());

​ o.test(1);

​ System.out.println(o.test(1,“test3”));

​ System.out.println(o.test(“test4”,1));

​ }

}

5).重写与重载之间的区别

方法重载是一个类中定义了多个方法名相同,而他们的参数的数量不同或数量相同而类型和次序不同,则称为方法的重载(Overloading)。

方法重写是在子类存在方法与父类的方法的名字相同,而且参数的个数与类型一样,返回值也一样的方法,就称为重写(Overriding)。

方法重载是一个类的多态性表现,而方法重写是子类与父类的一种多态性表现。

3. 多态

**1).**多态是同一个行为具有多个不同表现形式或形态的能力

2).多态的实现方式

重写与重载

接口:多重继承

抽象类和抽象方法

4. 抽象类

1).抽象类定义:

如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类,不能实例化,抽象类必须被继承,并在子类中实现抽象方法

2).抽象方法定义:

抽象类中定义,子类中实现

如果一个类包含抽象方法,那么该类必须是抽象类。

抽象类中的抽象方法只是声明,不包含方法体

任何子类必须重写父类的抽象方法,或者声明自身为抽象类。

**3).抽象类&方法:**abstract定义,extends继承

public abstract class Employee

{

private String name;

private String address;

private int number;

public abstract double computePay();

}

public class Salary extends Employee

{

private double salary=104.00;

public double computePay()

{

​ System.out.println(“Computing salary pay for " + getName());

​ return salary/52;

}

}

5.封装

1).定义

是指一种将抽象性函式接口的实现细节部份包装、隐藏起来的方法。

封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。

要访问该类的代码和数据,必须通过严格的接口控制。

2).优点

\1. 良好的封装能够减少耦合。

\2. 类内部的结构可以自由修改。

\3. 可以对成员变量进行更精确的控制。

\4. 隐藏信息,实现细节。

3).实现:

使用修饰符去实现封装,public是外界访问的入口,private和protected是实现封装

public class Person{

​ private String name;

​ private int age;

​ public int getAge(){

​ return age;

​ }

​ public String getName(){

​ return name;

​ }

​ public void setAge(int age){

​ this.age = age;

​ }

​ public void setName(String name){

​ this.name = name;

​ }

}

6.接口

1).定义

在JAVA编程语言中是一个抽象类型,是抽象方法的集合,接口通常以interface来声明。一个类通过继承接口的方式,从而来继承接口的抽象方法。

2).特点

接口不能用于实例化对象。

接口没有构造方法,且没有具体的抽象方法

接口中所有的方法必须是抽象方法,每一个方法也是隐式抽象。

接口不能包含成员变量,除了 static 和 final 变量,变量会被隐式的指定为 public static final 变量。

接口不是被类继承了,而是要被类实现。

接口支持多继承。

和抽象类的区别

抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。

抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。

接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。

一个类只能继承一个抽象类,而一个类却可以实现多个接口。

**3).实现,**interface定义,implements实现

interface Animal {

public void eat();

public void travel();

}

public class MammalInt implements Animal{

public void eat(){

​ System.out.println(“Mammal eats”);

}

public static void main(String args[]){

​ MammalInt m = new MammalInt();

​ m.eat();

}

}

4).接口的继承

一个接口能继承另一个接口,和类之间的继承方式比较相似。接口的继承使用extends关键字,子接口继承父接口的方法。

public interface Sports

{

public void setHomeTeam(String name);

public void setVisitingTeam(String name);

}

public interface Football extends Sports

{

public void homeTeamScored(int points);

public void visitingTeamScored(int points);

public void endOfQuarter(int quarter);

}

5).接口的多继承

public interface Hockey extends Sports, Event

6).标记接口

标记接口是没有任何方法和属性的接口.它仅仅表明它的类属于一个特定的类型,供其他代码来测试允许做一些事情。

package java.util;

public interface EventListener

{}

建立一个公共的父接口:

正如EventListener接口,这是由几十个其他接口扩展的Java API,你可以使用一个标记接口来建立一组接口的父接口。例如:当一个接口继承了EventListener接口,Java虚拟机(JVM)就知道该接口将要被用于一个事件的代理方案。

向一个类添加数据类型:

这种情况是标记接口最初的目的,实现标记接口的类不需要定义任何接口方法(因为标记接口根本就没有方法),但是该类通过多态性变成一个接口类型。

7. 包(package)

1).包的定义

为了更好地组织类,Java 提供了包机制,用于区别类名的命名空间。

img

2).包的作用

把功能相似或相关的类或接口组织在同一个包中,方便类的查找和使用。

如同文件夹一样,包也采用了树形目录的存储方式。同一个包中的类名字是不同的,不同的包中的类的名字是可以相同的,当同时调用两个不同包中相同类名的类时,应该加上包名加以区别。因此,包可以避免名字冲突。

包也限定了访问权限,拥有包访问权限的类才能访问某个包中的类。

package net.java.util;

//它的路径应该是 net/java/util/Something.java 这样保存的

public class Something{

}

3).导入包,import 关键字

import net.java.util.*;

五. 数据结构

枚举(Enumeration)

位集合(BitSet)

向量(Vector)

栈(Stack)

字典(Dictionary)

哈希表(Hashtable)

属性(Properties)

六.内存模型

img

七.jdbc

1.官网下载包

http://dev.mysql.com/downloads/connector/j/

选择合适的版本下载

2.使用idea在项目中导入包

3.使用,加载包,链接数据库

Class.forName(“com.mysql.cj.jdbc.Driver”);

conn = DriverManager.getConnection(“jdbc:mysql://localhost:3306/test_demo?useSSL=false&serverTimezone=UTC”,“root”,“password”);

4.执行查询

stmt = conn.createStatement();

ResultSet rs = stmt.executeQuery(sql);

while(rs.next()){

​ // 通过字段检索

​ int id = rs.getInt(“id”);

​ String name = rs.getString(“name”);

​ String url = rs.getString(“url”);

}

5.关闭链接

rs.close();

stmt.close();

conn.close();

八.maven项目

1.官网下载

http://maven.apache.org/download.cgi

选择apache-maven-3.6.1-bin.zip下载

2.配置环境变量

MAVEN_HOME D:\wnmp\apache-maven-3.6.1

PATH %MAVEN_HOME%\bin

mvn -v 可看到版本信息,看是否配置成功

3.修改国内阿里源

打开文件 D:\wnmp\apache-maven-3.6.1\conf\settings.xml

间添加下列代码

aliyunmaven

*

阿里云公共仓库

https://maven.aliyun.com/repository/public

4.修改本地仓库位置

新建D:\wnmp\apache-maven-3.6.1\MavenRepository文件夹

打开文件 D:\wnmp\apache-maven-3.6.1\conf\settings.xml

间添加下列代码

D:\wnmp\apache-maven-3.6.1\MavenRepository

5.构建项目

新建文件夹:D:\www\mvnpro

mvn -B archetype:generate -DgroupId=com.jtthink -DartifactId=htmlparser

GroupID:项目唯一的标识符,对应初始项目包。在main下放的java里面

ArtifactID:项目唯一的标识符,好比项目名称

修改项目下pom.xml

org.jsoup

jsoup

1.10.2

下载依赖

mvn dependency:copy-dependencies

九.jsp/servlet

1.jsp

1).定义

JSP是一种在HTML中嵌入Java代码的动态网页技术

与Servlet相比,JSP更偏重于将数据展示在HTML中,更适合制作动态页面

JSP的执行过程需要经过翻译、编译、执行三个步骤

JSP页面的构成元素有指令、声明、表达式、脚本、动作标签和注释

JSP指令用来向JSP容器提供编译信息

JSP声明用于在JSP中定义变量和方法

JSP表达式用于将Java表达式的运行结果输出在页面中

JSP脚本用于在JSP页面中插入Java代码

JSP提供了很多动作标签实现特定的功能

2).文件组成

JSP文件由6类基本元素组成

JSP指令

JSP声明

JSP表达式

JSP脚本

JSP动作

JSP注释

<%– 指令 –%>

<%@ page language=“java” contentType=“text/html; charset=UTF-8”%>

<%– 申明 –%>

<%!

​ //全局方法和变量

​ private String str = “全局变量”;

​ void setStrParam(String param) {

​ str = param;

​ }

%>

第一个JSP页面

欢迎!

<%– 表达式 –%>

<%

​ java.util.Date now = new java.util.Date();

​ out.println(“当前时间是:” + now);

%>

3).JSP中有9个内置对象

out对象是一个输出流,用于将信息输出到网页中

request对象封装了当前请求信息,可以存取数据

response对象封装了当前响应信息

session对象表示当前会话,可以存取数据

application对象表示整个应用程序,可以存取数据

pageContext对象表示当前JSP页面,可以存取数据

JSP的4种作用范围分别使用pageContext、request、session、application来表示,它们都具有getAttribute()和setAttribute()方法

<%

request.setCharacterEncoding(“GBK”);

String age = request.getParameter(“age”);

String[] channels = request.getParameterValues(“channel”);

out.println(age);

//response.sendRedirect("/test/");

session.setAttribute(“name”, “海尔”);

String name = (String)session.getAttribute(“name”);

out.println(name);

application.setAttribute(“number”, 1);

Integer i = (Integer) application.getAttribute(“number”);

out.println(i);

​ String initValue = config.getInitParameter(“initValue”);

​ out.println(initValue);

%>

2.EL && JSTL

1).EL定义

jsp2.0的一种简捷的语言,表达式语言(Expression Language,EL),简化了访问方式

2).EL基础语法

EL提供 . 和 [] 两种运算符来导航数据,可以同时混合使用。

以下两种情况需要使用 [] :

当要存取的属性名称中包含一些特殊字符时,例如${user.My-Name}。

当属性名称需动态取值时,例如${sessinScope.user[data]},其中data是一个变量。

${EL表达式}

${person.name}

${person[age]}

3).JSTL定义

提供了简单易用的标签,简化了JSP开发,减少了代码数量及增强了可移植性

核心标签库导入:

<%@taglib uri=“http://java.sun.com/jsp/jstl/core" prefix=“c”%>

4).JSTL标签

通用标签

条件标签

迭代标签

URL标签

5).总结

EL的隐含对象有pageScope、requestScope、sessionScope、applicationScope、param、paramValues、initParam等

EL中可以使用算术运算符、关系运算符和逻辑运算符进行运算

JSTL简化了JSP开发,提供了一个无脚本环境

JSTL提供了5个标签库:核心标签库、I18N标签库、XML标签库、SQL标签库和EL函数库

在JSP页面中使用标签库,需要使用taglib指令导入,格式如下:

​ <%@taglib uri=“标签库uri路径” prefix=“前缀名”%>

核心标签库分为通用标签、条件标签、迭代标签和URL标签

常用的通用标签有:<c:out>、<c:set>、<c:remove>和<c:catch>

条件标签有:<c:if>、<c:choose>、<c:when>和<c:otherwise>

迭代标签有:<c:forEach>、<c:forTokens>

URL标签有:<c:import>、<c:redirect>和<c:url>

常用的I18N标签有:fmt:setLocalefmt:bundlefmt:setBundlefmt:messagefmt:formatNumberfmt:formatDate

EL函数主要提供了对字符串处理的功能,此外还可以利用EL函数获取集合的大小

3.Servlet

1).定义

Servlet是运行在Web服务器中的小型Java程序。Servlet通常通过HTTP(超文本传输协议)接收和响应来自Web客户端的请求

2).配置

将TOMCAT服务器中的common\lib 下的servlet-api.jar文件复制到JDK的安装目录的\jre\lib\ext子目录中

Servlet需要在web.xml文件中配置

Hello

​ com.haiersoft.ch01.HelloServlet

Hello

/hello

3).生命周期

init():用于Servlet初始化。当容器创建Servlet实例后,会自动调用此方法

service():用于服务处理。当客户端发出请求,容器会自动调用此方法进行处理,并将处理结果响应到客户端

destroy():用于销毁Servlet。当容器销毁Servlet实例时自动调用此方法,释放Servlet实例,清除当前Servlet所持有的资源

img

4).总结

动态网站开发技术有Servlet、JSP、PHP、ASP、ASP.NET和CGI等

Servlet是运行在服务器端的Java程序,内嵌HTML

Servlet生命周期的三个方法分别是:init()、service()和destroy()

Servlet处理Get/Post请求时分别使用doGet()/doPost()方法进行处理

HttpServletRequest的getParameter(“参数名称”)获取表单、URL参数值

HttpServletResponse的getWriter()获取向客户端发送信息的输出流

HttpServletRequest的getHeader(“报头名称”)获取相关报头信息

请求转发和重定向都可以使浏览器获得另外一个URL所指向的资源

请求转发通常由RequestDispatcher接口的forward()方法实现,转发前后共享同一个请求对象

重定向由HttpServletResponse接口的sendRedirect()方法实现,重定向不共享同一个请求对象

十. 注解 (Annotation)

十一.java反射

1.定义

反射就是把java类中的各种成分映射成一个个的Java对象

例如:一个类有:成员变量、方法、构造方法、包等等信息,利用反射技术可以对一个类进行解剖,把个个组成部分映射成一个个对象。

​ (其实:一个类中这些成员方法、构造方法、在加入类中都有一个类来描述)

img

**2.**反射的使用

1、获取Class对象的三种方式

1.1 Object ——> getClass();

1.2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性

1.3 通过Class类的静态方法:forName(String className)(常用)

public static void getObjectClass(){

​ //第一种方式获取Class对象

​ Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。

​ Class stuClass = stu1.getClass();//获取Class对象

​ System.out.println(stuClass.getName());

​ System.out.println(stuClass.getClasses());

​ //第二种方式获取Class对象

​ Class stuClass2 = Student.class;

​ System.out.println(stuClass == stuClass2);//判断第一种方式获取的Class对象和第二种方式获取的是否是同一个

​ //第三种方式获取Class对象

​ try {

​ Class stuClass3 = Class.forName(“com.zhu.test.Student”);//注意此字符串必须是真实路径,就是带包名的类路径,包名.类名

​ System.out.println(stuClass3 == stuClass2);//判断三种方式是否获取的是同一个Class对象

​ } catch (ClassNotFoundException e) {

​ e.printStackTrace();

​ }

}

2、获取Class对象的构造方法

//1.加载Class对象

Class clazz = Class.forName(“com.zhu.test.Student”);

//2.获取所有公有构造方法

System.out.println("所有公有构造方法***********");

Constructor[] conArray = clazz.getConstructors();

for(Constructor c : conArray){

​ System.out.println(c);

}

System.out.println("所有的构造方法(包括:私有、受保护、默认、公有)***");

conArray = clazz.getDeclaredConstructors();

for(Constructor c : conArray){

​ System.out.println(c);

}

System.out.println("获取公有、无参的构造方法**************");

Constructor con = clazz.getConstructor(null);

//1>、因为是无参的构造方法所以类型是一个null,不写也可以:这里需要的是一个参数的类型,切记是类型

//2>、返回的是描述这个无参构造函数的类对象。

System.out.println(“con = " + con);

//调用构造方法

Object obj = con.newInstance();

// System.out.println(“obj = " + obj);

// Student stu = (Student)obj;

System.out.println("获取私有构造方法,并调用*************");

con = clazz.getDeclaredConstructor(char.class);

System.out.println(con);

//调用构造方法

con.setAccessible(true);//暴力访问(忽略掉访问修饰符)

obj = con.newInstance(‘男’);

3、获取成员变量并调用

public static void getParams() throws Exception {

​ //1.获取Class对象

​ Class stuClass = Class.forName(“com.zhu.test.Student”);

​ //2.获取字段

​ System.out.println("获取所有公有的字段********");

​ Field[] fieldArray = stuClass.getFields();

​ for(Field f : fieldArray){

​ System.out.println(f);

​ }

​ System.out.println("获取所有的字段(包括私有、受保护、默认的)********");

​ fieldArray = stuClass.getDeclaredFields();

​ for(Field f : fieldArray){

​ System.out.println(f);

​ }

​ System.out.println("获取公有字段并调用********************");

​ Field f = stuClass.getField(“name”);

​ System.out.println(f);

​ //获取一个对象

​ Object obj = stuClass.getConstructor().newInstance();//产生Student对象–》Student stu = new Student();

​ //为字段设置值

​ f.set(obj, “刘德华”);//为Student对象中的name属性赋值–》stu.name = “刘德华”

​ //验证

​ Student stu = (Student)obj;

​ System.out.println(“验证姓名:” + stu.name);

​ System.out.println("获取私有字段****并调用******************");

​ f = stuClass.getDeclaredField(“phoneNum”);

​ System.out.println(f);

​ f.setAccessible(true);//暴力反射,解除私有限定

​ f.set(obj, “18888889999”);

​ System.out.println(“验证电话:” + stu);

}

4、获取成员方法并调用

public static void getAction() throws Exception {

​ //1.获取Class对象

​ Class stuClass = Class.forName(“com.zhu.test.Student”);

​ //2.获取所有公有方法

​ System.out.println("获取所有的”公有“方法****");

​ stuClass.getMethods();

​ Method[] methodArray = stuClass.getMethods();

​ for(Method m : methodArray){

​ System.out.println(m);

​ }

​ System.out.println("获取所有的方法,包括私有的****");

​ methodArray = stuClass.getDeclaredMethods();

​ for(Method m : methodArray){

​ System.out.println(m);

​ }

​ System.out.println("获取公有的show1()方法****");

​ Method m = stuClass.getMethod(“show1”, String.class);

​ System.out.println(m);

​ //实例化一个Student对象

​ Object obj = stuClass.getConstructor().newInstance();

​ m.invoke(obj, “刘德华”);

​ System.out.println("获取私有的show4()方法***");

​ m = stuClass.getDeclaredMethod(“show4”, int.class);

​ System.out.println(m);

​ m.setAccessible(true);//解除私有限定

​ Object result = m.invoke(obj, 20);//需要两个参数,一个是要调用的对象(获取有反射),一个是实参

​ System.out.println(“返回值:” + result);

}