JavaSE基础教程

更新时间:2023-11-16 12:55:01 阅读量: 教育文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

JavaSE

一、java语言概述

1.软件 : 系统软件 vs 应用软件

2.人与计算机做交互:使用计算机语言。 图形化界面 vs 命令行方式 dir md rd cd cd.. cd/ del exit

3.语言的分类:第一代:机器语言 第二代:汇编语言 第三代:高级语言(面向过程 --- 面向对象) 4.java语言的特性:①面向对象性 ②健壮性 ③跨平台性(write once ,run anywhere)---JVM 5.安装JDK及配置path环境变量 1)傻瓜式安装JDK。 2)path:window操作系统在执行命令时所要搜寻的路径。 我们需要将jdk中bin目录所在的路径:D:\\Java\\jdk1.7.0_07\\bin 保存在path环境变量下。 3)测试:在命令行窗口,任意的文件目录下,执行javac.exe 或者java.exe都可以调用成功。

>河床好比操作底层,jdk好比是河水,java应用程序好比是船。 注意:JDK JRE JVM

6.如何编写并运行第一个java程序 【过程】编写----编译----运行

1)编写:每一个java文件都是.java结尾的,称为源文件【HelloWorld.java】。java程序就存在于源文件中

public class HelloWorld{

//程序的主方法,是程序的入口 public static void main(String args[]){ //要执行的代码

System.out.println(\} }

注意点:

Java源文件以“java”为扩展名。源文件的基本组成部分是类(class),如本类中的HelloWorld类。

一个源文件中最多只能有一个public类。其它类的个数不限,如果源文件包含一个public类,则文件名必 须按该类名命名。

Java应用程序的执行入口是main()方法。它有固定的书写格式:public static void main(String[] args) {...} Java语言严格区分大小写。

Java方法由一条条语句构成,每个语句以“;”结束。 大括号都是成对出现的,缺一不可。

2)编译: 在源文件所在的目录下,执行javac.exe 源文件名.java;生成诸多个.class结尾的字节码文件 3)运行:生成的字节码文件通过java.exe解释执行

7.会调试程序中出现的问题

8.注释: ①单行注释 // ②多行注释 /* */ (多行注释不能够嵌套)

③文档注释 /** */ javadoc -d 文件目录名 -author -version 源文件名.java;

9.JDK提供的关于旗下所有的包、类的文档:API 二、基本语法

(一)关键字 & 标识符

关键字:被Java语言赋予了特殊含义,用做专门用途的字符串(单词)

保留字:

标识符:凡是自己可以起名字的地方都叫标识符

命名的规则:(一定要遵守,不遵守就会报编译的错误) 由26个英文字母大小写,0-9 ,_或 $ 组成 数字不可以开头。

不可以使用关键字和保留字,但能包含关键字和保留字。 Java中严格区分大小写,长度无限制。 标识符不能包含空格。

Java中的名称命名规范:(不遵守,也不会出现编译的错误) 包名:多单词组成时所有字母都小写:xxxyyyzzz

类名、接口名:多单词组成时,所有单词的首字母大写:XxxYyyZzz 变量名、方法名:多单词组成时,第一个单词首字母小写,第二个单词开始每个单词首字母大写:xxxYyyZzz 常量名:所有字母都大写。多单词时每个单词用下划线连接:XXX_YYY_ZZZ (二)变量

1.java中变量按照数据类型来分类:基本数据类型 vs 引用数据类型(数组 类 接口) >基本数据类型:

整型:byte(8 bit) short int(默认类型) long 浮点型:float double (默认类型) 字符型:char(‘ ’)

布尔类型: boolean(只能取值为true 或false,不能取null)

补充:按照在类中存在的位置的不同:成员变量 vs 局部变量

2.进制(了解)

十进制 二进制 八进制 十六进制

二进制:计算机底层都是用二进制来存储、运算。 >二进制 与十进制之间的转换。 >二进制在底层存储:正数、负数都是以补码的形式存储的。(原码、反码、补码) >四种进制间的转换

3.变量的运算:

①自动类型转换:容量小的数据类型自动转换为容量大的数据类型。 short s = 12; int i = s + 2;

注意:byte short char之间做运算,结果为int型! ②强制类型转换:是①的逆过程。使用“()”实现强转。 (三)运算符

运算符是一种特殊的符号,用以表示数据的运算、赋值和比较等。 算术运算符:

+ - + - * / % ++ -- +

注意:1) /: int i = 12; i = i / 5; 2) %:最后的符号只跟被模数相同 3)前++:先+1,后运算 后++:先运算,后+1 4)+:String字符串与其他数据类型只能做连接运算,且结果为String类型。sysout('*' + '\\t' + '*'); vs sysout(\

赋值运算符:

= += -= *= /= %= int i= 12; i = i * 5;

i *= 5;//与上一行代码同样的意思 【特别地】 short s = 10;

s = s + 5;//报编译的异常 s = (short)(s + 5);

s += 5;//s = s + 5,但是结果不会改变s的数据类型。

比较运算符(关系运算符) == ><>= <= instanceof

【注意】区分== 与 = 区别。

进行比较运算操作以后,返回一个boolean类型的值 4>=3 表达的是4 > 3或者 4 = 3.结果是true。

if(i > 1 && i < 10){ } 不能写为:if(1 < i < 10){}

逻辑运算符(运算符的两端是boolean值) &&& | || ^ !

【注意】区分 & 与 && 的区别,以及 | 与 || 的区别 我们使用的时候,选择&& , ||

位运算符(两端是数值类型的数据) <<>>>>>& | ^ ~

【例子】1.如何交换m = 12和n = 5的值

2.将60转换为十六进制输出。 三元运算符

(条件表达式)? 表达式1 : 表达式2;

1)既然是运算符,一定会返回一个结果,并且结果的数据类型与表达式1,2的类型一致 2)表达式1与表达式2 的数据类型一致。

3)使用三元运算符的,一定可以转换为if-else。反之不一定成立。 例子:获取两个数的较大值;获取三个数的最大值。 (四)流程控制

1.顺序结构

>程序从上往下的顺序执行

2.分支结构: if-else switch-case

3.循环结构: while(){} do{}while() for(;;){}

4.1分支结构

1.条件判断:

①if(条件表达式){ }

