Java开发笔记

本文详细介绍了Java编程的基础知识,包括Java的开场白、变量、常量、数据类型、关键字、标识符、转义字符、运算符、程序流程控制和数组。此外,还讲解了面向对象设计的原理,如类、对象、构造方法、方法、继承、多态、抽象类和接口。最后,简要讨论了异常处理和集合框架,如ArrayList、LinkedList、Map和线程的概念。
摘要由CSDN通过智能技术生成

目录

第1章 Java开场白 2

1.1 认识Java程序 2

1.1.1 main()函数 2

1.1.2 Java代码组织习惯 2

1.2 认识变量 2

1.2.1 变量的申明 2

1.2.2 命名规范 3

1.2.3 八种基本类型变量 3

1.2.4 变量的范围 3

1.3 认识常量 4

1.4 数据的类型 4

1.4.1 类型的转换 4

1.5 Java关键字 4

1.6 认识标识符名 4

1.7 转义字符 4

1.8 Java运算符 5

1.8.1 算术运算符 5

1.8.2 赋值运算符 5

1.8.3 关系运算符 5

1.8.4 逻辑运算符 5

1.8.5 其它运算符 5

1.8.6 运算符号之优先级 6

1.9 程序流程控制 6

1.9.1 顺序结构 6

1.9.2 选择结构 6

1.9.3 循环结构 7

1.10 数组 9

1.11 一维数组 9

1.12 二维数组 10

1.12.1 多维数组 10

第2章 Java面向对象程序设计 10

2.1 面向对象设计思想 10

2.2 类 10

2.2.1 类的概念 10

2.2.2 封装 11

2.2.3 类的创建 11

2.2.4 对象的创建与使用 11

2.3 Java中的方法 12

2.3.1 Java程序执行分析过程 12

2.3.2 方法分类 12

2.3.3 构造方法 12

2.3.4 自定义方法 13

2.3.5 方法的重载 13

2.3.6 方法的调用 13

2.3.7 方法参数极其传递 14

2.4 类的属性 15

2.4.1 属性 15

2.4.2 this关键字 15

2.5 包 16

第3章 类的继承和多态 16

3.1 继承 16

3.1.1 Object类 16

3.1.2 Java中继承 16

3.1.3 super关键字 17

3.2 多态 17

3.2.1 Java中多态的实现 17

3.2.2 类型检测—向上转型/向下转型 18

3.3 Static关键字 18

3.4 Final关键字 19

3.5 Abstract关键字 19

3.5.1 抽象类 19

3.5.2 抽象方法 19

第4章 接口 19

4.1 接口例子 19

4.2 接口声明 20

4.3 使用接口 20

4.3.1 接口的使用 20

4.3.2 Java接口的特征 20

4.4 接口可以继承 20

第5章 程序的异常 21

5.1 异常的声明,捕获和处理 21

5.1.1 异常机制概述 21

5.1.2 在Java中如何进行异常处理 22

5.2 用Log4J记录异常日志信息 24

第6章 集合 27

6.1 Java集合 27

6.1.1 集合与数组的区别 27

6.1.2 集合包结构 27

6.2 容器类 27

6.2.1 Collection接口 27

6.2.2 Comparable/comparable接口 29

6.2.3 Iterator接口 29

6.2.4 Map接口 31

6.3 容器选择原则 32

第7章 线程 32

7.1 线程简介和Java实现 32

7.1.1 主线程 33

7.1.2 线程的创建和启动 33

7.2 线程组 34

7.3 线程状态 35

7.3.1 线程状态 35

7.3.2 线程状态转换 35

7.3.3 让线程之间通信 37

第8章 用I/O进行数据处理 38

8.1 文件 38

8.2 流和流的分类 38

8.2.1 字节流和字符流 39

8.2.2 过滤(处理)流 43

8.2.3 对象序列化与反序列化 44

第9章 反射与注解 44

9.1 反射概念 44

9.1.1 class类 44

9.1.2 用反射获取类的属性 45

9.2 注解 45

9.2.1 常用注解 46

第10章 数据库技术 46

10.1 MySQL 46

10.2 用JDBC与数据库交互 49

10.3 Java与MySQL连接 49

第11章 XML技术 50

11.1 XML 50

第12章 软件工程 51

Java开场白

认识Java程序

main()函数

public static void main(String[] args){…}

public:关键字访问权限

static:告诉编译器main函数是一个静态函数存储在静态区域

void:该函数没有返回类型

main:main是函数名

String[] args:方法的参数public class Main {

public static void main(String[] args) throws Exception {
// write your code here
String[] s = {“test01”, “test02”, “test03”};
if (s == null || s.length == 0) {
System.out.println(“没有传递参数”);
return;
}
for (int i = 0; i < s.length; i++) {
System.out.println(s[i] + " ");
}
}
}

Java代码组织习惯

代码块:用大括号括起来的程序块

public class HelloWorld{

public static void main(Strings[] args){

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

}

}

认识变量

变量的申明

Java是强类型语言变量必须声明才能使用

声明:类型 变量名;

命名规范

变量命名只能以$、字母、下划线、数字组合这种方式,并且只能以$、字母、下划线开头,不能以数字开头。

八种基本类型变量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bplorHtw-1617798717612)(media/528321547bf98b5f22c3c0b49678a0a8.png)]

变量的范围

变量的范围:变量定义开始,到块结束。

局部变量:在方法内定义的变量

注意:1.Java的局部变量,必须初始化才能使用;2.变量是有作用域的,也就是范围;3.变量名是不可以重复的;

public static void main(String[] args) throws Exception {
// write your code here
if(5>3){
int i=0;
}
int i=5;
}

这种代码运行成功
Reason:两个变量i,这个i是在代码块里,作用域就是这个if代码块,超过这个代码块,就被回收了。

public static void main(String[] args) throws Exception {
// write your code here
int i=2;
if(5>3){
int i=0;
}
}
}

这种代码运行不成功
Reason:第一个变量i作用域就是这个main函数代码块,所以在这个范围内的任何地方,包括if代码块都是i的作用域,所以if代码块里的变量i与第一个变量i冲突,所以错误。

认识常量

常量:常量定义之后,就不会再发生变化。

public static final + 类型名 +变量 = …

eg. public static final double PI= 3.14;

常量作用:固定变量数值不改变。

数据的类型

类型的转换

值域大的类型不能直接转换成智育类型小的的类型,但是可以强转

强转语法:类型A 变量名 = {类型A}变量名

public static void main(String[] args) throws Exception {
// write your code here
double i = 9.2;
int a = (int) i;
System.out.println(a);
}

虽然可以强转类型,但是丢失了精度。输出结果:a=9

Java关键字

Java中关键字:Java中的保留字(我们定义的变量不能和Java的关键字重名)

认识标识符名

Java中标识符:类名(【n】每个单首字母大写)、变量名(【n】首字母小写)、方法名(【v】首字母小写)、包名(通常全部小写)

转义字符

常见转义字符

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M2W3NKcJ-1617798717619)(media/493fa42b919f84432878b4d7b3ced4d1.png)]

