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
public void test3(){ Map
3.自定义泛型类:应用 public class DAO
} }
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 extends A>。其中B 是A的子类 ? super A:可以将List的对象或List的对象赋给List extends A>。其中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.线程的同步机制(重点、难点)
前提:如果我们创建的多个线程,存在着共享数据,那么就有可能出现线程的安全问题:当其中一个线程操作共享数据时,还未操作完成,
另外的线程就参与进来,导致对共享数据的操作出现问题。 解决方式:要求一个线程操作共享数据时,只有当其完成操作完成共享数据,其它线程才有机会执行共享数据。
正在阅读:
JavaSE基础教程11-16
高补部理科数学周小题训练4(理)11-20
观看《开学第一课》观后感100字优秀2篇03-26
大学英语精读第三册cloze及答案04-12
企业财务风险成因分析与防范对策03-24
蒋立源编译原理 第三版 第三章 习题与答案(修改后)12-04
春的信息作文300字07-06
实验三 食物中主要营养成分的鉴定108-17
- exercise2
- 铅锌矿详查地质设计 - 图文
- 厨余垃圾、餐厨垃圾堆肥系统设计方案
- 陈明珠开题报告
- 化工原理精选例题
- 政府形象宣传册营销案例
- 小学一至三年级语文阅读专项练习题
- 2014.民诉 期末考试 复习题
- 巅峰智业 - 做好顶层设计对建设城市的重要意义
- (三起)冀教版三年级英语上册Unit4 Lesson24练习题及答案
- 2017年实心轮胎现状及发展趋势分析(目录)
- 基于GIS的农用地定级技术研究定稿
- 2017-2022年中国医疗保健市场调查与市场前景预测报告(目录) - 图文
- 作业
- OFDM技术仿真(MATLAB代码) - 图文
- Android工程师笔试题及答案
- 生命密码联合密码
- 空间地上权若干法律问题探究
- 江苏学业水平测试《机械基础》模拟试题
- 选课走班实施方案
- 基础
- 教程
- JavaSE
- 冬季路桥施工中混凝土的浇筑措施
- 办公室岗位职责
- 基础会计教学案例
- 新核心大学英语读写教程2课文翻译
- 22.LDRA - Testbed - C语言编码规则列表1.0
- 师德材料(6)
- 仁爱英语七年级下册Unit3短语句子
- 幼儿园高效率集体教学活动策略研究
- 上饶市城镇职工基本医疗保险市级统筹业务经办管理试行规程
- 高数习题1
- 2008年汶川地震各省捐款最终核实数
- Yearbooks in the United States
- 1-6-6-1分户热计量供暖系统安装技术要求
- 图论
- MS 4.3磁性体系LDA+U计算设置 - 图文
- 动词的过去式和过去分词规则表
- “开展批评和自我批评”组织生活会个人对照检查材料
- 提高自身素质 树立班主任新形象
- 中北 工程流体力学 第二章
- 合同战术论文