②if(条件表达式){ //执行的语句1; }else{ //执行的语句2; }

③if(条件表达式1){ //执行的语句1; }else if(条件表达式2){ //执行的语句2; }else if( 条件表达式3){ //执行的语句3; }... }else{

//执行的语句; }

【注意】

1.一旦满足某个条件表达式,则进入其执行语句块执行,执行完毕,跳出当前的条件判断结构,不会执行其以下的条件结构语句。

2.如果诸多个条件表达式之间为“互斥”关系,多个结构可以上下调换顺序

如果诸多个条件表达式之间为“包含”关系,要求条件表达式范围小的写在范围大的上面。

2.选择结构 switch(变量){ case 值1: //break;

case 值2: //break; ... default: break; }

【注意】

1.变量可以为如下的数据类型:byte short int char 枚举 String 2.case后只能填写变量的值,不能写范围。

3.default是可以省略的。并且其位置也是灵活的,但是通常将其放在case语句之后。 4.一旦满足某个case语句,则进入执行其操作。直至遇到break或者程序终止。

5.若要判断的语句的条件满足switch变量的数据类型,且值不多的情况下,建议选择switch-case . 除此之外,选择if-else.

4.2循环结构

1.格式:

①初始化条件 ②循环条件 ③迭代部分 ④循环体

for(①;②;③){ ④ } ①

while(②){ ④ ③ }

① do{

④ ③ }while(②);

注:1.不同的循环结构之间可以相互转换

2.while和do-while的区别:do-while程序至少会执行一次

2.嵌套循环:循环结构还可以声明循环。让内层循环结构整体充当外层循环的循环体。 若外层循环执行m次,内层循环执行n次,整个程序执行m*n次。

【题目】 ****** ****** ******

for(int i = 0;i < 3;i++){ for(int j = 0;j < 6;j++){ System.out.print(\ } System.out.println(); }

说明:外层循环控制行数,内层循环控制列数 【例题】1.九九乘法表 2.输出100内的质数。(两种)

3.无限循环结构 for(;;){ ... if( ){ break;

} ... }

或者

while(true){ ... if( ){ break; } ... }

往往我们在无限循环结构内部提供循环的终止条件,使用break关键字。否则,此循环将无限制的执行下去,形成死循环!

死循环是我们要避免的。 4.3break&continue

break:

>使用switch-case结构或者循环结构中

>在循环结构中,一旦执行到break,就跳出当前循环。

continue:使用在循环结构中

>一旦执行到continue,就跳出当次循环。

for(int i = 1;i <= 10;i++){ if(i % 4 == 0){ //break; //123 continue; //123567910 } System.out.print(i); }

在嵌套循环中,使用带标签的break和continue。 label:for(int i = 1;i < 5;i++){ for(int j = 1;j <= 10;j++){ if(j % 4 == 0){ //break; //continue; //break label; continue label; } System.out.print(j); } System.out.println(); }

(五)数组

二维数组

数组的常见异常

//1.数组下标越界的异常:java.lang.ArrayIndexOutOfBoundsException int[] i = new int[10]; // i[0] = 90; // i[10] = 99; // for(int m = 0;m <= i.length;m++){ // System.out.println(i[m]); // } //2.空指针的异常:NullPointerException //第一种: // boolean[] b = new boolean[3]; // b = null; // System.out.println(b[0]); // // //

//第二种:

String[] str = new String[4];

//str[3] = new String(\System.out.println(str[3].toString());

//第三种:

int[][] j = new int[3][]; j[2][0] = 12;

数组的常用的算法问题

1.求数组元素的最大值、最小值、和、平均数

2.数组的复制和反转 情况1:

情况2:(如何实现复制)

数组的反转:

// 数组元素的反转

// for(int i = 0;i < arr.length/2;i++){ // int temp = arr[i];

// arr[i] = arr[arr.length-1 - i]; // arr[arr.length - 1 - i] = temp; // }

for (int x = 0, y = arr.length - 1; x < y; x++, y--) { int temp = arr[x]; arr[x] = arr[y]; arr[y] = temp; }

拓展:String str = \

数组的排序:

插入排序

直接插入排序、折半插入排序、Shell排序

交换排序

冒泡排序、快速排序(或分区交换排序)

选择排序

简单选择排序、堆排序 归并排序

基数排序

// 使用冒泡排序使数组元素从小到大排列 // for (int i = 0; i < arr.length - 1; i++) { // for (int j = 0; j < arr.length - 1 - i; j++) { // if (arr[j] > arr[j + 1]) { // int temp = arr[j]; // arr[j] = arr[j + 1]; // arr[j + 1] = temp; // } // } // } // //使用直接选择排序使数组元素从小到大排列 // for(int i = 0; i < arr.length - 1; i++){

// int t = i;//默认i处是最小的 // for(int j = i;j < arr.length;j++){ // //一旦在i后发现存在比其小的元素,就记录那个元素的下角标 // if(arr[t] > arr[j]){ // t = j; // } // } // if(t != i){ // int temp = arr[t]; // arr[t] = arr[i]; // arr[i] = temp; // } // }

还可以调用:Arrays工具类:Arrays.sort(arr);

三、面向对象(一)

1.类及对象

1.关于于类的设计

2.类的组成成分:

1) 属性(成员变量,Field)

2)方法(成员方法,函数,Method)

2.1属性:

* 成员变量 vs 局部变量

* 相同点:1.遵循变量声明的格式: 数据类型 变量名 = 初始化值 * 2.都有作用域

* 不同点:1.声明的位置的不同 :成员变量:声明在类里,方法外 * 局部变量:声明在方法内,方法的形参部分,代码块内 * 2.成员变量的修饰符有四个:public private protected 缺省 * 局部变量没有修饰符,与所在的方法修饰符相同。 * 3.初始化值:一定会有初始化值。

* 成员变量:如果在声明的时候,不显式的赋值,那么不同数据类型会有不同的默认初始化值。 * byte short int long ==>0 * float double ==>0.0 * char ==>空格 * boolean ==>false

* 引用类型变量==>null

* 局部变量:一定要显式的赋值。(局部变量没有默认初始化值)

* 4.二者在内存中存放的位置不同:成员变量存在于堆空间中;局部变量:栈空间中 *

* 总结:关于变量的分类:1)按照数据类型的不同:基本数据类型(8种) & 引用数据类型 * 2)按照声明的位置的不同:成员变量 & 局部变量

2.2 方法:提供某种功能的实现

* 1)实例:public void eat(){//方法体} * public String getName(){}

* public void setName(String n){}

* 格式:权限修饰符 返回值类型(void:无返回值/具体的返回值) 方法名(形参){} *

* 2)关于返回值类型:void:表明此方法不需要返回值 * 有返回值的方法:在方法的最后一定有return + 返回值类型对应的变量 * 记忆:void 与return不可以同时出现一个方法内。像一对“冤家”。 *

* 3)方法内可以调用本类的其他方法或属性,但是不能在方法内再定义方法!

3.面向对象编程的思想的落地法则一: 1)设计并创建类及类的成分 2)实例化类的对象

3)通过“对象.属性”或\对象.方法\的形式完成某项功能

4.类的初始化的内存解析 4.1 内存划分的结构:

栈(stack):局部变量 、对象的引用名、数组的引用名 堆(heap):new 出来的“东西”(如:对象的实体,数组的实体),含成员变量 方法区:含字符串常量