Java运算符

算术运算符

“+”“-”“*”“/”“%”“++”{(++a)前++:变量先加1后再算表达式}{(a++)后++:先算表达式后变量加1}

赋值运算符

“=”

扩展赋值运算符:在赋值运算符“=”前加上其它运算符。

“+=”“-=”“/=”“%=”“&=”…

关系运算符

关系运算符:用来比较两个值,返回布尔类型:true或者false。

关系运算符都是二元运算符

“>”“>=”“<”“<=”“==”“!=”

逻辑运算符

&&:与串联 c=a&&b :如果a为false,c直接为false;如果a为true,b也为true,c为true;

||:或并联 c=a||b :如果a为ture,c直接为true;如果a为false,b也为false,c为false

!:非 !c 布尔值直接取反

其它运算符

instanceof
实例运算符:用于测试一个对象是否是一个指定类的实例(判断对象是否为某个类或者接口类型)

new 对象实例化运算符:实例化一个对象,即对象分配的内存

三目运算符 布尔表达式?值1:值2

public static void main(String[] args) throws Exception {
// write your code here
int Num= 5> 3? 1:2;
System.out.println(Num);
}

输出结果:1

运算符号之优先级

优先级别高的运算符号先运算,级别低的运算符后计算

程序流程控制

顺序结构

执行顺序自上而下

选择结构

if语句:

if语法:

if(布尔表达式){…}

在if中如果布尔表达式为true,就执行里面的代码,否则不执行。

if…elseif语句

if…elseif语法:

if(布尔表达式1){…}

else if(布尔表达式2){…}

else {…}

switch语句 只能操作整型(byte、short、int)和char类型

switch语法:

switch(整型变量或者char变量){

case 值1:

break;

case 值2:

break;

case 值n:

break;

default;

}

Scanner con =new Scanner(System.in);//此类方法从控制台输入
int num =con.nextInt();//从控制台输入整数
switch (num){
case 1:
System.out.println(“大根子我爱你”);
break;
case 2:
System.out.println(“大根子不行了”);
break;
case 3:
System.out.println(“大根子啊”);
default:
System.out.println(“大根子小鸡鸡”);
}

循环结构

循环结构:可以减少资源重复书写的工作量

while循环
while语句重复执行循环,直到条件式的布尔值为假为止,如果第一次条件就不满足,那么这个循环体就一次也不执行。

语法:while(布尔条件式){

程序语句

}

do while循环 do
while循环重复执行循环,直到条件式的布尔值为假为止,如果第一次条件不满足,那么这个循环体也会执行一次。

语法:do{

程序语句

}while(条件式);

for循环 循环重复执行循环

语法:for(表达式1,表达式2,表达式3){

程序语句

}

表达式1:指定一个初始值

表达式2:检查循环是否为真(真:继续 假:退出循环)

表达式3:定义每次循环后变量应做的修改

break 1.在switch语句中用来终止一个语句序列 2.用来退出一个循环

1. 在switch语句中用来终止一个语句序列

for(int i=0;i<=5;i++){
System.out.println(“i=”+i);
if(i==2){
break;
}
}

输出结果:

i=0

i=1

i=2

2. 用来退出一个循环

break只能跳出当前的循环,不能跳出其它的循环

但是可以用特殊手段让break跳出多层循环,特殊手段:分别在外层循环加上“标记”,在该程序中,在外层循环加上out标记,内层循环加上in标记;

out :for(int i=0;i<=5;i++){
System.out.println(“i=”+i);
System.out.println("{");
in:for(int j=0;j<5;j++){
System.out.println(“j=”+j+"\t");
if(i2&&j3){
break out;//跳出最外循环
}
}
System.out.println("}");
}
}

输出结果:

i=0

{

j=0

j=1

j=2

j=3

j=4

}

i=1

{

j=0

j=1

j=2

j=3

j=4

}

i=2

{

j=0

j=1

j=2

j=3

continue 回到循环的开始处,继续向下执行

for(int i=0;i<5;i++){
if(i==2){
continue;
}
System.out.println(“i=”+i);
}

输出结果:

i=0

i=1

i=3

i=4

数组

一维数组

一维数组:可以存储多个值,缓解存储单个值得局限性

定义 两种方式:1.先声明,然后初始化 2.直接初始化

1.先声明,然后初始化

类型[] 名称;//先声明

名称=new 类型[] {元素1,元素2,…,元素n};

2. 直接初始化

类型[] 名称 = {元素1,元素2,…,元素n};

数组的下标

数组下标表示数组的位置,在Java中数组下标从0开始,下标数组长度减一表示最后一个元素

数组的长度

在Java中数组长度用length表示 “数组名称.length”:数组长度

数组的打印

数组的打印除了可以用for循环,也可以用Arrays类中的to String方法

int[] a= {1,2,3,4,5};
System.out.println(Arrays.toString(a));

二维数组

二维数组:一维的一维

二维数组的声明:

类型[][] 名称;

二维数组里存放的是一维数组

类型[][] 名称 ={{数组1},{数组2}}

二维数组的下标

int[][] a= {{1,2,3},{4,5,6}}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dhl1Kg4t-1617798717622)(media/02441ced9bfe8dc8f7fa49e1756fc04d.png)]

多维数组

多维数组:一维的多维

Java面向对象程序设计

面向对象设计思想

Java语言:OOP(Object-Oriented Programming):考虑我要做什么,然后才是怎么做

面向对象:对象各司其职;一个对象绝对不能直接对另一个对象内部的数据(成员变量)进行计算,可以对象通过调用另一个对象的方法来进行。

类的概念

对象:程序的基本单位。相似的对象:变量和方法的关系相似的一类对象

:一种对象类型,就是对象实现的模板,也相当于相似的对象之间共同的属性。

一个类可以产生很多对象。产生对象的过程,称之为实例。一个对象的内部状态(私有属性private),只能让对象自己来修改,其它任何对象都不能直接修改它,但是可以通过调用它的方法来修改它。

封装

封装:把相关的数据和方法都组织在类内,构成一个组件;也称组件

封装意义:一种信息隐藏技术,对象内部对用户是透明的,用户只能通过接口去调用对象种的方法,不能直接去修改对象内部的信息。包就体现了封装的好处。

类的创建

Java的开发实质上就是设计类,具体执行就是CPU按照用户所编写的类去执行。类有两种基本成分:1.变量(成员变量):基本类型的数据或者数组;类的实例2.方法(成员方法):类似与函数,但是与函数的区别是只能在类中定义,调用方法时,实际上是对象与对象之间或者用户与对象之间的消息传递。

注意:变量一般设置为共有(public),方法一般设置为私有(private)

字段:类中的数据,也叫做类的变量;属性:类的变量的值;方法:类中的函数

//class 类名 {类体}

public class Main {
public static void main(String[] args) throws Exception {
// write your code here
GirlFriend jia = new GirlFriend();//创建一个GirlFriend实例
jia.setMoney(200);
System.out.println(“jia的私房钱有:”+jia.getMoney());
}
}
class GirlFriend {
private int money;
public void setMoney(int x){
money =x;
}
public int getMoney(){
return money;
}
}

对象的创建与使用

对象(Object)是类的实例,程序运行时就会占用内存单元。Java语言是建立在类的基础上,所以对象就是Java语言的核心。

对象的创建

对象需要先声明,然后需要用new进行实例化

GirlFriend caosijia;
caosijia= new GirlFriend();

访问对象实质上就是访问对象的成员变量,对象的成员变量的访问使用“.”运算符。

caosijia.sex=“女”;

创建对象的意义就是可以访问对象的属性,其次可以通过对象来调用该对象的方法。对象调用方法也是要用到“.”运算符。对象名.方法()。

caosijia.getmoney();

注意:如果是静态方法(static修饰的方法),可以直接使用类名访问

public static void getMoney01(){

System.out.println(“no money”);

}

Main:GirlFriend.getMoney01();

输出结果:no money

Java中的方法

Java程序执行分析过程

JVM执行Java程序,先编译(虚拟机根据Java语言的规则进行语法分析,词法分析,语义分析,以及类变量常量的提取,然后依据class文件的格式转换为字节码文件,用Javac命令),后运行(JVM用解释器来完成,用Java命令)。

方法分类

类方法(静态方法):该方法,系统只为该类创建一个版本,这个版本被该类和该类所创建的所有对象所共享。注意:类方法只能操作静态变量(用static修饰的变量),不能访问实例变量。

static void m(){…}

实例方法:可以操作对象的实例变量,还可以访问类变量。

构造方法

**构造方法(构造器):**和类名同名(大小写也要一致)的方法,而且不能有返回值。如果不写构造方法,Java会自动创建一个构造方法。

class Demo{

public Demo(){}

}

除了无参构造方法,构造方法也会有参数

class Demo{

public Demo(int x){}

}

构造方法作用:通过构造方法创建对象,分为有参构造方法构造和无参构造方法构造。

1.Demo a =new Demo();

2. Demo a =new Demo(2);

自定义方法

方法除了系统默认的构造方法以外,其它都是自定义方法。

声明语法:访问修饰符 返回类型 方法名(参数列表){ }

修饰符:public private 缺省 protected

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5UDaTLd5-1617798717626)(media/f53290eea85eca25249ea66798ff6897.png)]

返回值:方法体必须返回一个return语句,返回的类型必须和返回值一致

方法参数类型:参数个数,各参数的类型,参数之间用逗号分隔

形参:在方法定义是括号里面的参数 实参:调用方法传入具体的值

带static关键字的方法(静态方法):public static void test(){…}

带final修饰的方法:该方法不能被重载也不能被覆盖。public final void test(){…}

注意:final和static的顺序可以互换。

方法的重载

**重载(overloaded):**同一个类中两个或者两个以上的方法有相同的名字,但是参数声明不同。注意:参数字母不同,返回值类型不同也不能称之为重载。

public int add (int x,int y){…}

public void add(int a,int b){…}

这两个方法都不能称之为重载。

方法的调用

非静态方法调用:对象名.方法() 静态方法调用:类名.方法()

方法与方法之间的调用:主要是在于一个方法内部如何调用其它方法。

方法参数极其传递

方法参数传递分为两种类型:基本类型和引用类型

基本类型:传入的是基本类型的时候,实参会复制一份,传入方法内,在方法内修改数值不会影响原实参。

public class Main {

private static int x=10;

public static void main(String[] args) throws Exception {

Main a = new Main();

getX(x);

System.out.println(“x:”+x);

}

public static void getX(int x){

x–;

}

}

输出结果:x:10,这就代表方法内部不会修改实参的值

引用类型传递:在栈中声明对象,之后在堆内存中分配内存。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YrnDjez7-1617798717629)(media/85185a9122d8f0835e25dbb62d01fd15.png)]

注意:如果没有给对象初始化,会报空指针报错,NullPointException异常。

“对象名.属性名”实际是就是每一个对应的堆内存空间的属性,只要存在new关键字,Java就会新开辟一个堆空间。

一个堆内存可以被多个对象同时指向(一个堆内存被多个栈内存所指向)

public class Main {

private static int x=10;

public static void main(String[] args) throws Exception {

// write your code here

P p =new P();

p.name=“jia”;

p.age=30;

P p2= new P();

p2.name=“jiajia”;

p2.age=20;

p2.t();

}

}

class P{

String name;

int age;

public void t(){

System.out.println(“姓名:”+name+",age:"+age);

}

}

输出结果:姓名:jiajia,age:20

p的属性被p2修改了。原因:一个堆内存可以同时被多个栈所指向。

类的属性

属性

属性包括 成员属性(全局) 局部属性(在方法内部)

this关键字

this指的是当前对象。在Java中用户可以通过this关键字访问类中的属性、方法。

public class Main {

int x=5;

public static void main(String[] args) throws Exception {

Main a =new Main();

}

public Main() {

System.out.println(this.x);

}

}

输出结果:5

包类似于文件夹,主要是给类分类工作,便于维护和管理。

包导入类型:1.导入包所有类 import 包名.* 2.导入包中具体的类 import 包名.类名

类的继承和多态

继承

Object类

Java中所有类都默认继承Obejct类,Object类是所有Java的父类。

object是类层次结构的根类,每个类都使用Obeject作为超类(父类)。

Java中继承

Java中继承使用关键字“extends” class 子类 extends 父类{}

继承类作用:使用继承,子类可以拥有父类中的非私有属性,父类中非私有方法。

public class Main {

int x=5;

public static void main(String[] args) throws Exception {

// write your code here

student a= new student();

}

}

class person{

public String name=“大根子”;

public String sex=“男”;

public int age=10;

public void setName(String name){

this.name=name;

}

}

class student extends person{

private int grade=10;

student(){

System.out.println(“姓名:”+name+" 性别:"+sex+" 年龄:"+age+" 成绩:"+grade);

}

}

输出结果:姓名:大根子 性别:男 年龄:10 成绩:10

super关键字

子类可以用super关键字调用父类的非私有属性和非私有方法,还可以调用父类的非私有构造方法。

用法:super.父类属性 super.父类方法

public class Student extends Person{

private int grade;

String name = super.name;

public void test(){

super.getAge();

}

}

super调用父类的构造方法

调用无参构造方法super();(super关键字可以省略)
调用有参数构造方法super(参数);super(参数)

super执行顺序:执行完父类构造方法之后再调用本类的构造方法

多态

Java中多态的实现

多态体现再重载和覆盖;覆盖:子类重写了父类的方法。

class father{

public void say(){

System.out.println(“father say()”);

}

}

class son extends father{

public void say(){

System.out.println(“son say()”);

}

}

类型检测—向上转型/向下转型

向上转型:父类对象引用指向子类对象。

父类 对象 = new 子类()

father a = new son( );

向下转型:在向上转型的基础上再次指向子类的对象

父类 对象1 =new 子类();

子类 对象2= (子类) 对象1;//强类型转换