静态域:声明为static的变量

4.2 理解的基础上,学会基本的创建的类的对象在内存中的运行。

2.方法的重载

* 方法的重载(overload)

* 要求:1.同一个类中 2.方法名必须相同 3.方法的参数列表不同(①参数的个数不同②参数类型不同) * 补充:方法的重载与方法的返回值类型没有关系!

//如下的四个方法构成重载 //定义两个int型变量的和 public int getSum(int i,int j){ return i + j; }

//定义三个int型变量的和 public int getSum(int i,int j,int k){ return i + j + k; }

//定义两个double型数据的和

public double getSum(double d1,double d2){ return d1 + d2; }

//定义三个double型数组的和

public void getSum(double d1,double d2,double d3){ System.out.println(d1 + d2 + d3); }

//不能与如上的几个方法构成重载 // public int getSum1(int i,int j,int k){ // return i + j + k; // }

// public void getSum(int i,int j,int k){ // System.out.println(i + j + k); // }

//以下的两个方法构成重载。 public void method1(int i,String str){ }

public void method1(String str1,int j){ }

3.可变个数的形参的方法

* 可变个数的形参的方法:

* 1.格式:对于方法的形参: 数据类型 ... 形参名 * 2.可变个数的形参的方法与同名的方法之间构成重载

* 3.可变个数的形参在调用时,个数从0开始,到无穷多个都可以。 * 4.使用可变多个形参的方法与方法的形参使用数组是一致的。

* 5.若方法中存在可变个数的形参,那么一定要声明在方法形参的最后。 * 6.在一个方法中,最多声明一个可变个数的形参。

2.通过\类实现类的继承。 * 子类:A 父类(或基类 SuperClass):B *

* 3.子类继承父类以后,父类中声明的属性、方法,子类就可以获取到。

* 明确:当父类中有私有的属性或方法时,子类同样可以获取得到,只是由于封装性的设计,使得子类不可以直接

* 调用罢了。

* 子类除了通过继承,获取父类的结构之外,还可以定义自己的特有的成分。 *

* extends:子类是对父类功能的“扩展”,明确子类不是父类的子集。 * * 4.java中类的继承性只支持单继承:一个类只能继承一个父类。反之,一个父类可以有多个子类。 * 5.子父类是相对的概念。

1.方法的重写(override orverwrite) vs 重载(overload)

【面试题】方法的重载与重写的区别? 重载:“两同一不同”:同一个类,同一个方法名,不同的参数列表。 注:方法的重载与方法的返回值无关! >构造器是可以重载的 重写:(前提:在继承的基础之上,子类在获取了父类的结构以后,可以对父类中同名的方法进行“重构”) 方法的返回值,方法名,形参列表形同;权限修饰符不小于父类的同名方法;子类方法的异常类型不大于父类的;

两个方法要同为static或同为非static。

public void method1(String[] str,int age) throws Exception{ }

class Cirlce{

//求圆的面积

public double findArea(){

} }

class Cylinder extends Circle{ //求圆柱的表面积

public double findArea(){ } }

2.关键字super

1.super,相较于关键字this,可以修饰属性、方法、构造器

2.super修饰属性、方法:在子类的方法、构造器中,通过super.属性或者super.方法的形式,显式的调用父类的指定

属性或方法。尤其是,当子类与父类有同名的属性、或方法时,调用父类中的结构的话,一定要用“super.”

3.通过“super(形参列表)”,显式的在子类的构造器中,调用父类指定的构造器! >任何一个类(除Object类)的构造器的首行,要么显式的调用本类中重载的其它的构造器“this(形参列表)”或显式的调用父类中

指定的构造器“super(形参列表)”,要么默认的调用父类空参的构造器\>建议在设计类时,提供一个空参的构造器!

3.子类对象实例化的全过

//子类对象实例化的全过程 public class TestDog { public static void main(String[] args) { Dog d = new Dog(); d.setAge(10);