注意:向下转型有时候丢失子类特有的方法

Static关键字

被static修饰的

静态变量访问:“类名.变量名”直接访问

静态方法:“类名.方法名”

静态代码块:被static修饰的静态代码块,位置可以随便放,不在任何的方法体内。static会优先与构造器执行。如果有多个static修饰的代码块,JVM会在它们类中出现的先后顺序依次执行,每个代码块只会执行一次。

public class Main {

public static void main(String[] args) throws Exception {

// write your code here

father a= new father();

}

}

class father{

static{

System.out.println(“static way”);

}

father(){

System.out.println(“构造方法”);

}

public void say(){

System.out.println(“father say()”);

}

}

输出结果:static way

构造方法

Final关键字

使用final修饰的类,表示该类不能被继承

Abstract关键字

抽象类

被abstract修饰的类。抽象类必须由子类继承,才能实例化对象。

abstract class 类名{ }

抽象方法

被abstract修饰的方法。该方法只有方法头,没有方法体。

public abstract class Type(){没有方法体}

总结:抽象类中既有抽象方法,也有非抽象方法;有抽象方法的类一定是抽象类。

接口

接口例子

接口就是一种特殊的抽象类,接口中只提供了方法的原形,没有方法体,具体实现还是要靠子类的继承来覆盖。接口和抽象类一样,可以定义抽象方法,包含抽象的方法和常量,但是不能有变量、初始化块和构造函数。接口中的方法必须都要由接口的实现类来实现,这就是一种规范。

interface Student{

int class=10;//常量

void learn();

}

class student1 implements student{

public void learn(){

System.out.println(“我正在学习”);

}

}

接口声明

Java接口的声明类似于Java类。并且Java文件名(接口文件名)必须与接口名一致。

修饰符 interface 接口名 [extends 父类接口名] {

[public] [static] [final] 常量;

[public] [abstract] 方法;

}

使用接口

接口不能单独实例化,必须通过类来继承接口来实现。接口的实现类必须要实现接口中的所有方法。这就是一种规范。

接口的使用

类在实现接口的语法:

[修饰符] class <类名> [extends 父类名] [implements 接口列表] {}

注意:接口也可以实例化,但是必须由接口的实现类来实现。

接口 对象名 = new 接口的实现类();

Java接口的特征

接口中所有的变量都是常量,接口中所有的方法都是抽象方法;类实例化接口,必须要实现接口中所有的方法,一个类不可以继承多个类,但是可以继承多个接口。

接口可以继承

接口可以实现多继承,原因:Java中类只能实现单继承,如果一个子类继承多个父类,父类中出现同一个方法D,这个时候子类就不知道该继承哪一个,但是接口不一样,都是抽象方法,继承谁都无所谓。注意:接口只能继承接口,不能继承普通类和抽象类。

public interface A extends B{}

interface B{public void b();}

程序的异常

异常的声明,捕获和处理

异常机制概述

Java把程序运行中遇到非致命的,通过某种修正后还能继续执行的错误称为异常通常Java的异常:表达式的计算违反了Java定义,如整数被0除;使用了太多内存;程序代码中throw语句被使用;异步异常发生(Thread的stop方法被调用;Java虚拟机内部错误发生)

Java异常处理通过5个关键字来处理:try、catch、throw、throws、finally

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qz5RiDtF-1617798717631)(media/c51af03d19b347a34984905f34c142ff.png)]

Error通常是错误,程序员是不可能通过代码来修改。

Exception指的是异常。分为运行时异常(RuntimeException;Java编译器可以允许程序不做处理)和非运行时异常(java.lang库中定义;Java编译器要求程序必须捕获或者声明抛出这种异常)。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VS3p9vuc-1617798717633)(media/42711783abafbbd2110fbe5f6f921350.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-T3I0M7S3-1617798717634)(media/f915a37a4915c3ddbe8e2d891b5324dc.png)]

在Java中如何进行异常处理

Java中处理异常有两种方法:try…catch…finally…和throws来操作

try…catch…finally…捕获命名为异常类的异常;finally语句是可以省略的,catch语句可以有多个,如果用户要捕获多个异常,按照异常的范围从小到大顺序叠放。

public class Main {

public static void main(String[] args) throws Exception {

try{

int x=5;

int y=x/0;

System.out.println(y);

}catch(Exception e){

e.printStackTrace();//将错误打印到堆栈

}finally {

System.out.println(“Over!”);

}

}

}

输出结果:

java.lang.ArithmeticException: / by zero

at com.company.Main.main(Main.java:11)

Over!

使用throw抛出的异常,throw子句通过是可以指明多个异常,说明该方法将不对这些异常进行处理,而是声明抛弃它们。

public static void main(String[] args) throws IllegalArgumentException {

{

int x=5;

int y=x/0;

System.out.println(y);

}

}

}

手动异常:抛弃的对象是通过throw语句来实现的,可以抛出的异常必须是Throwable或者其子类的实例。(throw
异常名;throw关键字主要是用在try块中)

try{

System.out.println(“正在运行的程序…”);

throw new IOException(“用户自行产生的异常”);

}catch (IOException e){

e.printStackTrace();

}finally {

System.out.println(“over!”);

}

自定义异常:建立自己的异常类型,只要定义Exception的一个子类就可以了。

class 自定义异常 extends 父异常类名{类体}

public class Main {

public static void main(String[] args) throws IllegalArgumentException {

// write your code here

Main a= new Main();

try{

a.add(2,2);

}catch (MyException e){

e.printStackTrace();

}

}

private void add(int a,int b)throws MyException{

if(a==b){

throw new MyException(“输入两个数相等”);

}

}

}

class MyException extends Exception{

public MyException(String msg){

super(msg);

}

public MyException(String message,Throwable cause){

super(message,cause);

}

}

输出结果:com.company.MyException: 输入两个数相等

at com.company.Main.add(Main.java:19)

at com.company.Main.main(Main.java:12)

用Log4J记录异常日志信息

log4j是Apache的一个开放源代码项目。是一个日志操作包,可以通过使用log4j指定日志信息输出的目的地,控制每一条日志的输出格式,定义日志信息的级别。所有的这些功能都是通过一个日志配置文件来实现的。

日志:记录程序的运行情况,如错误信息、系统管理员的登录情况等。

如何使用log4j记录日志:log4j主要是由三大组件组成:Logger:决定什么日志信息应该被输出、什么日志信息应该被忽略。Appender:指定日志信息应该被输出到什么地方。Layout:指定日志信息的输出格式。

一个日志可以多个Appender,(日志信息可以同时输出到多个设备上)一个Appender对应一个Layout。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q1OuFC8X-1617798717636)(media/927a66f656cd2a55b7c6557d1abd07bf.png)]

**Logger组件:**log4j核心组件,代表日志记录器,对日志信息进行筛选。由org.apache.log4j.Logger类实现。源代码如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ebhn4If8-1617798717637)(media/dbb785d9446e29f666fa518b97f0ad50.png)]

配置文件中配置Logger组件:

log4j.logger.myLogger=WARN
//定义了一个Logger组件,名称为myLogger,日志级别为WARN。

日志种类一共有五种,级别由高到低依次是fatal、error、warn、info、debug。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3eqnUeCW-1617798717639)(media/27e83a944e10b47574f62924fec4763c.png)]

以上方法只有级别大于或等于Logger组件配置的日志级别才被调用。

**Appender组件:**决定将日志信息输出到什么地方。支持:控制台(console)、文件(file)、GUI组件、套接口服务器等。

log4j.logger.myAppender=WARN,file,console

log4j.appender.file=org.apache.log4j.RollingFileAppender

log4j.appender.file.File=log.txt

log4j.apender.console=org.apache.log4j.ConsoleAppender

//mylogger配置了两个Appender:一个是file,一个是console

Layout组件:决定日志输出格式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1T2pnbjU-1617798717640)(media/361c4f99a53f896d0bafd0028cac103b.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WjSh6n2D-1617798717641)(media/9e58be1f3895ffad5c0bd748cf731fd7.png)]

log4j.appender.console.layout=org.apache.log4j.SimpleLayout//配置日志输出格式为SimpleLayout。

patternLayout让开发者依照ConversionPattern定义输出格式。ConversionPattern一些指定日志内容和格式预定义符号如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oe2Z6SUG-1617798717643)(media/368c2226876c69d89ab5d02e2373fc72.png)]

定义配置文件:log4j支持两种配置文件:XML和Java属性文件(采用“键=值”形式)

常见的是log4j.properties文件

### set log levels ###

log4j.rootLogger = debug , C , D , E

### console ###

log4j.appender.C = org.apache.log4j.ConsoleAppender

log4j.appender.C.Target = System.out

log4j.appender.C.layout = org.apache.log4j.PatternLayout

log4j.appender.C.layout.ConversionPattern = [%d] [%t] (%F:%L) %-5p %c - %m%n

### log file ###

log4j.appender.D = org.apache.log4j.DailyRollingFileAppender

log4j.appender.D.File = …/logs/project_logs/ssm_demo/ssm_demo_info.log

log4j.appender.D.Append = true

log4j.appender.D.Threshold = INFO

log4j.appender.D.layout = org.apache.log4j.PatternLayout

log4j.appender.D.layout.ConversionPattern = [%d] [%t] (%F:%L) %-5p %c - %m%n

### exception ###

log4j.appender.E = org.apache.log4j.DailyRollingFileAppender

log4j.appender.E.File = …/logs/project_logs/ssm_demo/ssm_demo_error.log

log4j.appender.E.Append = true

log4j.appender.E.Threshold = ERROR

log4j.appender.E.layout = org.apache.log4j.PatternLayout

log4j.appender.E.layout.ConversionPattern = [%d] [%t] (%F:%L) %-5p %c - %m%n

具体使用:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VbWkSRgs-1617798717645)(media/6fe89bba0479737947de084c4c55db31.png)]

集合

Java集合

集合可以认为是一种可变的数组,大小可以随着元素的增加而增加。

集合与数组的区别

数组是一个线性的序列,数组容量是不变的,生命周期也是不变的,Java数组会做边界检查,如果越过边界会报RuntimeException异常错误。集合容量是可变的,扩展性比较好,内部实现基于数组,所以综上数组的效率要高于集合。

集合包结构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p5Htq9f2-1617798717646)(media/daaca421951aea8214a84ca77f6d7ec8.png)]

容器类

Collection接口

Collection接口(最基本的接口)List、Set;这些接口主要用于操作集合,如集合的增删改查。

ArrayList:允许集合存储的元素可以重复,并且可以将null存储到集合中,有一个默认容量并且集合长度是自动增长的。注意:线程是不安全的,如果多个线程同时访问一个ArrayList实例,有肯能会出现访问数据不一样的情况。

List lis= new ArrayList();

lis.add(“大根子”);

lis.add(“大根子”);

lis.add(520);

lis.add(‘a’);

System.out.println(lis);

输出结果:[大根子, 大根子, 520, a]

但是注意:List集合既增加了字符串类型的数据,又增加了整型的数据,会给程序带来危险。JDK1.5提出了泛型的概念,不允许不同类型的数组存在一个集合。

list<类型> 变量名 = new ArrayList<类型>();

List <String> lis= new ArrayList<String>();

lis.add(“大根子”);

lis.add(“大根子”);

lis.add(520);//报错

System.out.println(lis);

LinkedList:可以在集合的前面后面增加元素。注意:线程不安全,多个线程同时访问一个链接列表,有可能造成集合访问不同步。LinkedList类的iterator和listiterator方法可以遍历集合元素。

LinkedList <String> lis= new LinkedList<>();

lis.add(“大根子”);

lis.addFirst(“小根子”);

lis.addLast(“老根子”);

System.out.println(lis);

输出结果:[小根子, 大根子, 老根子]

HashSet:顺序不确定,允许使用null元素,不允许集合添加重复的元素,如果添加重复的元素将会覆盖之前的元素,注意:线程不同步,多个线程访问同一个HashSet,至少一个线程修改了该集合,可能造成数据访问不一致的情况发生。

Set<String> set =new HashSet<String>();

set.add(“大根子”);

set.add(“大根子”);

set.add(“小根子”);

System.out.println(set);

输出结果:[小根子, 大根子]

TreeSet:用来集合元素内部进行排序使用的;注意:TreeSet集合是线程不同步的。

Set<String> set=new TreeSet<String>(new Comparator<String>() {

@Override

public int compare(String o1, String o2) {

return o1.compareTo(o2);

}

});

set.add(“大根子”);

set.add(“小根子”);

set.add(“老根子”);

System.out.println(set);

输出结果:[大根子, 小根子, 老根子]

Comparable/comparable接口

Comparable接口主要用来对对象排序使用,这种排序被称为类的自然排序,类的comparaTo方法可以由用户自定义排序规则。Comparable接口中只有一个方法compareTo,定义如下:int
compareTo(To):比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回整数、零或正整数。

Iterator接口

Iterator接口用来遍历集合用的。

public interface Iterator<E>可以使用Iterator接口删除元素。

public static void main(String[] args) throws IllegalArgumentException {

// write your code here

iterator2List();

iterator2set();

}

public static void iterator2List() {

List<String> lis = new ArrayList<String>();

lis.add(“大根子”);

lis.add(“小根子”);

Iterator<String> it = lis.iterator();

while (it.hasNext()) {

String obj = it.next();

System.out.println(obj);

}

}

public static void iterator2set(){

//创建HashSet对象

Set<String> set =new HashSet<String>();

set.add(“大根子”);

set.add(“小根子”);

//获得Iterator接口

Iterator<String> it =set.iterator();

while(it.hasNext()){

String obj =it.next();

System.out.println(obj);

}

//删除

Iterator<String> it2 =set.iterator();

while(it2.hasNext()){

String obj =it2.next();

if(“大根子”.equals(obj)){

it2.remove();

}

for(String s:set){

System.out.println(s);

}

}

}