d.setName(\小明\ d.setHostName(\花花\ System.out.println(\ + \ System.out.println(d.toString()); } }

// 生物

class Creator { private int age; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Creator() { super(); System.out.println(\ } }

// 动物类

class Animal extends Creator { private String name; public String getName() { return name;

}

}

public void setName(String name) { this.name = name; }

public Animal() { super(); System.out.println(\}

// 狗

class Dog extends Animal { private String hostName; public String getHostName() { return hostName; } public void setHostName(String hostName) { this.hostName = hostName; } public Dog() { super(); System.out.println(\ } }

4.面向对象的特征三:多态性

1.多态性的表现:①方法的重载与重写 ②子类对象的多态性 2.使用的前提:①要有继承关系 ②要有方法的重写 3.格式:Person p = new Man();//向上转型

// 虚拟方法调用:通过父类的引用指向子类的对象实体,当调用方法时,实际执行的是子类重写父类的方法

p1.eat(); p1.walk(); // p1.entertainment();

4.>编译时,认为p是Person类型的,故只能执行Person里才有的结构,即Man里特有的结构不能够调用 >子类对象的多态性,并不使用于属性。

5.关于向下转型:

①向下转型,使用强转符:()

②为了保证不报ClassCastException,最好在向下转型前,进行判断: instanceof // 若a是A类的实例,那么a也一定是A类的父类的实例。

if (p1 instanceof Woman) { System.out.println(\ Woman w1 = (Woman) p1; w1.shopping(); }

if (p1 instanceof Man) { Man m1 = (Man) p1; m1.entertainment(); }

Object类

1.java.lang.Object 类,是所有类的根父类!

2.Object类仅有一个空参的构造器 public Object(){ }

3.关于方法:

① equals(Object obj)

public boolean equals(Object obj) { return (this == obj); } // ==

// 1.基本数据类型:根据基本数据类型的值判断是否相等。相等返回true,反之返回false // 注:两端数据类型可以不同,在不同的情况下,也可以返回true。 // 2.引用数据类型:比较引用类型变量的地址值是否相等。

//equals():

>①只能处理引用类型变量②在Object类,发现equals()仍然比较的两个引用变量的地址值是否相等 >像String 包装类 File类 Date类这些重写Object类的equals()方法,比较是两个对象的 //\实体内容\是否完全相同。

>若我们自定义一个类,希望比较两个对象的属性值都相同的情况下返回true的话,就需要重写Object类的

equals(Object obj)方法

② toString()方法

当我们输出一个对象的引用时,会调用toString()方法。 1.public String toString() {

return getClass().getName() + \ }

当我们没有重写Object类的toString()方法时,打印的就是对象所在的类,以及对象实体在堆空间的位置 2.一般我们需要重写Object类的toString()方法,将此对象的各个属性值返回。 3.像String类、Date、File类、包装类都重写了toString()方法。 包装类

基本数据类型由于不是类,不能够使用java类库里提供的大量的方法。所有在设计上, 我们让每一个基本数据类型都对应一个类,同时数据存储的范围还不变。此时相当于 基本数据类型就具有了类的特点。这些类即为包装类(wrapper 或封装类)

我们需要掌握的:

基本数据类型、包装类、String类之间的转换!

简易版:

1.基本数据类型与对应的包装类有自动装箱、自动拆箱 如:int i = 10;

Integer i1 = i;//自动装箱 int j = i1;//自动拆箱

2.基本数据类型、包装类---->String类:调用String类的重载的valueOf(Xxx xx); String类---->基本数据类型、包装类:调用相应的包装的parseXxx(String str); 注意:String str = \

int i = (int)str;是错误的转法。

五、面向对象(三)

1.static关键字

1.static:静态的,可以用来修饰属性、方法、*代码块(或初始化块)、*内部类 2.

static修饰属性(类变量):

* 1.由类创建的所有的对象,都共用这一个属性

* 2.当其中一个对象对此属性进行修改,会导致其他对象对此属性的一个调用。vs 实例变量(非static修饰的属性,各个对象各自拥有一套副本)

* 3.类变量随着类的加载而加载的,而且独一份

* 4.静态的变量可以直接通过“类.类变量”的形式来调用

* 5.类变量的加载是要早于对象。所以当有对象以后,可以“对象.类变量”使用。但是\类.实例变量\是不行的。

* 6.类变量存在于静态域中。 * * static修饰方法(类方法):

* 1.随着类的加载而加载,在内存中也是独一份 * 2.可以直接通过“类.类方法”的方式调用

* 3.内部可以调用静态的属性或静态的方法,而不能调用非静态的属性或方法。反之,非静态的方法是可以调用静态的属性或静态的方法

* >静态的方法内是不可以有this或super关键字的!

* 注:静态的结构(static的属性、方法、代码块、内部类)的生命周期要早于非静态的结构,同时被回收也要晚于非静态的结构

public class TestCircle { public static void main(String[] args) { Circle c1 = new Circle(); Circle c2 = new Circle(2.3); System.out.println(c1); System.out.println(c2); System.out.println(Circle.getTotal());

} }

class Circle{ private double radius;

private static String info = \我是一个圆\private int id;//编号

private static int init = 1001;//控制每个对象的id private static int total = 0;//记录创建了多少个对象

public Circle(){ this.id = init++; total++; }

public Circle(double radius){ this.radius = radius; this.id = init++; total++; }

public double getRadius() { return radius; }

public void setRadius(double radius) { this.radius = radius; }

public static String getInfo() { return info; }

public static void setInfo(String info) { Circle.info = info; }

public int getId() { return id; }

public void setId(int id) { this.id = id; }

public static int getTotal() { return total; }

public static void setTotal(int total) { Circle.total = total; }

@Override

public String toString() { return \

}

}

public static void show(){ System.out.println(Circle.info); }

public void desc(){ System.out.println(this.info); }

单例模式

23种设计模式

单例模式:

解决的问题:如何只让设计的类只能创建一个对象 如何实现:饿汉式 & 懒汉式 //饿汉式1 class Bank{

//1.私有化构造器 private Bank(){}

//2.创建类的对象,同时设置为private的,通过公共的来调用,体现封装性 //4.要求此对象也为static的 private static Bank instance = new Bank(); //3.此公共的方法,必须为static public static Bank getInstance(){ return instance; } }

//饿汉式2 class Bank{ //1.私有化构造器 private Bank(){} //2.创建类的对象,同时设置为private的,通过公共的来调用,体现封装性 //4.要求此对象也为static的 private static Bank instance = null; static{ instance = new Bank(); } //3.此公共的方法,必须为static public static Bank getInstance(){ return instance; } }

//懒汉式 class Bank{ private Bank(){}

}

private static Bank instance = null;

public static Bank getInstance(){ }

if(instance == null){//可能存在线程安全问题的! instance = new Bank(); }

return instance;

2.main()方法

public static void main(String[] args){ //方法体 }

//1.main()是一个方法,是主方法,为程序的入口

//2.权限修饰符:public protected 缺省 private ---面向对象的封装性 //3.对于方法来讲:static final abstract

//4.方法的返回值:void / 具体的返回值类型(基本的数据类型 & 引用数据类型),方法内部一定要有return

//5.方法名:命名的规则:xxxYyyZzz。给方法命名时,要见名之意

//6.形参列表:同一个方法名不同的形参列表的诸多个方法间构成重载。 形参 & 实参---方法的参数传递机制:值传递

//7.方法体:方法定义的是一种功能,具体的实现由方法体操作。 3.代码块

代码块:是类的第4个成员 作用:用来初始化类的属性 分类:只能用static来修饰。

* 静态代码块:

* 1.里面可以有输出语句

* 2.随着类的加载而加载,而且只被加载一次 * 3.多个静态代码块之间按照顺序结构执行

* 4.静态代码块的执行要早于非静态代码块的执行。

* 5.静态的代码块中只能执行静态的结构(类属性,类方法) *

* 非静态代码块:

* 1.可以对类的属性(静态的 & 非静态的)进行初始化操作,同时也可以调用本类声明的方法(静态的 & 非静态的)

* 2.里面可以有输出语句

* 3.一个类中可以有多个非静态的代码块,多个代码块之间按照顺序结构执行 * 4.每创建一个类的对象,非静态代码块就加载一次。 * 5.非静态代码块的执行要早于构造器 *

* 关于属性赋值的操作: ①默认的初始化

②显式的初始化或代码块初始化(此处两个结构按照顺序执行) ③构造器中;

—————————以上是对象的属性初始化的过程—————————————

④通过方法对对象的相应属性进行修改 4.final关键字

/*

* final:最终的 ,可以用来修饰类、属性、方法 *

* 1.final修饰类:这个类就不能被继承。如:String类、StringBuffer类、System类 *

* 2.final修饰方法:不能被重写。如:Object类的getClass() *

* 3.final修饰属性:此属性就是一个常量,一旦初始化后,不可再被赋值。习惯上,常量用大写字符表示。 * 此常量在哪里赋值:①此常量不能使用默认初始化 ②可以显式的赋值、代码块、构造器。 *

* 变量用static final修饰:全局常量。比如:Math 类的PI *

* >与finally finalize()区分开 * */

class D{ final int I = 12; final double PI; final String NAME; public void m1(){ System.out.println(I); // I = 10; } { PI = 3.14; } public D(){ NAME = \ } public D(String name){ this(); //NAME = name; } }

5.抽象:abstract

重点!

abstract:抽象的,可以用来修饰类、方法

* 1.abstract修饰类:抽象类 * 1)不可被实例化

* 2)抽象类有构造器 (凡是类都有构造器) * 3)抽象方法所在的类,一定是抽象类。

* 4)抽象类中可以没有抽象方法。

* >当我们设计一个类,不需要创建此类的实例时候,就可以考虑将其设置为抽象的,由其子类实现这个类的抽象方法以后,就行实例化

* * 2.abstract修饰方法:抽象方法

* 1)格式:没有方法体,包括{}.如:public abstract void eat();

* 2)抽象方法只保留方法的功能,而具体的执行,交给继承抽象类的子类,由子类重写此抽象方法。 * 3)若子类继承抽象类,并重写了所有的抽象方法,则此类是一个\实体类\即可以实例化

* 4)若子类继承抽象类,没有重写所有的抽象方法,意味着此类中仍有抽象方法,则此类必须声明为抽象的!