Map接口

Map接口可以存储键值对,并允许使用null值和null键,Map接口不保证映射的顺序。key-value。注意:线程不同步。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2et2sFDc-1617798717648)(media/06d963749ac527f483d04d209f80432e.png)]

public class Main {

public static void main(String[] args) throws IllegalArgumentException {

// write your code here

add();

}

public static void add(){

//创建HashMap对象

Map<String,String> map =new HashMap<String,String>();

//增加元素

map.put(“国家”,“中国”);

map.put(“国家”,“美国”);

map.put(“身份证”,“1234”);

String id = map.get(“身份证”);

System.out.println(id);

//取出所有的key

Set<String> keys =map.keySet();

for (String s:keys){

System.out.println(s);

}

//取出所有的value

Collection<String> cs=map.values();

for(String s:cs){

System.out.println(s);

}

//取出所有的key-value值

Set<Map.Entry<String,String>> sets =map.entrySet();

for(Map.Entry<String,String> s:sets){

String key = s.getKey();

String value= s.getValue();

System.out.println(key+":"+value);

}

}

}

输出结果:1234

国家

身份证

美国

1234

国家:美国

身份证:1234

容器选择原则

只需要增加值,可以考虑ArrayList集合,不重复使用HashSet集合,如果采用Key-Value这种情形,可以选择HashMap集合。

线程

线程简介和Java实现

进程是资源分配的最小单位,线程是CPU调度的最小单位。做个简单的比喻:进程=火车,线程=车厢;线程在进程下进行(单纯的车厢无法运行),一个进程可以包括很多线程(一个火车可以有很多车厢)不同进程之间数据很难共享(一辆火车上的乘客很难换到另一辆火车上),同一进程上的不同线程数据容易共享(A车厢到B车厢很容易),进程比线程更消耗计算机资源(多列火车比多个车厢更消耗资源)进程之间不相互影响,但是一个线程挂掉将会影响整个进程(一辆火车不会影响到另一个火车,但是一列火车中的一个车厢着火将会影响所有车厢)进程可以拓展到多级,线程最多适合多核(不同火车可以开在多个轨道上,同一火车的车厢不能在进行的轨道上)线程使用的内存地址可以上锁(一个线程使用某些共享内存,其它线程必须等待;互斥锁)进程使用的内存地址可以限定使用量(信号量)

主线程

每个Java都有一个主线程,也就是main函数

线程的创建和启动

创建有两种方式,分别继承Thread类和继承Runable接口

继承Thread类:当一个类需要按照多线程的方式处理,只需要继承Thread类,并且还要覆盖该类的run()方法。run方法作为线程的主体

public void run(){}

继承Thread类

public class Main {

public static void main(String[] args) throws IllegalArgumentException {

// write your code here

MyThread a = new MyThread();

a.start();

}

}

class MyThread extends Thread{

@Override

public void run() {

for(int i=0;i<10;i++){

System.out.println(“i=”+i);

}

}

}

输出结果:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M3XPxI2Q-1617798717649)(media/2d0bc301101bccef259c8306a2372d33.png)]

启动线程调用start方法而不是run方法,主要是由Java的内部实现机制决定的。

实现Runnable接口:启动时首先创建一个Thread对象,并将实现Runable接口类的实例放入Thread的构造器中。使用Runnable接口可以实现资源(对象属性)共享,但是Thread不可以。

public class Main {

public static void main(String[] args) throws IllegalArgumentException {

// write your code here

run a =new run();

Thread t= new Thread(a);

t.start();

}

}

class run implements Runnable{

@Override

public void run() {

for(int i=0;i<10;i++){

System.out.println(“i=”+i);

}

}

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-prhFTtcF-1617798717651)(media/2d0bc301101bccef259c8306a2372d33.png)]

线程组

线程组:线程组成的管理线程的类,这个类就是Java.lang.ThreadGroup类。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-072vcWmk-1617798717652)(media/aee6c8a20e8e821d14486a9697717f2b.png)]

线程状态

线程状态

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eUsAK9ab-1617798717653)(media/d28bfdf03f936610b9ce2f5ca7ad3bc2.png)]

初始:创建一个线程;可执行:调用start()方法;运行:调用run()方法;

停止:线程运行都需要占用CPU资源,一个线程运行完,其它线程都在等待,所以停止了;死亡:线程运行结束,中止。

线程状态转换

线程名字的取得和设置:线程运行不固定,取得线程名字,可以很好的知道线程情况。取得当前进程名字具体方法如下:

public static Thread currentThread()

public class Main {

public static void main(String[] args){

// write your code here

MyThread a1 =new MyThread();

MyThread a2 =new MyThread();

MyThread a3 =new MyThread();

a1.start();

a2.start();

a3.start();

}

}

class MyThread extends Thread{

public void run(){

System.out.println(“当前进程的名字为:”+Thread.currentThread().getName());

}

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uMAW7bWH-1617798717655)(media/485e5adeea91ec0bf10daf63e80bcc50.png)]

设置名字:对象.setName(“线程1”)

线程的休眠:线程在运行期间,会休息一段时间后再执行,休眠后,线程进入可运行状态。

public static void sleep(long millis) throws InterruptedException

倒计时效果:

public class Main {

private final static int count=20;

public static void main(String[] args){

// write your code here

new Thread() {

public void run(){

int temp = count;

for(int i=temp;i>=0;i–){

try{

Thread.sleep(1000);

}catch (InterruptedException e){

e.printStackTrace();

}

System.out.println(“还剩:”+(temp–)+“秒”);

}

}

}.start();

}

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FQXlaxzG-1617798717656)(media/875d0e72f79cb7f627f0841b966ab0f0.png)]

让线程之间通信

同步:给方法加锁,其它线程调用该方法时,如果锁解开了才能调用。关键字:synchronized,具体使用synchronized(对象){}包裹。锁代码块时,不必创建一个新的对象,直接使用this对象即可。但是锁不住静态方法,因为静态方法是属于整个类。

public class Main {

public static void main(String[] args){

// write your code here

final Main a = new Main();

//开辟两个线程

new Thread() {

public void run(){

while(true){

a.setName(“大根子”);

}

}

}.start();

new Thread() {

public void run(){

while(true){

a.setName(“小根子”);

}

}

}.start();

}

public void setName(String name){

String str =“hello”;

synchronized (str){

for(int i=0;i<name.length();i++){

System.out.println(name.charAt(i));

}

System.out.println();

}

}

}

异步:没有秩序,线程随机占用电脑资源。

死锁:多个线程同时被堵塞。

守护进程(后台进程或者精灵进程):所有前台线程运行完,不管后台线程有没有结束,守护线程都必须停止。

用I/O进行数据处理

文件

Java中文件操作所有类都在Java.io包里面,File类,只能创建文件、删除文件、对文件属性进行操作,不能对文件里面的内容进行读写操作。

目录管理:File中有一个listFiles()方法可以搜索某个目录下面所有的方法。

流和流的分类

文件的读写、网络收发和进程通信,几乎所有需要输入和输出的地方都要用到流。流是有源端和目的端。可以是计算机内存的某些区域,也可以是磁盘文件,甚至是Internet上的某个URL。在Java中,每个流都是一个对象。流通常分为两种,输入流和输出流。输入和输出的方向是对于程序而言,向程序中读入数据就是输入流,程序向外写出数据就是输出流。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C6Qc1qpJ-1617798717658)(media/1a681be0c1fbb2f7d89ff8f4e5ac3e8c.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uYo64IvJ-1617798717659)(media/8794cddac121e69aa83800fc0a2f1676.png)]

字节流和字符流

字节流:主要操作字节序列的对象,如二进制文件、图片及影像文件的操作

输出字节流:OutputStream(一个抽象类)ByteArrayOutputStream、FileOutputStream是两种基本的介质流,分别向Byte数组和本地文件写入数据。使用OutputStream定义如下:

public abstract class OutputStream extends object implements Closeable,Flushable

使用字节流输出内容:

public class Main {

public static void main(String[] args) throws IOException{

// write your code here

out();

}

public static void out() throws IOException{

OutputStream out = new FileOutputStream(“D:/hello.txt”);//获取对象

String info = “Hello java!!”;//输出的内容

byte[] buf =info.getBytes();//将内容转换成字节数组

out.write(buf);//写到文件里

out.close();//关闭文件

System.out.println(“over!”);

}

}

加强版的

public class Main {

public static void main(String[] args) throws IOException{

// write your code here

out();

}

public static void out() throws IOException{

OutputStream out =null;

try{

out= new FileOutputStream(“D:/Hello.txt”,true);//获取对象

String info =“Hello PHP!”;//输出的内容

byte[] buf =info.getBytes();//将内容转换成字节数组

out.write(buf);//写到文件

}catch(IOException e){

e.printStackTrace();

}finally {

try{

if(out!=null)

out.close();

}catch (IOException e){

e.printStackTrace();

}

}

}

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Kfm62jqp-1617798717661)(media/60e4e0e6d77165b91c48277eb5648e6b.png)]

输入字节流InputStream是所有的输入字节流的父类,是一个抽象类。ByteArrayInputStream、StringBufferInputStream、FileInputStream分别向Byte数组、StringBuffer和本地文件中读取数据。InputStream完成输入字节流定义如下:

public abstract class InputStream extends Object implements Closeable

实例:使用字节流读取文件内容

public class Main {

public static void main(String[] args) throws IOException {

// write your code here

in();

}

public static void in() throws IOException{

FileInputStream in =null;//获取对象

try{

in=new FileInputStream(“D:/Hello.txt”);//开辟一个空间

byte[] buf= new byte[1024];//读文件

int len=-1;

while((len=in.read(buf))!=-1){

String s =new String(buf,0,len);

System.out.println(s);

}

}catch (IOException e){

e.printStackTrace();

}finally {

try{

if(in!=null)

in.close();

}catch (IOException e){

e.printStackTrace();

}

}

}

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VxHCJa7i-1617798717662)(media/cdf62ee968de4943cf977ea6fa45094c.png)]

字符流:可以对流数据以一个字符的长度为单位来处理,并进行适当的字符编码转换处理。

字符输出流:Writer是字符输出流,该类是一个抽象类,需要子类FileWriter类来操作文件。

实例:public class Main {

public static void main(String[] args) throws IOException {

// write your code here

write();

}

public static void write() throws IOException{

FileWriter fw = new FileWriter(“D:/Hello.txt”,true);//获取对象

fw.write(“Hello C++”);//直接输出字节符

fw.close();//关闭

}

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FsIp2yzk-1617798717664)(media/a42b221f7d13cfbea9571b846f5fcc37.png)]

字符输入流:Reader是字符输入流,是一个抽象类,必须由子类FileReader来是例化。

public class Main {

public static void main(String[] args) throws IOException {

// write your code here

reader();

}

public static void reader() throws IOException{

Reader r =new FileReader(“D:/Hello.txt”);

char[] buf =new char[1024];

int len=0;

while((len=r.read(buf))!=-1){

String s =new String(buf,0,len);

System.out.println(s);

}

r.close();

}

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8A9q1BmO-1617798717666)(media/8973e8f55e8c5a30e621dbb7aaf7185c.png)]

过滤(处理)流

字节流通常只具有读写字节内容的方法,只能在文件中读取或者向文件中写入字节,但是在实际开发中需要在文件中写入各种类型的数据,如整型、布尔类型等数据,就必须先将其它类型的数据转换成字节数组后写入文件,或者将字节数组转换成其它数据类型。这个时候就需要包装类,这个类提供了向各种输出流写入各种类型数据的方法。

DataOutputStream必须给它一个输出流对象,完成类似DataOutputStream功能的类,就是处理流类。

DataInputStream与DataOutputStream类似,必须给一个输入流对象,才能完成过滤流的功能。

public class Main {

public static void main(String[] args) throws IOException {

// write your code here

writer();

reader();

}

public static void writer() throws IOException{

OutputStream os =new FileOutputStream(“D:/Hello.txt”);

DataOutputStream dos = new DataOutputStream(os);

dos.writeInt(123);

dos.writeBoolean(true);

dos.flush();//输出缓冲

dos.close();//关闭

}

public static void reader() throws IOException{

InputStream in =new FileInputStream(“D:/Hello.txt”);

DataInputStream dis =new DataInputStream(in);

int a= dis.readInt();

boolean flag= dis.readBoolean();

dis.close();

System.out.println(a);

System.out.println(flag);

}

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qTWqPKah-1617798717667)(media/1b1eab3ce77d72aef6bc1cae472fd5ab.png)]

内存操作流:输入输出的位置改为内存
缓冲流:数据先缓存起来,然后一起写入或者读取出来,使用缓冲流读写文件。BufferedReader、BufferedWriter、BufferedInputStream和BufferedOutputStream。

对象序列化与反序列化

序列化:将一个内存中保存的对象变成一个二进制的数据流进行传输,如果一个对象需要被序列化,则对象所在的类必须实现Serializable接口。使用ObjectOutputStream将对象写到文件中去。

反序列化:将文件中读取对象的过程。使用ObjeInputStream可以实现反序列化。

transient关键字:使用该关键字,可以是类中的某个属性不被序列化

序列化一组对象可以使用数组来解决。

打印流:Java提供了打印流PrintStream可以方便打印出文件

RandomAccessFile随机访问文件:可以随机读写文件

反射与注解

反射概念

反射机制可以在程序运行过程中获取对象的属性和方法。在一些底层技术上,如Struts、Hibernate、Spring框架上,反射会经常使用到。

class类

获取Class对象三种方法;

1.通过对象获取getClass()方法 对象名.getClass(); 2.通过Class.forName()获取
Class.forName(“包名.类名”); 3.通过类名.class获得Class对象 类名.class

public class Main {

public static void main(String[] args) throws ClassNotFoundException{

// write your code here

Class clazz =Class.forName(“com.company.Person”);

Class claz =Person.class;

Person p =new Person();

Class cla=p.getClass();

}

}