模板方法的设计模式

//模板方法设计模式 public class TestTemplate { public static void main(String[] args) { new SubTemplate().spendTime(); } }

abstract class Template { public abstract void code(); public void spendTime() { long start = System.currentTimeMillis(); this.code(); long end = System.currentTimeMillis(); System.out.println(\花费的时间为:\ } }

class SubTemplate extends Template { public void code() { boolean flag = false; for(int i = 2;i <= 10000;i++){ for(int j = 2;j <= Math.sqrt(i);j++){ if(i % j == 0){ flag = true; break; } } if(!flag){ System.out.println(i); } flag = false; } }

}

6.接口interface

* 接口(interface) 是与类并行的一个概念

* 1.接口可以看做是一个特殊的抽象类。是常量与抽象方法的一个集合,不能包含变量、一般的方法。 * 2.接口是没有构造器的。

* 3.接口定义的就是一种功能。此功能可以被类所实现(implements)。 * 比如:class CC extends DD implements AA

* 4.实现接口的类,必须要重写其中的所有的抽象方法,方可实例化。若没有重写所有的抽象方法,则此类仍为一个抽象类

* 5.类可以实现多个接口。----java 中的类的继承是单继承的 * 6.接口与接口之间也是继承的关系,而且可以实现多继承 * >5,6描述的是java中的继承的特点。 * 7.接口与具体的实现类之间也存在多态性

* 8.面向接口编程的思想: 工厂方法的设计模式

//接口的应用:工厂方法的设计模式 public class TestFactoryMethod { public static void main(String[] args) { IWorkFactory i = new StudentWorkFactory(); i.getWork().doWork(); IWorkFactory i1 = new TeacherWorkFactory(); i1.getWork().doWork(); } }

interface IWorkFactory{ Work getWork(); }

class StudentWorkFactory implements IWorkFactory{ @Override public Work getWork() { return new StudentWork(); } }

class TeacherWorkFactory implements IWorkFactory{ @Override public Work getWork() { return new TeacherWork(); } }

interface Work{ void doWork();

}

class StudentWork implements Work{ @Override public void doWork() { System.out.println(\学生写作业\ } }

class TeacherWork implements Work{ @Override public void doWork() { }

}

System.out.println(\老师批改作业\

代理模式

//接口的应用:代理模式(静态代理) public class TestProxy { public static void main(String[] args) { Object obj = new ProxyObject(); obj.action(); } }

interface Object{ void action(); }

//代理类

class ProxyObject implements Object{ Object obj; public ProxyObject(){

System.out.println(\代理类创建成功\ obj = new ObjctImpl(); } public void action(){ System.out.println(\代理类开始执行\ obj.action(); System.out.println(\代理类执行结束\ } }

//被代理类

class ObjctImpl implements Object{ @Override

}

public void action() { System.out.println(\被代理类开始执行======\ System.out.println(\具体的操作======\ System.out.println(\被代理类执行完毕======\ }

7.内部类

* 类的第5个成员:内部类

* 1.相当于说,我们可以在类的内部再定义类。外面的类:外部类。里面定义的类:内部类

* 2.内部类的分类:成员内部类(声明在类内部且方法外的) vs 局部内部类(声明在类的方法里) * 3.成员内部类: * 3.1是外部类的一个成员:①可以有修饰符(4个)②static final ③可以调用外部类的属性、方法 *

* *

3.2具体类的特点:①abstract ②还可以在其内部定义属性、方法、构造器

* 4.局部内部类: *

* 5.关于内部类,大家掌握三点:

* ①如何创建成员内部类的对象(如:创建Bird类和Dog类的对象) * ②如何区分调用外部类、内部类的变量(尤其是变量重名时) * ③局部内部类的使用 (见TestInnerClass1.java) 总结

面向对象的三条主线: 1.类及类的成分

2.面向对象的三大特性

3.其他的关键字:this super import package abstract static final interface等

1.java程序是关注于类的设计。类从代码的角度:并列关系! 从执行、设计的角度:关联关系、继承关系、聚合关系

class A{ }

class B{

A a = new A(); }

2.类的成分:属性 方法 构造器 代码块 内部类 2.1 属性:①变量的分类:成员变量(属性 Field) vs 局部变量(方法的形参、方法内部、代码块内部)

基本数据类型(8种,不同的数据类型对应不同的默认初始化值) vs 引用数据类型(数组、类、接口 默认初始化值为null)

②属性的声明格式:修饰符 数据类型 变量名 = 初始化值;//java是强数据类型的语言

③对属性的赋值的操作:1.默认初始化 2.显式的初始化 3.代码块的初始化 4.构造器的初始化;5.调用方法、属性进行赋值

2.2 方法 ①格式:修饰符 (其它的关键字:static/final/abstract)返回值类型 方法名(形参列表){ //方法体 }

②方法的重载(overload) vs 方法的重写(override overwrite) ③ 方法的参数传递机制:值传递(难点)

2.3构造器 ①构造器的作用:1.创建类的对象 2.初始化对象的成员变量 ②构造器也是可以重载的。 2.4 代码块 主要作用:用来初始化类的成员变量

分类:静态的代码块 vs 非静态的代码块

2.5 内部类 ①分类:成员内部类(static的成员 vs 非static的成员) vs 局部内部类(方法内部声明的类)

②掌握 :①如何创建成员内部类的对象(如:创建Bird类和Dog类的对象) ②如何区分调用外部类、内部类的变量(尤其是变量重名时) ③局部内部类的使用 (见TestInnerClass1.java) 3. 类的初始化(创建类的对象)

3.1 如何创建类的对象。如: Person p = new Person(); Date d = new Date(); 3.2 内存解析:

①栈:局部变量、对象的引用名、数组的引用名 堆:new 出来的“东西” 方法区:(字符串常量池) 静态域:存放类中静态的变量

②如何理解创建的对象在内存中加载的过程(理解) 3.3 子类对象实例化的全过程: SubClass sc = new SubClass(); 4.面向对象的三大特性: 4.1 封装性: ① 通过私有化类的成员变量,通过公共的getter和setter方法来调用和修改 ② 还可以对类的其他结构进行“封装”

③ 权限修饰符:public protected 缺省 private 4.2 继承性: 通过让一个类A继承另一个类B,就可以获取类B中的结构(主要的:属性、方法、构造器)。子类:类A 父类:类B

>java中的类的继承性:单继承的。 4.3 多态性:

①体现:方法的重载与重写 ; 子类对象的多态性 Person p = new Student(); ②子类对象多态性的使用:虚拟方法调用。

③向上转型 向下转型 Student s = (Student)p; //建议在向下转型之前: if ( p instanceof Student)避免出现ClassCastException的异常

5.其它关键字:

5.1 this:修饰属性、方法、构造器 。表示:当前对象或当前正在创建的对象

5.2 super:修饰属性、方法、构造器。显式的调用父类的相应的结构,尤其是子父类有重名的方法、属性

5.3 static : 修饰属性、方法、代码块、内部类。随着类的加载而加载! 5.4 final:修饰类、属性、方法。表示“最终的” 5.5 abstract : 修饰类、方法

5.6 interface:表示是一个接口,(接口是与类并列的一个结构)。类与接口之间同时“implements”发生关系。

5.7 package import 。。。

>abstract不能修饰属性、构造器、不能与final static private共用。

6.Bank项目

六、异常处理 1.体系结构

java.lang.Object

|----java.lang.Throwable |-------java.lang.Error:错误,java程序对此无能为力,不显式的处理 |-------java.lang.Exception:异常。需要进行处理 |------RuntimeException:运行时异常 |-----ArrayIndexOutOfBoundsException/NullPointerException/ArithmeticException/ClassCastException

|------非RuntimeException:编译时异常

2.因为java程序分为javac.exe和java.exe两个过程,在每个过程中,都有可能出现异常。故分为编译时异常、运行时异常

2.1 对于运行时异常比较常见,可以不显式的来处理。 2.2 对于编译时异常,必须要显式的处理 编译时异常,不是说有异常才处理,而是存在异常的隐患,必须在编译前,提示程序,万一出现异常,如何处理!

2.如何处理异常?

java 中的“抓抛模型”

* 1.\抛\:当我们执行代码时,一旦出现异常,就会在异常的代码处生成一个对应的异常类型的对象,并 * 将此对象抛出。(自动抛出 / 手动抛出)

* >一旦抛出此异常类的对象,那么程序就终止执行 * >此异常类的对象抛给方法的调用者。

* 2.\抓\:抓住上一步抛出来的异常类的对象。如何抓?即为异常处理的方式 * java 提供了两种方式用来处理一个异常类的对象。 * 处理的方式一: * try{

* //可能出现异常的代码 * }catch(Exception1 e1){ * //处理的方式1 * }catch(Exception2 e2){

* //处理的方式2 * }finally{

* //一定要执行的代码 * }

* 注:1.try内声明的变量,类似于局部变量,出了try{}语句,就不能被调用 * 2.finally是可选的。

* 3.catch语句内部是对异常对象的处理: * >getMessage(); printStackTrace();

* 4.可以有多个catch语句,try中抛出的异常类对象从上往下去匹配catch中的异常类的类型,一旦满足 * 就执行catch中的代码。执行完,就跳出其后的多条catch语句 * 5.如果异常处理了,那么其后的代码继续执行。

* 6.若catch中多个异常类型是\并列\关系,孰上孰下都可以。

* 若catch中多个异常类型是\包含\关系,须将子类放在父类的上面,进行处理。否则报错! * 7.finally中存放的是一定会被执行的代码,不管try中、catch中是否仍有异常未被处理,以及是否有return

语句。

* 8.try-catch是可以嵌套的。 处理方式二:

在方法的声明处,显式的使用throws + 异常类型

public void method1() throws Exception1 e1,Exception2 e2{

//可能出现异常(尤其是编译时异常,一定要处理) }

public void method2() throws Exception1 e1,Exception2 e2{ method1(); }

public void method3(){ try{ method2(); }catch(Exception1 e1){ System.out.println(e1.getMessage()); }catch(Exception2 e2){ System.out.println(e2.getMessage()); }

}

public static void main(String[] args){ 对象1.method3();//不会再出现上述的Exception1和Exception2的异常! }

3.如何手动的抛出一个异常?

在方法的内部,可以使用 throw + 异常类对象,来手动的抛出一个异常!

//比较两个圆的半径的大小。 public int compareTo(Object obj) throws Exception{ if(this == obj){ return 0; } else if(obj instanceof Circle){ Circle c = (Circle)obj; if(this.radius > c.radius){ return 1; }else if(this.radius == c.radius){ return 0; }else{ return -1; } }else{ //return -2; //手动的抛出一个异常 //throw new Exception(\传入的类型有误!\ //throw new String(\传入的类型有误!\ throw new MyException(\传入的类型有误!\

} }

4.如何自定义一个异常类?

>手动的抛出一个异常,除了抛出的是现成的异常类的对象之外,还可以抛出一个自定义的异常类的对象! >如何自定义一个异常类呢?

//1.自定义的异常类继承现有的异常类

//2.提供一个序列号,提供几个重载的构造器 public class MyException extends Exception{ static final long serialVersionUID = -70348975766939L; public MyException(){ } public MyException(String msg){ super(msg); } }

5.“5个关键字搞定异常处理!” 其中,要区分:throw与throws的区别? 7.集合

1.对象的存储:①数组(基本数据类型 & 引用数据类型) ②集合(引用数据类型)

>数组存储数据的弊端:长度一旦初始化以后,就不可变;真正给数组元素赋值的个数没有现成的方法可用。 2.集合框架

Collection接口 :方法:①add(Object obj),addAll(Collection coll),size(),clear(),isEmpty(); ②remove(Object obj),removeAll(Collection coll),retainAll(Collection coll),equals(Object obj),contains(Object obj)

containsAll(Collection coll),hashCode() ③ iterator(),toArray(); * |------List接口:存储有序的,可以重复的元素.---相当于“动态”数组 >新增的方法:删除remove(int index) 修改set(int index,Object obj) 获取get(int index)插入add(int index,Object obj)

>添加进List集合中的元素(或对象)所在的类一定要重写equals()方法 * |------ArrayList(主要的实现类) |------LinkedList(更适用于频繁的插入、删除操作) |------Vector(古老的实现类、线程安全的,但效率要低于ArrayList) * |------Set接口:存储无序的,不可重复的元素。---相当于高中的“集合”概念 >Set使用的方法基本上都是Collection接口下定义的。 >添加进Set集合中的元素所在的类一定要重写equals() 和 hashCode()。要求重写equals() 和 hashCode()方法保持一致。

>1.无序性:无序性!= 随机性。真正的无序性,指的是元素在底层存储的位置是无序的。 >2.不可重复性:当向Set中添加进相同的元素的时候,后面的这个不能添加进去。 * |------HashSet(主要的实现类) |------LinkedHashSet(是HashSet的子类,当我们遍历集合元素时,是按照添加进去的顺序实现的;频繁的遍历,较少的添加、插入操作建议选择此)

|------TreeSet(可以按照添加进集合中的元素的指定属性进行排序) >要求TreeSet添加进的元素必须是同一个类的! >两种排序方式:自然排序:①要求添加进TreeSet中的元素所在的类implements Comparable接口

②重写compareTo(Object obj),在此方法内指明按照元素的

哪个属性进行排序

③向TreeSet中添加元素即可。若不实现此接口,会报运行时异常

定制排序:①创建一个实现Comparator接口的实现类的对象。在实现类中重写Comparator的compare(Object o1,Object o2)方法

②在此compare()方法中指明按照元素所在类的哪个属性进行排序

③将此实现Comparator接口的实现类的对象作为形参传递给TreeSet的构造器中

④向TreeSet中添加元素即可。若不实现此接口,会报运行时异常

>要求重写的compareTo()或者compare()方法与equals()和hashCode()方法保持一致。 Map接口:存储“键-值”对的数据 ----相当于高中的“函数y = f(x)” (x1,y1) (x2,y2)

>key是不可重复的,使用Set存放。value可以重复的,使用Collection来存放的。一个key-value对构成一个entry(Map.Entry),entry使用Set来存放。

>添加、修改 put(Object key,Object value) 删除remove(Object key) 获取get(Object key) size() / keySet() values() entrySet()

* |-----HashMap:主要的实现类,可以添加null键,null值 |-----LinkedHashMap:是HashMap的子类,可以按照添加进Map的顺序实现遍历 |-----TreeMap:需要按照key所在类的指定属性进行排序。要求key是同一个类的对象。对key考虑使用自然排序 或 定制排序

|-----Hashtable:是一个古老的实现类,线程安全的,不可以添加null键,null值不建议使用。 |-----子类:Properties:常用来处理属性文件

Iterator接口:用来遍历集合Collection元素

Collections工具类:操作Collection及Map的工具类,大部分为static的方法。

附:Properties的使用

Properties pros = new Properties(); pros.load(new FileInputStream(new File(\ String user = pros.getProperty(\ System.out.println(user); String password = pros.getProperty(\ System.out.println(password); 八、泛型

1.泛型在集合中的使用(掌握)

2.自定义泛型类、泛型接口、泛型方法(理解 --->使用) 3.泛型与继承的关系 4.通配符

1.在集合中不使用泛型 public void test1(){ List list = new ArrayList(); list.add(89); list.add(87); list.add(67); //1.没有使用泛型,任何Object及其子类的对象都可以添加进来

list.add(new String(\

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

//2.强转为int型时,可能报ClassCastException的异常 int score = (Integer)list.get(i); System.out.println(score); } }

2.在集合中使用了泛型 public void test2(){ List list = new ArrayList(); list.add(78); list.add(87); // list.add(\ // for(int i = 0;i < list.size();i++){ // int score = list.get(i); // System.out.println(score); // } Iterator it = list.iterator(); while(it.hasNext()){ System.out.println(it.next()); } }

public void test3(){ Map map = new HashMap<>(); map.put(\ map.put(\ map.put(\ Set> set = map.entrySet(); for(Map.Entry o : set){ System.out.println(o.getKey() + \ } }

3.自定义泛型类:应用 public class DAO { public void add(T t){ //.... } public T get(int index){ return null; } public List getForList(int index){ return null; } public void delete(int index){

} }

public class CustomerDAO extends DAO{ }

public class TestCustomerDAO { public static void main(String[] args) { CustomerDAO c = new CustomerDAO(); c.add(new Customer()); c.get(0); } }

【注意点】

1.对象实例化时不指定泛型,默认为:Object。 2.泛型不同的引用不能相互赋值。

3.加入集合中的对象类型必须与指定的泛型类型一致。 4.静态方法中不能使用类的泛型。

5.如果泛型类是一个接口或抽象类,则不可创建泛型 类的对象。

6.不能在catch中使用泛型

7.从泛型类派生子类,泛型类型需具体化

4.泛型与继承的关系

A类是B类的子类,G是带泛型声明的类或接口。那么G不是G的子类!

5.通配符:?

A类是B类的子类,G是带泛型声明的类或接口。则G 是G、G的父类!

①以List为例,能读取其中的数据。因为不管存储的是什么类型的元素,其一定是Object类的或其子类的。 ①以List为例,不可以向其中写入数据。因为没有指明可以存放到其中的元素的类型!唯一例外的是:null

6*. List<? extends A> :可以将List的对象或List的对象赋给List。其中B 是A的子类 ? super A:可以将List的对象或List的对象赋给List。其中B 是A的父类 九、枚举类和注解

一、枚举类

1.如何自定义枚举类。 枚举类:类的对象是有限个的,确定的。 1.1 私有化类的构造器,保证不能在类的外部创建其对象 1.2 在类的内部创建枚举类的实例。声明为:public static final

1.3 若类有属性,那么属性声明为:private final 。此属性在构造器中赋值。 2.使用enum关键字定义枚举类 >2.1其中常用的方法:values() valueOf(String name); >2.2枚举类如何实现接口 :①让类实现此接口,类的对象共享同一套接口的抽象方法的实现。 ①让类的每一个对象都去实现接口的抽象方法,进而通过类的对象调用被重写的抽象方法时,执行的效果不同

public class TestSeason1 {

public static void main(String[] args) { Season1 spring = Season1.SPRING; System.out.println(spring); spring.show(); System.out.println(spring.getSeasonName()); System.out.println(); //1.values() Season1[] seasons = Season1.values(); for(int i = 0;i < seasons.length;i++){ System.out.println(seasons[i]); } //2.valueOf(String name):要求传入的形参name是枚举类对象的名字。 //否则,报java.lang.IllegalArgumentException异常 String str = \ Season1 sea = Season1.valueOf(str); System.out.println(sea); System.out.println(); Thread.State[] states = Thread.State.values(); for(int i = 0;i < states.length;i++){ System.out.println(states[i]); } sea.show(); } }

interface Info{ void show(); }

//枚举类

enum Season1 implements Info{

SPRING(\春暖花开\ public void show(){ System.out.println(\春天在哪里?\ } },

SUMMER(\夏日炎炎\ public void show(){ System.out.println(\生如夏花\ } },

AUTUMN(\秋高气爽\ public void show(){ System.out.println(\秋天是用来分手的季节\ } },

WINTER(\白雪皑皑\ public void show(){

System.out.println(\冬天里的一把火\ } }; private final String seasonName; private final String seasonDesc; private Season1(String seasonName,String seasonDesc){ this.seasonName = seasonName; this.seasonDesc = seasonDesc; } public String getSeasonName() { return seasonName; } public String getSeasonDesc() { return seasonDesc; } @Override public String toString() { return \ + seasonDesc + \ }

// public void show(){ // System.out.println(\这是一个季节\// } }

二、注解Annotation

1.JDK提供的常用的三个注解

@Override: 限定重写父类方法, 该注释只能用于方法 @Deprecated: 用于表示某个程序元素(类, 方法等)已过时 @SuppressWarnings: 抑制编译器警告

2.如何自定义注解

以SuppressWarnings为例进行创建即可

3.元注解:可以对已有的注解进行解释说明。 Retention: SOURCE CLASS RUNTIME Target:

Documented:javadoc Inherited 十、IO流

1.java.io包下

File类:java程序中的此类的一个对象,就对应着硬盘中的一个文件或网络中的一个资源。 File file1 = new File(\File file2 = new File(\

>1.File既可以表示一个文件(.doc .xls .mp3 .avi .jpg .dat),也可以表示一个文件目录!

>2.File类的对象是与平台无关的。

>3.File类针对于文件或文件目录,只能进行新建、删除、重命名、上层目录等等的操作。如果涉及到访问文件的内容,File

是无能为力的,只能使用IO流下提供的相应的输入输出流来实现。 >4.常把File类的对象作为形参传递给相应的输入输出流的构造器中!

2.IO 流的结构 3.IO流的划分

1) 按照流的流向的不同:输入流 输出流 (站位于程序的角度)

2) 按照流中的数据单位的不同:字节流 字符流 (纯文本文件使用字符流 ,除此之外使用字节流) 3) 按照流的角色的不同:节点流 处理流 (流直接作用于文件上是节点流(4个),除此之外都是处理流)

4.重点掌握 * 抽象基类 节点流(文件流) 缓冲流(处理流的一种,可以提升文件操作的效率)

* InputStream FileInputStream (int read(byte[] b)) BufferedInputStream (int read(byte[] b)) * OutputStream FileOutputStream (void write(b,0,len)) BufferedOutputStream (flush()) (void write(b,0,len))

* Reader FileReader (int read(char[] c)) BufferedReader (readLine()) (int read(char[] c))或String readLine()

* Writer FileWriter (void write(c,0,len)) BufferedWriter (flush()) (void write(c,0,len)或void write(String str))

注: 1.从硬盘中读入一个文件,要求此文件一定得存在。若不存在,报FileNotFoundException的异常

2.从程序中输出一个文件到硬盘,此文件可以不存在。若不存在,就创建一个实现输出。若存在,则将已存在的文件覆盖

3.真正开发时,就使用缓冲流来代替节点流

4.主要最后要关闭相应的流。先关闭输出流,再关闭输入流。将此操作放入finally 5.其它的流

1.转换流:实现字节流与字符流之间的转换

InputStreamReader:输入时,实现字节流到字符流的转换,提高操作的效率(前提是,数据是文本文件) ===>解码:字节数组--->字符串

OutputStreamWriter:输出时,实现字符流到字节流的转换。 ===>编码: 字符串---->字节数组

例子:从键盘输入字符串,要求将读取到的整行字符串转成大写输出。然后继续进行输入操作,直至当输入“e”或者“exit”时,退出程序。

2.标准的输入输出流

System.in: The \从键盘输入数据

System.out:The \:从显示器输出数据

3.打印流 (都是输出流) PrintStream(处理字节) PrintWriter(处理字符) 可以使用System.setOut(PrintStream p)重新设置一下输出的位置。 PrintStream p = new PrintStream(new FileOutputStream(\

4.数据流(处理基本数据类型、String类、字节数组) DataInputStream DataOutputStream

5.对象流(用来处理对象的)

>对象的序列化机制:允许把内存中的Java对象转换成平台无关的二进制流,从而允许把这种二进制流持久地保存在磁盘上,

或通过网络将这种二进制流传输到另一个网络节点。当其它程序获取了这种二进制流,就可以恢复成原来的Java对象

ObjectInputStream(Object readObject();) ObjectOutputStream (void writeObject(Object obj))

如何创建流的对象:ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File(\

ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File(\ 实现序列化机制的对象对应的类的要求:①要求类要实现Serializable接口②同样要求类的所有属性也必须实现Serializable接口

③ 要求给类提供一个序列版本号:private static final long serialVersionUID;

④属性声明为static 或transient的,不可以实现序列化

6.随机存取文件流:RandomAccessFile

6.1既可以充当一个输入流,又可以充当一个输出流:public RandomAccessFile(File file, String mode) 6.2支持从文件的开头读取、写入。若输出的文件不存在,直接创建。若存在,则是对原有文件内容的覆盖。

6.3 支持任意位置的“插入”。

十一、多线程

1.理解程序、进程、线程的概念 程序可以理解为静态的代码 进程可以理解为执行中的程序。

线程可以理解为进程的进一步细分,程序的一条执行路径

2.如何创建java程序的线程(重点) 方式一:继承于Thread类 class PrintNum extends Thread{ public void run(){ //子线程执行的代码 for(int i = 1;i <= 100;i++){ if(i % 2 == 0){ System.out.println(Thread.currentThread().getName() + \ } } } public PrintNum(String name){ super(name); } }

public class TestThread { public static void main(String[] args) { PrintNum p1 = new PrintNum(\线程1\

PrintNum p2 = new PrintNum(\线程2\ p1.setPriority(Thread.MAX_PRIORITY);//10 p2.setPriority(Thread.MIN_PRIORITY);//1 p1.start(); p2.start(); } }

方式二:实现Runnable接口

class SubThread implements Runnable{ public void run(){

//子线程执行的代码 for(int i = 1;i <= 100;i++){ if(i % 2 == 0){ System.out.println(Thread.currentThread().getName() + \ } } } }

public class TestThread{ public static void main(String[] args){ SubThread s = new SubThread(); Thread t1 = new Thread(s); Thread t2 = new Thread(s); t1.setName(\线程1\ t2.setName(\线程2\ t1.start(); t2.start(); } }

两种方式的对比:联系:class Thread implements Runnable 比较哪个好?实现的方式较好。①解决了单继承的局限性。②如果多个线程有共享数据的话,建议使用实现方式,同时,共享

数据所在的类可以作为Runnable接口的实现类。 线程里的常用方法:start() run() currentThread() getName() setName(String name) yield() join() sleep() isAlive()

getPriority() setPriority(int i); wait() notify() notifyAll()

3.线程的生命周期

4.线程的同步机制(重点、难点)

前提:如果我们创建的多个线程,存在着共享数据,那么就有可能出现线程的安全问题:当其中一个线程操作共享数据时,还未操作完成,

另外的线程就参与进来,导致对共享数据的操作出现问题。 解决方式:要求一个线程操作共享数据时,只有当其完成操作完成共享数据,其它线程才有机会执行共享数据。

本文来源:https://www.bwwdw.com/article/w0dv.html

Top