用反射获取类的属性

public class Main {

public static void main(String[] args) throws Exception{

// write your code here

Class clazz =Person.class;//第一步获取Class对象

Object obj =clazz.newInstance();//将对象实例化

Field filed =clazz.getField(“id”);//获取Field字段对象

String idname= filed.getName();//获取Field字段名称

Integer idValue=(Integer) filed.get(obj);//获取Field的值

System.out.println(“获取的”+idname+"="+idValue);

filed.set(obj,10);//设置id值

Integer idV=(Integer) filed.get(obj);

System.out.println(“设置的”+idname+"="+idV);

}

}

public class Person implements Serializable {

private transient String name;

private int age;

public int id=-1;

}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rZxYDfFY-1617798717669)(media/0c7057ca4a0531a811a42fec53f8a9b0.png)]

用反射可以获取类的方法、构造方法、操作数组。

注解

annotation注解:功能类似于代码中的注释,但是可以实现程序功能。在Java中常见的注解有@Override和@SuperssWarnings,@Override(标记注解)只需要在方法前面声明即可。使用@SuperssWarnings语法:@SuperssWarnings({“uncheck”,“unused”})

括号内容为该注解可供配置的值;注解作用:生成文档,跟踪代码(替代配置文件),在编译时进行格式检查,如@Override放在方法面前,如果这个方法并不是覆盖了超类方法,编译就会出错。

常用注解

@Override:覆盖超类方法 @Deprecated:表示当前元素是不赞成使用的 @
SuperssWarnings:表示关闭一些不当的编译器警告信息

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Uxc7wu54-1617798717670)(media/60d740933e2305f95f9a920f9b43a0a6.png)]

数据库技术

MySQL

SQL(Structed Query
language)j结构化查询语言,主要访问和处理数据库的计算机语言。在MySQL中有一个大单位叫数据库(Database),MySQL中可以建立多个数据库(Database)都有若干个表(table)。

MySQL的数据类型:数值类型、字符串类型、日期和时间类型。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SIjdqTtb-1617798717671)(media/2206adab16a315aa9ddee49cd99c7a77.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TinhmoMp-1617798717673)(media/8f0e605b60b456172a77ec722402ab02.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OBe0vjh3-1617798717674)(media/d986751af2abeeab67fd7e8dcfc87d5a.png)]

**创建数据库:**create database xuru default character set
utf8;//创建数据设置编码为utf8

**创建表:**表必须在数据库中创建,use xuru;之后创建表create table 表名(z字段
字段类型…)

create table gongwuyaun(

id int primary key auto_increment,

name varchar(32),

salary double;

age int;

)

primary key:主键,代表唯一标识的,并且不能重复

auto_increment:自动增长,每插入一条新的记录,数据库会自动生成一个值。

对表中的数据进行增删改查

**insert语句(在表中插入数据):**insert into
表名(字段1,字段2…)values(值1,值2…)

insert into
gongwuyuan(name,salary,age)values(‘xuru’,2000,20)数据库字符串类型使用单引号表示。

**select语句(在表中查询数据):**select * from 表名//查询所有数据 select
字段1,字段2…from表名 //查询某几个字段的数据

update语句(在表中对数据进行修改):update 表名 set 字段1=值1,字段2=值2……

update gongwuyuan set age= 30;

**delete语句(在表中删除语句):**delete from 表名

delete from gongwuyuan;

where语句(关键字进行过滤):select * from 表名 where 条件表达式

update from 表名 set 字段1=值1,…where条件表达式

delete from 表名 where 条件表达式

条件表达式运算符:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YhPlgYVl-1617798717676)(media/06f17363013781a7baf4ba92bd8d75e3.png)]

查询字段id不等于2的所有数据

select * from gongwuyuan where id<>2;

聚合函数与having:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7KbllRew-1617798717677)(media/1e6a905f41892ebc4db60bad0a2cea1e.png)]

goup
by语句
(通过一定的规则将一个数据集划分成若干个小的区域,然后针对性的对若干个小区域进行数据处理)

select count(*),name from gongwuyuan froup by name;

用JDBC与数据库交互

JDBC(Java Data base Connectivity)是一种用于执行SQL语句的Java
API,由Java语言编写的类和接口组成。JDBC设有两种接口,一个是面向应用程序层(开发成员通过SQL调用数据),一个是驱动程序层(利用JDBC
API使得Java可以方便的操作数据库)。客户端程序调用Java.sql包下面的API,Java.sql下的API调用相应的驱动程序,驱动程序调用相应的数据库,从而完成对数据库的操作。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hP4uwhdu-1617798717679)(media/3c1059cc3a752bf5d59a58890c78e26c.png)]

Java与MySQL连接

Java连接MySQL数据库分为几大步骤:

  1. 加载驱动程序 Class.forName(“com.mysql.jdbc.Driver”);

  2. 创建数据连接对象(通过DriverManager类创建数据库连接对象Connection),DriverManager类作用于Java程序和JDBC驱动程序之间,用于检查它们之间是否可以连接,然后通过getConnection方法,根据数据库的URL、用户名、密码,创建一个JDBC
    Connection对象

Connection connection = DriverMannager.getConnection(“URL”,“用户名”,“密码”);

(3)创建Statement对象(Statement对象主要是执行静态SQL语句并返回它所生成结果的对象)

Statement statement = conn.createStatement();

(4)调用Statement对象相关方法去执行对于SQL语句

例:通过execuUpdate()方法来数据的更新,包括插入和删除操作

statement.execuUpdate(“insert into gongwuyuan (name,salary,age) values
(‘s’,2000,20)”);

之后查询的结果会得到ResulSet对象

ResulSet resulSel = statement.executeQuery(“select * from gongwuyuan”);

(5)关闭数据库连接

conn.close();

XML技术

XML

XML是标记扩展语言,用来存储数据的。作用:作为软件的配置文件使用;存储传输数据,而非显示数据。

XML分为文档声明、元素、属性、注释、CDATA区、处理命令。一个XML文档只能允许一个根元素,根元素下面可以拥有多个子元素,每个子元素有多个属性。

文档声明:声明文档类型

<?xml version=“1.0”encoding=“GB2312”standalone=“yes”?>

encoding属性说明文档的字符编码;standalone属性说明文档是否独立

**元素就是标签:**标签分为开始标签和结束标签。注意:标签中出现的所有空格和换行,XML解析程序都会当作标签内容进行处理。

**属性:**每个属性都有它自己的名称和取值

<input type=“text”>也可以改用子元素来使用

<input>

<name>text</name>

</input>

注释:<!–注释–>

CDATA区:在编写XML文件时,如果希望一些特殊的字符显现出来可以使用CDATA语法。

软件工程

MVC;分为视图层(View)表现界面、控制层(Controller)负责业务层与表现层的交互、业务层(Model)对数据库进行一些操作

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wWBChg4D-1617798717681)(media/8a1bdddb73dc78cec98d2041324f62c3.png)]

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值