Lusir Shahtml
Core Javajava
引言:程序员
1、why:算法
Core Java是整个Java体系的基础和核心,其余Java技术均是构建在Core Java基础之上的。sql
2、What:数据库
java语法基础:字符集,条件语句,循环语句express
java面向对象编程:特征,高级特性,面向对象编程思想编程
java IO流(输入输出)和文件操做小程序
多线程编程设计模式
图形用户界面(GUI)编程
Java 网络编程:Socket编程
3、How:
Thinking+Coding+Testing;
ch01 java入门
1、Java起源与发展
java起源于SUN公司的Green项目----》Oak
SUN公司在推出java语言的同时,也推出了一系列开发工具,如:JDK(java Development Kit)java开发工具包
时间 版本 类库数量 描述
1996 JDK1.0 250 Applet
1997 JDK1.1 500 图形用户界面编程
1998 JDK1.2(java2.0) 2300 全面支持企业及开发
2000 JDK1.3(java2.0)
2002 JDK1.4(java2.0)
2004 JDK1.5(java5.0) 3500 对语言自己作了重大改变,更稳定、更高效、更安全;---Tiger
2005 JDK1.6(java6.0)
补充内容:
java的应用版本:
JavaSE:java标准版本,基础和核心,主要用来作java小程序,桌面程序;
JavaME:java微型版本,主要用来作移动开发,游戏开发;
JavaEE:java企业版本,主要用来作企业级开发;
JDK(java Development Kit)包括:
java虚拟机JVM:编译、运行java程序,JVM能够运行在任何平台上;
java API(java/JDK类库):别人开发好的能够直接使用的类。提供一些最基础和实用的java类,例如java.lang,java.util,java.sql包中的类都处于java API中;
开发工具:这些开发工具都是可执行文件
javac.exe 编译java源程序
java.exe 运行java程序
javadoc.exe 生成java说明文档
jar.exe 打包工具
2、设置java开发环境
1)获取J2SDK
2)安装J2SDK
JDK安装目录下的文件夹简介:
bin:表示java的可执行命令/文件
demo:java的一些基本例子
include:一些c程序,主要是和其它语言集成
jre:java的运行环境,jdk必须有jre,java程序才能被处理
lib:放置库函数,也称之为第三方文件
sample:java的实例程序
src.zip:java类库源代码
3)设置环境变量
JAVA_HOME:设置为java安装目录,设置目的是简化其余环境变量的设置;该变量可设可不设;
path:设置java命令(工具)的路径范围,保证在操做系统的任何位置调用java命令;该变量必须设置;%JAVA_HOME%\bin;
classpath:设置java源文件的二进制文件的存储位置,通常设定为当前路径,默认为当前路径。该变量可设可不设;
3、java是什么?
java是编程语言、开发环境、应用环境、部署环境。
制订了规则并予以实现(JDK);
4、java的特色
1)简单功能强大的:语法相似于C、C++;废弃了指针操做,自动内存管理;Java提供了大量类库;
2)安全的:无指针操做;严格的代码校验(校验器能够发现操做数栈的溢出,非法类型转化等错误);
3)健壮的:致力检查编译和运行时错误;强类型语言;自动垃圾内存回收;
4)纯面向对象的
面向对象是java语言最重要的特征,具备封装、继承、多态等特征;java语言只支持面向对象编程,不支持相似于C那样的面向过程编程;C++既支持面向对象编程,也支持面向过程编程;
5)解释的:java源程序先编译成结构中立的字节码文件,而后解释执行;C和C++是编译执行的,先编译成本地机器码文件,而后执行;
6)跨平台的(可移植的):即“一次编译,到处执行”,经过JVM虚拟机实现的,其原理是为不一样的OS提供不一样JVM,但其编译生成字节码文件的规格相同;
java做为一门网络编程语言,编译生成结构中立的字节码文件,该文件能够运行在任意一个具备java运行环境的机器上。
注意:java语言的跨平台是经过JVM实现的,可是JVM自己并不跨平台;
7)多线程的:java是一个从语言级支持多线程程序设计的编程语言,也就是能够直接经过java编程实现多线程。
多线程编程的简单性是Java成为流行的服务器端开发语言的主要缘由之一
8)自动垃圾内存回收
垃圾:无用对象占用的内存
垃圾回收:无用对象占用的内存的回收过程
C和C++要经过编程者自身经过编程实现内存的分配和回收,若是内存分配和回收不平衡时,将形成系统资源耗尽或者内存溢出而致使程序异常终止,从而发生错误;
java中垃圾内存是由垃圾回收器线程在适当的时候自动回收。
当系统内存紧张时,回收;不然不回收;
编程者也能够手动回收垃圾内存:java.lang.System.gc()/java.lang.Runtime.gc();
5、JVM(java virtual machine)java虚拟机:利用软件来模拟一个虚拟的环境;
6、垃圾回收
7、java代码安全
8、第一个java程序
1)源文件:包含java代码(符合java语言规则编写的内容)的文件;
特征:以.java为后缀名;能够包含多个类或者接口;文件名与类名或者接口(只包含一个类或者接口)或者与public修饰的类或者接口(包含多个类或者接口)同名;
结构:
包声明:无关紧要,若是有只能有一行而且必须处于第一行(注释除外);
import语句:无关紧要,可有多行,紧跟包声明语句;
类的声明语句;
2)类:java代码的组织单位,java代码就是由一个个类组织的,java编程就是编写一个个的java类;
3)方法、main方法
4)剖析类
package:
将类放入某一特定的包中,便于类的组织、权限访问和区分名字相同的类;
能够定义多级包,中间用“.”分开,包名.包名....
引入包名后,类的名字为:包名+类名;
java中包层次和文件系统中的目录/文件夹结构相似;
import:
导入一个或者多个与本类不在同一包层次下的类文件;
import java.io.File;
import java.io.*;导入java.io包下的全部类,可是不包括其中子包下的类;
java.lang包下的类默认导入;
9、经常使用的包:
java.lang:包含一些Java语言的基本类与核心类,如String、Math、Integer、System和Runtime,提供经常使用的功能,这个包中的全部类是被隐式导入的;
java.awt/javax.swing/java.awt.event:包含编写与平台无关的图形界面(GUI)应用程序的类;
java.io:包含一些用做输入输出(I/O)处理的类,主要包括流的类;
java.net:包含用于创建网络链接的类,与java.io同时使用完成与网络有关的读写;
java.util:包含一些实用工具类和数据结构类。像集合类、日期类等。
10、Java API:Java Application Programming Interface,java开发者预先定义好的供编程者直接使用的类库;
ch02 java语法基础
1、程序注释
为了加强程序代码的可读性,在java源文件中的任意位置都可以加入程序注释。
程序中加入注释语句,在java程序编译时会被编译器忽略,不管在程序注释中添加任何东西,编译后程序不受任何影响。
单行注释://注释内容;
利用单行注释,从符号//开始至换行之间的内容会被认为是注释内容编译时编译器会忽略;
例如:int age;//age表示年龄
多行注释:/*.........*/,“/*”,“*/”之间为注释内容,必须成对出现,注释内容能够换行;
例如:/*注释内容*/
或者
/*
注释内容
*/
为了美观能够写成:
/*
*注释内容
*/
文档注释:和多行注释类似,任何声明以前都可加入文档注释,注释内容可被JavaDoc工具读取做为JavaDoc文档内容,文档是对代码结构和功能的描述;
/**
*注释内容
*/
2、java代码编写基本规则
java语句以英文分号结束,为了程序代码的可读性最好占一行;
java代码块放在一对大括号之间;java容许一组语句放在一块儿用大括号括起来造成代码;例如:循环体,语句块,类体,方法体;语句块可嵌套;
程序忽略空格、制表符、空行、续行符;
3、标识符
java中用来为类、方法、变量等所起的名字叫标识符;
规则:标识符以字母、“_”、“$”开头,后可跟字母、“_”、“$”或者数字,无长度限制,大小写敏感,不能使用java的关键字、预留关键字以及有特殊用途的符号做为标识符;
有效:abc $qw $$$ q1 _$ $_
无效:1q #qw class true
注意:goto和const虽然目前不是java的关键字,可是被做为预留关键字保留;
true,false,null具备特殊用途,不能用作标识符;
Volatile修饰的成员变量在每次被线程访问时,都强迫从共享内存中重读该成员变量的值。
命名规范:类和接口的名字首字母要大写;方法名和变量名第一个单词字首字母要小写,其余首字母要大写;包名要小写;常量名要大写;全部的命名最好不要用中文以及英文以外的其余语言;
4、数据类型:一组性质相同的值的集合以及定义在该值集合上一组操做的总称;
程序的基本功能就是处理数据,程序中用变量来表示数据,变量必定要先定义在使用;
经常使用的数据类型:整型,浮点型,字符型,字符串型,逻辑型
java中的数据类型分为基本数据类型和引用类型;
引用类型:类类型,数组类型,接口类型等;
基本数据类型:
数值型:整型(字节型byte,short短整型,int整型,long长整型),浮点型(float单精度型,双精度型double)
逻辑型boolean:只能表明两种状态逻辑真或者假,用于判断现实中条件的成立与否,经常使用来进行逻辑运算和程序的流程控制;
在java中boolean型只能取true或者false,不能像C语言中那样用0和非0的整数来表明true或者false;
字符型char:2个字节,16位,无符号,用“'”括起来;
char a='a';
char a='\u0061';
char a=ox0061;
char a=97;
转义字符:以反斜杠开头
\n 换行符,将光标定位当下一行的开头;
\t 垂直制表符,将光标定位到下一个制表符位置;
\r 回车,将光标定位到当前行开始处,并不移到下一行;
\\ 反斜杠
\' 单引号
5、变量:
变量是用来记录值能够发生改变的数据的标识符,一样那么常量就是用来记录值不能够发生改变的数据的标识符;
在计算机技术中,变量包括变量名和变量值,变量名标示一段特定的存储空间,变量值就是存放在该空间中的二进制数据,能够被修改和访问;
变量的分类:
按照存储数据的数据类型分:基本数据类型和引用类型;
按照声明的位置分:局部变量和成员变量(又称为实例变量);
局部变量:声明在方法
内部或者代码块内;
成员变量:声明在类的内部,方法的外部;
在java中变量在声明和初始化后才能使用
成员变量定义在类的内部,在使用类建立对象时同时建立成员变量,进行系统默认初始化和显示初始化;
方法形参局部变量,在调用方式进行隐式初始化;
变量的做用域和生命周期:
成员变量的做用和其所属对象相同,生命周期随着对象的建立而建立,随着对象的销毁而销毁;
局部变量的做用域为其所在的方法内部或者代码块内部,生命周期就是方法或者代码块的一次执行期间;
6、内存的逻辑分区
栈内存:特定程序专用,先进后出的分配原则,存储空间分配连续,存储容量小速度快。一般存放局部变量;
堆内存:所用应用程序公用,存储空间分配不连续,存储容量大速度慢。一般存放成员变量、对象;
代码区:专门存放方法、代码块;
静态、常量存储区:存放静态变量、常量;
7、理解对象
面向对象的开发方法把软件系统当作各类对象的集合,对象就是最小的子系统,一组相关的对象可以组合成更复杂的子系统。面向对象的开发方法将软件系统当作各类对象的集合,接近人的天然思惟方式。
对象是对问题领域中实体、事件的抽象。对象具备如下特性:
1) 万物皆为对象。问题领域中的实体和概念均可以抽象为对象。例如学生,成绩单、教师、课和教室。
2) 每一个对象都是唯一的。正如世界上不存在如出一辙的叶子。
3) 对象具备属性和行为。
例如小张,性别女,年龄22,身高1.6m, 体重40kg, 可以学习,唱歌。小张的属性包括姓名、性别、年龄、身高和体重,行为包括学习、唱歌。
例如一部手机,牌子是诺基亚、价格是2000元,银白色,可以拍照、打电话和收发短信等。这部手机的属性包括品牌类型type、价格price和颜色color,行为包括拍照takePhoto(),打电话call(),收发短信receiveMessage()和发短信sendMessage().
4) 对象具备状态。状态是指某个瞬间对象的各个属性的取值。对象的某些行为会改变对象自身的状态,即属性的取值。
例如小张原本体重为40kg,经为减肥后,体重减到45kg.
肥胖状态: 40kg
|
| 减肥行为
|
肥胖状态: 35kg
5) 每一个对象都是某个类的实例。小张和小王都属于学生类、中国和美国都属于国家类、中文和英文都属于语言类。类是具备相同属性和行为的对象的集合。
同一个类的全部实例都有相同属性,但属性取值不必定相同,也就是它们的状态不必定相同。例如小张和小王都属于学生类,都有姓名、性别、年龄、身高和体重这些属性,可是他们的属性取值不一样。
同一个类的全部实例都有相同行为,意味着它们具备一些相同的功能。
8、类
类建立对象的模板,建立类语法为:
[<modifiers>] class <class_name>[extends superclass][implements interface a,....]{
[<attribute_declarations>]
[<constructor_declarations>]
[<method_declarations>]
}
修饰符 + 返回类型 +methodName(参数列表){
方法体;
}
void
9、实例化对象
new + 构造方法
引用变量名.属性名或者方法名;
类建立好以后,经过new关键字建立具体对象。它有如下做用:
. 为对象分配内存空间,将对象的实例变量自动初始化为其变量类型的默认值;(Java对象的默认初始化规则:数值型:0或者0.0;字符型:"\u0000";逻辑型:false;引用类型:null;)
. 如实例变量显示初始化,将初始化值赋给实例变量;
. 调用构造方法;
. 返回对象的引用;
注:结合实例,并画内存分配图讲解。
10. 基本类型和引用类型的区别
1) 基本类型表明简单的数据类型,好比整数和字符。
引用类型表明复杂数据类型,引用类型所引用的实例包括操纵这种数据类型的行为。经过"."运算符,就能访问引用变量所引用的实例的方法.
2) 基本类型Java虚拟机会为其分配数据类型实际占用的内存空间;
引用类型仅是一个指向堆区中某个实例的指针。
例:public class Counter {
int count = 13;
}
Counter counter = new Counter();
counter引用变量-------------> Counter实例
count变量(占4个字节,值为13)
counter引用变量的取值为Counter实例的内存地址。
counter引用变量自己也占必定的内存空间,到底占用多少内存空间取决于Java虚拟机的实现,这对Java程序是透明的。
注:counter引用变量到底位于Java虚拟机的运行时数据区的哪一个区?取决于counter变量的做用域,若是是局部变量,则位于Java栈区;静态成员变量,则位于方法区;实例成员变量,则位于堆区;
要求:
写一个Teacher类,属性:name,age,gender,salary
对于属性赋值和取值并打印本对象信息
对老师的salary作操做--->写方法,给每一个老师加薪,减薪
写一个测试类测试所写的方法
ch03 表达式、运算符、流程控制
1、运算符
算术运算符:+ - * / % ++ --;
自增自减符号:能够放在变量的前面也能够放在后面,放在后面表示先取变量值再自增或者自减1,放在变量前面先自增或者自减1再取变量值;
比较运算符:> >= < <= == != instanceof
引用名 instanceof 类型名;
判断引用是否指向某一类型或者其子类型的实例;
逻辑运算符: && || ! & | ^
语法:进行逻辑运算的逻辑值或者逻辑表达式
短路与:&&
A && B:只有当A的值为true才会考虑B,A,B都为true时返回true,不然false;
短路或:||
A || B 只有当A为false时才考虑B,A,B都为false时返回false,不然返回true;
位运算符:& | ^ ~
移位运算符:<< >> >>>
对整数的二进制数进行移位处理;
a<<b 左移:将二进制形式的a左移b位,最高位b为抛弃,低位(右侧)空出的b位补0;
a>>b 带符号右移:将二进制形式的a右移b位,最右侧的b为抛弃,最高位空出的b位补原来的符号位;
a>>>b 无符号右移:将二进制形式的a右移b位,最右侧的b为抛弃,最高位空出的b位补0;
int a=5;
00000000 00000000 00000000 00000101
a<<2 00 00000000 00000000 00000000 00010100
a>>2 00000000 00000000 00000000 00000001 01
a>>>2 00000000 00000000 00000000 00000001 01
int a=-5
10000000 00000000 00000000 00000101
11111111 11111111 11111111 11111010
11111111 11111111 11111111 11111011
a<<2 11 11111111 11111111 11111111 11101100
a>>2 11111111 11111111 11111111 11111110 11
a>>>2 00111111 11111111 11111111 11111110 11
赋值运算符:=
赋值运算符的左边必须是已经声明过的变量,不能是常量或者复合表达式;
运算符左右两边必须是相同的数据类型,能够进行类型自动转换的除外;
a E=b;
a=a E b;
条件运算符: ? :
(条件表达式)?(值1):(值2);
字符串链接符:+
2、表达式:符合必定语法规则的运算符和操做数组成的序列;
3、类型转换
基本数据类型转换和引用类型转换
基本数据类型转换:
隐式转换(自动转换):从窄精度类型向宽精度类型转换;int b=3;long d=b;
显示转换(强制类型转换):从宽精度类型向窄精度类型转换;
long d=234;int a=(int)d;
byte-->short-->int-->long-->float-->double
char-->int
引用类型转换:
隐式转换(自动转换):让父类型的引用指向子类型实例(对象);
Object object=new String("abc");
显示转换(强制类型转换):让子类型引用转换为父类型;
String str=(String)object;
4、流程控制语句
顺序结构:最简单的基本结构,按照语句顺序执行;
选择(分支)结构:按照给定条件判断,条件为true执行一个分支,为false执行另外一个分支;
包括if选择结构和switch分支结构:
if选择结构:
b表明一个逻辑表达式
if(b){
statement or block;
}
if(b){
statement or block;
}else{
statement or block;
}
if(b){
statement or block;
}else if(b){
statement or block;
}else if(b){
statement or block;
}
.....
[else{
statement or block;
}]
if选择结构能够嵌套;
switch选择结构:
switch(expression){
case(常量1):{
statement or block;
break;
}
case(常量2):{
statement or block;
break;
}
......
[dafault:{
statement or block;
break;
}]
}
expression值的类型只能是int,byte,short,char,枚举,类类型之一;
break使得执行完一个分支后跳出switch语句,从语法上来说能够没有break,可是不合语
意;
default语句能够放在switch结构的任何位置;
循环结构:按照须要使得重复执行一行或者多行代码;
for循环:用于循环次数已知的状况;
while循环:又称为当型循环或者前测试循环,该循环有可能一次都不执行;
do...while循环:又称为直到型循环或者后测试循环,该循环至少执行一次;
for each循环:
*
***
*****
*******
*********
***********
i为行标
每行*的个数为2i-1个;
每行要打印n-i个空格;
break语句:用于终止所在的switch语句或者循环语句;用于终止循环时终止的是所在单层循环;
continue语句:用于结束所在循环的本次执行,即跳过剩余循环语句,开始下一次循环;
ch04 数组
1、概念:一组相同数据类型的数据组成的有序集合;
数组是引用类型,数组型数据是一个对象,数组中元素至关于数组的属性;
数组中存放的元素能够是任意类型,基本数据类型和引用类型;
2、一维数组的声明,初始化,使用
声明:
int[] a;//规范,推荐使用
int a[];
Person[] ps;
Person ps[];
注意:数组在声明时不能指定长度(即元素个数);
例如:int[5] a;//不合法
建立数组
new int[3];
new Person[3];
数组是引用类型,数组的元素至关于对象的成员变量,在数组建立时各元素像对象的成员变量同样将根据元素类型进行默认(隐式)初始化;
数组初始化:
动态初始化:数组的声明、建立和初始化分开进行;
int[] a;
a=new int[3];
a[0]=2;
a[1]=3;
a[2]=9;
Person[] ps;
ps=new Person[3];
ps[0]=new Person("zhangsan",32);
.....
静态初始化:在声明数组的同时给数组分配内存空间并赋值;
int[] a={2,4,6};
Person[] ps={new Person("zhangsan",34),new Person("lisi",87)};
数组的访问:
数组名[元素下标]
数组元素下标:0--n-1;n为元素个数(数组长度);
数组的元素个数能够经过数组的属性length得到;
数组的长度一旦肯定将不可改变;
多维数组:
若干个低维数组组成的数组;
特性:多维数组的声明、初始化要从高维到低维进行;
java中的多维数组能够不是规则的矩形;
int[][] a=new int[3][];
int[][] b=new int[3][4];
int[][] c=new int[][4];//非法
int[][] a=new int[3][];
a[0]=new int[3];
a[1]=new int[2];
......
多维数组的初始化:
动态初始化:
int[][] a=new int[3][];
a[0]=new int[3];
a[1]=new int[2];
......
a[0][0]=3;
a[0][1]=4;
.....
静态初始化:
int[][] a={{1,2},{3,4},{5,6,7}};
int[3][2] a={{1,2},{3,4},{5,6}};//非法
数组的拷贝:java.lang.System.arraycopy(源数组,源数组索引位置,目标数组,目标数组索引位置,长度);
数组的排序:java.util.Arrays.sort(数组类型参数);
ch05 对象和类
1、java编程语言是面向对象的,利用java语言进行编程称为面向对象编程(oop:Object-Oriented Programming)。
java编程的基本单位是类,对象要经过类进行实例化,及建立对象。
2、理解对象:
对象的概念和特征(回顾ch02讲过的内容)引出类;
3、类是一种抽象数据类型:引用类型;
类是元数据,元数据就是表示数据的数据,数据在面向对象程序设计中以对象的形式存在,类是对对象共有属性和行为的抽象描述。
成员方法:
包括实例方法(无static修饰)和静态方法(类方法,有static修饰)
参数传递
值传递:对应参数的值拷贝过程,不能影响传入参数的值;
引用传递:不能改变引用变量自己的值,只可能改变传入引用所指向对象的值;
成员变量:
包括实例变量(无static修饰)和静态变量(类变量,有static修饰)
4、this变量:表明当前对象的引用
两种用法:
this.varName(实例变量):用来区分实例变量和局部变量
简化本类构造方法的调用:this(参数列表),在本类构造方法中调用其余构造方法必须放在第一行;
5、封装:封装就是包装,java编程的基本单位是类,也就是说java是以类为基础的,全部的数据和操做都封装到类中,封装是OOP的基本特征之一;
数据隐藏:
提供统一接口;
隐藏实现细节;
提升可维护性;
6、方法的重载 Overloading
条件:
1)方法名必须相同(在同一类中);
2)参数列表必须不一样(参数个数不一样,参数类型不一样,参数顺序不一样);
3)返回类型可有可无(相同不相同都可);
在编译的过程当中根据方法参数肯定寻找相应的方法,称为编译时多态;
编译以后的方法名加上其参数类型称为惟一的名字;
7、建立和初始化对象
new的做用;
8、构造方法
构造方法是一个特殊的方法,方法名和类名相同,无返回类型;
构造方法在建立所属类型的对象时使用,做用就是建立一个对象,构造方法中的代码通常作一些初始化工做;
每一个类都有一个构造方法,若是类中没有定义构造方法,那么系统将自动为其提供一个缺省的无参构造方法;
当一个类中定义了一个或者多个构造方法,那么系统将再也不提供缺省的无参构造方法;
通常状况下一个类都要保证具备一个无参构造方法,不然影响操做;
java Web中的JavaBean在使用时,系统将默认调用其无参参构造方法,若是没有定义将出错;
使用:
在本类的其余构造方法中利用this变量来调用;
在当前类的子类中利用super变量来调用;
在程序中建立对象时经过new来调用;
9、继承
概念:在已有类型的基础上进行改进和扩充而获得新的类型,也就是在定义一个类时能够继承一个已有的类,目的是为了简化代码,实现代码的复用;
条件:“is a”的关系
子类,父类--超类,派生;
关键字:extends
特色:
1)Object类是全部java类的父类;
2)单继承
java类只能有一个直接父类,但能够派生出多个子类;
3)子类不能继承父类的构造方法;
4)子类能够继承父类中非private的方法和属性;
5)若是子类声明了一个与父类同名的成员变量,此时咱们称子类的成员变量隐藏了父类的成员变量;
5)若是子类声明了一个与父类同名的成员方法,则此时子类不能继承父类的成员方法,此时咱们称子类的成员方法覆盖(重写)了父类的成员方法
10、super变量
做用
用来调用父类中被子类隐藏的变量和被覆盖的方法;
用来在子类的构造方法中调用父类的构造方法
1)super只能用在构造方法或者实例方法中,不能用在静态方法或者静态代码块中;
2)子类构造方法必定直接或者间接地调用父类的构造方法;
3)若是子类构造方法没有显示调用父类的构造方法,也没有经过this来调用本类中其余的重载构造方法,那么将默认调用父类无参构造方法(若父类中没有则出错);
11、方法覆盖:
覆盖(重写)overriding:子类根据须要对从父类继承来的方法进行重写实现;
条件:
1)重写发生在子父类之间,同一类中的方法不能被重写只能被重载。
2)重写方法和被重写方法要保证具备相同的方法名字、参数列表、返回类型;
3)重写方法不能具备比被重写方法更严格的访问权限;
4)重写方法不能抛出比被重写方法范围更大的异常;
5)静态方法的重写:父类的静态方法能够被子类同名的静态方法重写,此时隐藏了父类的方法;父类的静态方法不能被子类非静态的方法重写(编译错误);父类非静态的方法不能被子类重写为静态方法;
12、多态
多态是发生在继承的基础上的;
父类 FatherClass 类 Son1Class Son2Class...
FatherClass fc=new Son1Class()或者new Son2Class();
父类的一个引用能够指向多种不一样的子类对象;也就是引用能够有不少类型(能够是类型自己也能够强转为所指向对象的类型);
可是一个对象只有一个类型;
多态就是因为一个父类引用指向不一样的子类对象所引起的现象。当一个父类引用指向不一样的子类对象调用相同的方法时,表现出不一样的行为;
多态不像方法重载那样发生在编译时刻,而是发生在运行时刻。
13、instanceof
用法:引用变量 instanceof 类型名
判断引用变量是否指向指定类型的对象或者指定类型的子类型对象,若是是返回true,不然返回false;
引用类型之间的转换:
显式转换:父类型--》子类型(先用instanceof进行类型判断,结果为true才可进行强转)
隐式转换:子类型--》父类型
转化原则:被转化的实际对象类型必须是转化后类型自己或者子类型;
Animal a=new Animal();
Bird b=(Bird)a;
Animal a=new Bird();
Bird b=(Bird)a;
Animal a=new Bird();
Animal aa=(Bird)a;
14、Object类,“==”和equals方法
Object类是全部java的根类;
“==”符号对于基本数据类型就是比较值是否相等,
例如a=2,b=3;a == b返回false;
若是“==”比较两个引用变量也是比较两个引用变量的值是否相等;也就是说看两个引用变量是否指向内存中同一个对象,若是指向同一个对象返回true,不然则返回false;
equals方法:比较两个对象是否相等
,即同一类型的两个对象的各属性值是否相等,若是相等返回true不然返回false;
Object类中实现的equals方法实际和“==”功能相同,因此定义类时一般重写equals方法实现对象相等的比较;
equals和toString方法重写
String类
finalize方法使用
ch06 高级特性
1、static修饰符
static修饰符能够修饰成员变量、成员方法、代码块和内部类。
用static修饰的成员变量,称为成员变量或者类变量,能够经过类名.静态变量名来访问;
用static修饰的成员方法,称为静态方法或者类方法,能够经过类名.静态方法名来访问;
用static修饰的程序代码块,称为静态代码块,在类加载时由java虚拟机执行;
用static修饰的成员变量和成员方法属于整个类公有,不依赖于类的某个实例,为类的全部实例共享;
静态变量:
成员变量分为静态变量和实例变量:
区别:
静态变量属于某个类,在内存中静态变量只存一份,为该类全部实例共享;实例变量对于该类的每个实例在内存都存一份,互不影响;
java虚拟机在加载类时就为静态变量分配内存,实例变量是在利用类建立对象时分配内存;
静态变量存放在内存中静态变量常量区,实例变量存放在堆区;
静态变量经过类名.变量名访问(固然静态变量也能够经过实例名.变量名来访问,可是将出现警告信息),实例变量经过实例名.变量名访问;
实例一:说明内存分配;实例二:统计一个类建立实例的个数;
静态方法:
1)静态方法不能直接访问类的非静态成员(实例变量和实例方法),能够直接访问类的静态成员;
2)静态方法中不能使用this和super关键字;
3)子类中能够定义与父类同名的静态方法,这成为子类隐藏了父类的静态方法,此时也要知足覆盖条件;可是要注意:静态方法和类绑定,执行静态方法时要看该引用的实际类型,实例方法和实例绑定,执行实例方法要看引用指向对象实际类型;
4)父类中的静态方法不能被覆盖为非静态方法,反之也成立;
静态代码块:
定义在类的内部,方法外部由static修饰的代码块称为静态初始化代码块,类加载时自动执行,而且只执行一次;
非静态代码块:实例化块
非静态代码块在建立对象时自动执行;
静态代码块,非静态代码块,构造方法的执行顺序???
static应用:单例模式
设计模式:不一样于语法,高于语法,是一种设计思想,是被人反复使用、多人知晓的、前人代码设计经验的总结;例如单例模式、门面模式、MVC设计模式等
单例模式--》编写一个类实现该类只能产生惟一一个实例(对象);
1)提供一个私有的构造方法;
2)提供一个本类类型的私有的static的成员变量,并使用构造方法进行初始化;
3)提供一个public的方法得到成员变量即惟一实例;
2、final修饰符
final具备最终的,不可改变的意思,final能够修饰类、变量、方法;
final修饰的类不能被继承;
final修饰的方法不能被覆盖;
final修饰的变量即常量,不能被改变只能被赋值一次;常量只能在声明的同时赋值或者在构造方法中显式赋值,赋值后才能使用;
final不能修饰构造方法,抽象类和抽象方法;
3、abstract修饰符
abstract能够用来修饰类、成员方法,称为抽象类和抽象方法;
抽象方法:
只有方法声明,没有方法实现;
public abstract void setName(String name);//抽象方法
抽象方法必须用abstract修饰;
public void setName(String name){
}//不是抽象方法,是普通方法或者说是具体方法,只是实现为空实现;
抽象类:
用abstract修饰的类称为抽象类
语法规则:
1)抽象类不能实例化对象,能够声明引用;
public abstract class A{
.........
}
A a;//合法
new A();//非法
2)包含抽象方法的类必须声明为抽象类;但抽象类能够不包含抽象方法;//??想想若是能够实例化对象,来调用其中的抽象方法将执行什么???
3)定义抽象类主要用来定义新类时去继承它,子类继承抽象类要实现其中的全部抽象方法,不然必须也声明为抽象类;
抽象类主要做用是:规划和重用代码;由子类继承抽象类去发挥做用;
4)abstract修饰的方法、类不能有final来修饰;
4、接口interface
概念:接口本质是特殊的抽象类,比抽象类更抽象,是常量和抽象方法的集合,接口中只能包含常量和方法的定义,不能定义变量和方法的实现。
public interface Runner{
public static final int id=0;
public abstract void start();
public abstract void run();
public abstract void stop();
}
接口中的定义的属性默认就是public static final修饰的,方法默认是public abstract修饰的,所能够省略;
public interface Runner{
int id=0;
void start();
void run();
void stop();
}
接口和抽象类同样不能实例化对象,只能声明引用;
和继承类似,java类能够实现一个或者多个接口,类实现接口就必须实现所要实现接口中的全部抽象方法;
和子父类同样,接口与实现类之间也存在多态;
数据库--》任何语言数据库编程访问数据库--》导入驱动(SQL Server-微软,Oracle-oracle)
sun共制定统一接口 数据库厂商实现接口(驱动包)
接口能够继承,而且支持多继承;即定义一个接口能够继承一个或者多个已经存在的接口;
类能够在继承一个类的同时实现一个或者多个接口;
5、访问修饰符
类的修饰符
成员修饰符
6、内部类:在一个类内部再定义的一个类;
例如:
public class A{
private class B{
....
}
static class C{
....
}
接口名或抽象类 引用=new 接口名或抽象类(){
.......
};
public void test(){
class D{
...
}
if(...){
class E{
...
}
}
接口名或抽象类 引用=new 接口名或抽象类(){
.......
};
}
}
在程序中,凡是使用内部类的地方均可以使用普通类(顶层类)来替代,使用内部类可以使程序更有条理性,代码更加简洁,便于划分类的层次结构和命名规范。
根据变量划分原则来划份内部类:
做用
域划分:
成员内部类:实例内部类 静态内部类
局部内部类:
另外还有一种特殊的局部内部类没有名字,称为匿名内部类;
顶层类:public default
内部类的访问修饰符:private default protected public
静态内部类:最简单一种;
用static修饰的成员内部类(定义在外部类的内部,方法的外部);
1)不能用private修饰;
2)只能访问外部类的静态成员,不能访问非静态成员;
3)建立静态内部类实例不依附于外部类的实例,能够直接经过外部类名.内部类名来建立;
new OuterClass.InnerClass();
实例内部类:没有static修饰的成员内部类;
能够访问外部类的一切成员;
建立内部类的实例要依附于外部类的实例;
例如(new Outer()).new Inner();
局部内部类:定义在方法体内或者代码块内;
1)局部内部类和局部变量同样不能使用public,private,protected,static修饰符;
2)局部内部类能够访问外部类的一切成员,只能使用方法体内或者代码块内final修饰的局部变量(常量);
3)局部内部类只能在所定义的方法体内或者代码块内使用;
匿名内部类:既能够定义在方法体或者代码块内,也能够定义在方法体或者代码块外,没有名字,只能在所在之处使用一次;
匿名内部类必定在new关键字的后面使用,隐含着继承一个父类或者实现一个接口,没有名字,根据多态,使用其父类名或者所实现接口名字;
父类名 引用=new 父类名{....};
接口名 引用=new 接口名{....};
应用:a.当类与接口(或者是接口与接口)发生方法命名冲突的时候,此时必须使用内部类来实现。
b.用接口不能彻底地实现多继承,用接口配合内部类才能实现真正的多继承。
7、封装类:java API为每一个基本数据类型提供了一个包装类;
int --- Integer:对int类型数据进行包装成为一个对象;
byte-----Byte
short----Short
char---Char
boolean----Boolean
float----Float
double----Double
long ----Long
封装类处于:java.lang包下
做用:1)用引用类型表示数值,例如表示一个缺考学生的成绩;
2)有些场合必须使用引用类型,例如:集合中只能存放引用类型;
3)用于基本数据类型间以及与字符串间的转换;
以Integer为例讲解:查阅API文档
8、集合:
引入集合:数组的缺点
集合的概念:用来存放多个对象的对象,而且只能存放对象(引用类型),这个对象能够用来维护和管理一组相同和类似的对象;
集合三要素:接口,接口的实现类,算法
集合相关的要素由java API提供,处于java.util包下
主要掌握用法;
集合框架接口层次图:
Collection:集合的根接口,
集合分为三类:
Set:不容许存放重复的元素,其中存放的元素是无序的;
List:按照必定的顺序存放元素(不是排序),能够存放重复的元素;
Map:存放键值对,不容许存放键重复的键值对,一个键只能对应一个值;
briup---02111111111
SortedSet:和Set相似,其中的元素按升序排列;
SortedMap:和Map相似,其中的键值对按键升序排列;
接口实现类:
Collection--》无直接实现类,提供了访问集合的通用方法;
List---》ArrayList,Vector,LinkedList
Set --》HashSet,LinkedHashSet
SortedSet--》TreeSet
Map---》HashMap
SortedMap---》TreeMap
ArrayList类:实现了List接口,用于表示长度可变的数组列表;在构造对象时能够指定列表长度(所能容纳元素个数),默认长度为10,不指定长度但添加对象数目超过10时,系统将自动增长列表长度;
查阅ArrayList类的API;
Vector类:与ArrayList同样也实现了List接口,表示一个可变的对象数组;
与ArrayList的差异:Vector是同步(线程安全)的,占用的资源多一些,运行效率要低一些,主要用在多线程环境下,ArrayList是不一样步的,适合在单线程环境下使用;
Iterator(迭代器):Iterator描述的是使用统一方式对各类集合元素进行遍历/迭代的工具,也称为迭代器;
主要方法:
public interface Iterator{
boolean hasNext();
Object next();
void remove();
}
HashSet类:实现了Set接口,HashSet不能存放重复的元素,其中的元素是无序的;HashSet中能够存放null
HashSet在存储对象元素时,会根据对象的哈希码来计算对象的存储位置,对象的哈希码是经过Object类提供的hashCode()方法来得到,hashCode()方法返回的值是根据对象的内存地址获得哈希码,这两个对象经过new来构造的其地址不同,那么获得的哈希码就不同,因此HashSet认为二者是不一样的对象;
hashCode返回相同值的同时必须保证对象的equals方法为真这样HashSet才认为二者为相同的对象;
结论:如将自定义类对象用hashSet来添加时,必定要覆盖hashcode()和equals()这两个方法,覆盖的原则是保证当两个对象相同时hashcode返回相同的整数,并且equals()返回的值为True。
TreeSet类:实现了Set接口,实现了排序功能的集合;
在将对象元素添加到TreeSet中时会按照必定排序规则将元素插入到有序的对象序列中,保证TreeSet中的元素组成的对象序列时刻按照“升序”排列;
向TreeSet添加的对象元素的类型必须实现Comparable接口,不然程序编译时出现java.lang.ClassCastException异常,API中String类、封装类都已实现该接口;
HashMap类:实现了Map接口,用于存放“key-value”对信息,不能存放键值重复的“键-值”对;
主要方法:
TreeMap类:使用和HashMap相似;向TreeMap添加的"键--值"对元素的键类型必须实现Comparable接口,不然程序编译时出现java.lang.ClassCastException异常,API中String类、封装类都已实现该接口,这一点和TreeSet彻底一致。
反射:
1、概念
java程序在运行时能够动态加载、解析和使用编译时并不肯定的类型,这种机制称为反射或者说是内省;也就是说反射机制在运行状态中,对于任意一个类能够知道它具备的属性和方法,若是是一个对象,能够调用它的任意一个方法;指的是动态地获取类型信息和动态执行对象方法的功能;
2、功能
动态加载编译时不肯定的类型;
解析类型结构,获取内部信息;
操做类型及其实例,具体包括访问属性信息、执行对象方法、建立实例;
3、反射相关API
java.lang.Class:类类型,用来描述java类的抽象类型,和普通的java类同样。(类是用来描述对象的抽象类型,类的实例是一个特定的对象)
Class的实例表示运行时的java类型,例如:类、接口、注释、数组、枚举、java基本数据类型和void。
在类加载时,java虚拟机将自动建立一个相应的Class对象来描述所加载类的类型信息,即java类的成分信息(属性,构造方法,方法,所实现的接口,所继承的父类,所在包等等信息)。
java.lang.Class
java.lang.reflect.Field
java.lang.reflect.Method
java.lang.reflect.Constructor
java.lang.reflect.Modifier
4、反射编程的基本步骤:
1)得到Class实例
引用类型获取方式:
a:利用Class提供的静态方法forName:
Class c=Class.forName("类名");// 这里的类名指的是类的全名:包名+类名;
b:利用Object类提供的getClass方法:
Person p=new Person();
Class c=p.getClass();
c:利用.class表达式
Class c=类名.class;//这里的类名指的是类的全名:包名+类名;
Class c=String.class;
Class c=com.briup.Person.class;
基本数据类型和void的获取方式:
a:利用.class表达式
Class c=int.class;
Class c=void.class;
b:利用包装类的TYPE
Class c=Integer.TYPE;//表示的是int不是Integer(Integer.class);
Class c=void.TYPE;
2)利用Class对象的方法来得到类型的相关信息;
查阅java.lang.Class API;
3)访问/操做类型成员
java.lang.reflect.Field
java.lang.reflect.Method
java.lang.reflect.Constructor
java.lang.reflect.Modifier
public static final
public static void setName(int a,int b,String str){
};
ch07 异常
1、异常的基本概念:
1)异常产生的条件
或者称为异常状况。在Java代码中哪些是异常状况呢? 例如:
a. 整数相除运算中,分母为0;
b. 经过一个没有指向任何具体对象的引用去访问对象的方法;
c. 使用数组长度做为下标访问数组元素;
d. 将一个引用强制转化成不相干的对象;
..........
2)异常会改变正常程序流程;异常产生后,正常的程序流程被打破了,要么程序停止,要么程序被转向异常处理的语句;
3)当一个异常的事件发生后,该异常被虚拟机封装造成异常对象抛出。
4)用来负责处理异常的代码被称为异常处理器
5)经过异常处理器来捕获异常
6)异常分为错误(Error)和违例(Exception)两种:
错误Error是指像JVM错误,内存资源耗尽等严重状况。程序一旦发生错误是不可恢复的,只能终止程序;
违例Exception是指因为编程错误或者偶然的外在因素引起的事件致使的通常性问题,如网络链接中断、试图打开/读取不存在的文件、数组越界、空指针访问、对负数开平方等。程序发生违例Exception,能够经过适当的手段方式使得程序得以继续运行。
7)在Java中异常是特殊的运行错误对象。是面向对象规范的一部分,是异常类的对象,Java声明了不少异常类,每一个异常类都表明了一种运行“错误”。每当Java程序运行过程当中发生一个可识别的运行“错误”时,即该“错误”有一个异常类与之相对应时,系统都会产生一个相应的该异常类的对象,即产生一个异常。
2、java异常类层次:
Throwable
|
Error Exception
.....................
1)Error类:表示仅靠程序自己没法恢复的严重错误,好比内存空间不足,或者Java虚拟机的方法调用栈溢出。在大多数状况下,遇到这样的错误时,建议让程序终止。
2)Exception类:表示程序自己能够处理的异常。Exception还能够分为两种:运行时异常和受检查异常。
RuntimeException:运行时异常或者称为未检查异常,编译器不要求捕获、处理;
java.lang.ArithmeticException 算术异常,如除数为0
java.lang.ArrayIndexOutOfBoundsException 数组越界异常,如一个数组由3个元素,访问第4个元素;
java.lang.NullPointerException 空指针异常,没有初始化引用变量就使用
java.lang.NumberFormatException 数据格式转换异常,如Integer.parseInt("a");
java.lang.SecurityException 安全异常,通常碰不到
java.lang.NegativeArraySizeException 数组长度负数异常;
上述异常为unchecked异常,编译器不要求必须捕获,也就是说在程序中不进行异常处理编译时也不会报错,这个时候做为程序员必须考虑到这些状况,确保异常不要发生。如在作除法运算时必须确保除数不为0,经过引用变量访问对象时确保对象不为空等。
运行时异常表示没法让程序恢复运行的异常,致使这种异常的缘由一般是因为执行了错误操做。一旦出现了错误操做,建议终止程序,所以Java编译器不检查这种异常。运行时异常应该尽可能避免。在程序调试阶段,遇到这种异常时,正确的作法是改进程序的设计和实现方式,修改程序中的错误,从而避免这种异常。捕获它而且使程序恢复运行并非明智的办法。
受检查异常:除了RuntimeException及其子类之外, 其余的Exception类及其子类都属于受检查异常(Checked Exception)。 这种异常的特色是Java编译器会检查它,也就是说,当程序中可能出现这类异常时,要么用try...catch语句捕获它,要么用throws子句声明抛出它,不然编译不会经过。
例如java.io.IOException,java.lang.ClassNotFoundException,java.io.FileNotFoundException;
3、异常处理
checked异常必须处理,处理有两种方式:就地处理(try-catch块,捕获)和向上抛出;向上抛出异常使用throws关键字,声明将异常抛出给方法的调用者;
异常处理宗旨
1)使得程序返回到一个安全、已知的状态;
2)可以让用户执行其余命令;
3)若是可能保存全部的工做;
4)若是有必要能够退出,以免进一步危害;
异常处理机制
1)java程序在执行过程当中若是出现异常,系统监测到并自动生成对应的异常类对象,而后将它交给运行时系统;
2)运行时系统会寻找相对应的代码来处理这一异常,若是运行时系统找不到对应的异常处理代码,则运行时系统将终止,相应的java程序也将不得不退出;
3)程序员对错误Error无能为力,能够对违例Exception进行处理。
try{
....//可能产生异常的代码
}catch(ExceptionName1 e1){
....//异常处理代码
}catch(ExceptionName2 e2){
....//异常处理代码
}[finally{
....//无条件执行的语句,通常用于资源的释放
}]
在try/catch块语句中能够有多个catch语句,可是其捕获异常类对象应从特殊到通常(从窄到宽)
若是父类中的方法抛出多个异常,则子类中的覆盖方法要么抛出相同的异常,要么抛出异常的子类,但不能抛出新的异常(注:构造方法除外);
import java.io.*;
class B{
public void b() throws Exception{
}
}
class C extends B{
public void b() throws FileNotFoundException,IOException{//合法
}
}
class C1 extends B{
public void b() throws IOException{//合法
}
}
异常调用栈:异常处理时所通过的一系列方法调用过程被称为异常调用栈。
1. 异常的传播:哪一个调用,哪一个处理;
a. 异常状况发生后,发生异常所在的方法能够处理;
b. 异常所在的方法内部没有处理,该异常将被抛给该方法调用者,调用者能够处理;
c. 如调用者没有处理,异常将被继续抛出;如一直没有对异常处理,异常将被抛至虚拟机;
2. 若是异常没有被捕获,那么异常将使你的程序将被中止。
异常产生后,若是一直没有进行捕获处理,该异常被抛给虚拟机。程序将被终止。
3. 常常会使用的异常API
getCause():返回类型是Throwable,该方法得到Throwable的异常缘由或者null。
getMessage():得到具体的异常出错信息,可能为null。
printStackTrace():打印异常在传播过程当中所通过的一系列方法的信息,简称异常处理方法调用栈信息;在程序调试阶段,此方法可用于跟踪错误。
异常对象能够人为制造:
java异常对象除了当程序运行出错时有系统自动生成并抛出外,还能够人工建立异常对象并抛出;使用关键字throw
IOException e=new IOException();
throw e;
或者
throw New Exception();
在人工抛出异常时,必须是Throwable及其子类的对象,不然编译时将产生语法错误;
throw new String("aaa");//非法
throw语句后面不容许紧跟其它语句,由于这些语句永远不会被执行。
4、自定义异常
能够定义本身的异常类,继承Exception,必须人工抛出;
5、断言
JDK1.4引入,在java程序中加入检查语句,主要用于程序调试;
断言机制:
在程序中定义的boolean表达式(假定条件)不成立时(即返回false),系统将产生一个Error对象,类型为AssertionError类型;
在约定条件不成立的状况下须要终止程序操做时使用断言;
断言做为Error的一种,断言失败没必要进行铺获处理或者声明抛出,一旦出现终止程序,没必要进行补救和恢复。
使用断言
assert boolean表达式[:表达式]
断言用于程序调试,java运行时环境默认关闭断言功能;
开启断言功能:
java -ea classname
或者
java -enableassertions classname
关闭断言功能:
java -da classname
或者
java -disableassertions classname
ch08 GUI
1、基本概念
GUI:Graphics User Interface 图形用户界面,与用户交互的窗口;
咱们之前讲的内容也能够说程序都是经过命令行窗口或者说是控制台和用户进行交互,能够经过键盘输入数据给应用程序,程序经过命令行窗口或者控制台返回程序运行后的结果数据给用户,GUI是经过图形化的方式和用户进行交互;图形用户界面更友好,和用户交互很方便;典型是Windows界面,PPT等;
AWT:Abstract Window ToolKit抽象窗口工具集
AWT是JDK的一部分,能够说是Java API的子集,其中包括组件、容器和布局管理器等要素;AWT支持Java GUI事件处理;使用AWT能够进行Java GUI的开发;
AWT构建图形用户界面的机制包括:
提供了一些容器组件(如Frame和Panel), 用来容纳其余的组件(如按钮Button、复选框Checkbox和文本框TextField)。
用布局管理器来管理组件在容器上的布局;
利用监听器来响应各类事件,实现用户与程序的交互。一个组件若是注册了某种事件的监听器,由这个组件触发的特定事件就会被监听器接收和响应;
相关软件包:
java.awt.*:GUI基本组件包;
java.awt.event.*:java GUI事件处理包(用于实现与用户交互);
javax.swing.*:图形界面升级包;
2、组件:Component
组件是图形用户界面的基本组成元素;凡是可以显示在屏幕上而且可以和用户交互的对象称为组件,例如:菜单、按钮、标签、文本框和滚动条等;
组件不能单独的显示出来,必须放在必定的容器中才能显示出来;
在java.awt.*包中定义了不少组件类:Button、Menu、Lable、TextField;
在java.awt.*包中有一个抽象类java.awt.Component,该类是除了Menu类以外全部组件类的功能父类,其中定义了GUI组件的基本特征,例如:尺寸、位置、颜色等;还实现了做为GUI组件应该具有的基本功能;
3、容器:Container
容器自己也是一个组件,具备组件具备的全部性质,只是容器组件能够容纳其余组件或者容器;因此Container是Component的子类;
容器具备add()方法用于添加其余组件到容器中;
容器分类:
1)java.awt.Window
能够自由停泊的顶级窗口;例如:PPT
2)java.awt.Panel
能够做为容器容纳其余组件,可是不能独立存在,必须添加到其余容器;例如:添加到Frame中;
Frame
Frame的类层次结构:java API
java.lang.Object
java.awt.Component
java.awt.Container
java.awt.Window
java.awt.Frame
1、Frame对象的显示效果是一个能够自由停泊的“顶级”窗体;带有标题和尺寸重置角标;
2、Frame默认是不可见的,能够调用Frame的setVisible(true)方法设置为可见;
3、做为容器Frame可使用add()方法添加组件;
Panel
提供容纳组件的空间,不能独立存在,必须添加到其余容器中;
能够采用与所在容器不一样的布局管理器;
组件定位:
java组件在容器中的定位由布局管理器决定;
若是人工控制组件的定位,可取消布局管理器,而后使用Component的方法:
setLocation(),setSize,setBounds()
void setBounds(int x, int y, int width, int height)
void setSize(int width, int height)
void setLocation(int x, int y)
GUI的坐标系:
4、布局管理器:LayoutManager
用来控制组件在容器中的排列风格;包括组件的位置和大小的设定;
为了使java GUI程序具备良好的平台无关性,java提供了LayoutManager来管理容器的布局,不建议直接设置组件在容器中的尺寸和位置;
每一个容器都有一个默认的布局管理器,当容器须要对某一组件进行定位或者判断其大小尺寸时,就会调用对应的布局管理器;
GUI程序的开发步骤:
1、肯定容器;
2、设置布局管理器
3、向容器添加组件
4、添加事件处理器
一个容器只能有一种排列风格;
例如:BorderLayout、FlowLayout、GridLayout、CardLayout、GridBagLayout等;
Window及其子类(Frame、Dialog)默认布局管理器为BorderLayout;
Panel及其子类(Applet)默认布局管理器为FlowLayout;
BorderLayout
BorderLayout布局管理器是Frame默认的布局管理器;
布局效果:
BorderLayout将容器划分为东西南北中五个区域,组件只能被添加到指定的区域;
添加组件时若是没有指定添加区域,默认添加到Center区域;
一个区域只能放一个组件,若是在一个区域添加多个组件,则先前添加的组件将做废;
组件大小被强行控制,大小与指定区域大小相同;
BorderLayout容器的缩放原则;
FlowLayout
FlowLayout是Panel容器的默认布局管理器
布局效果:
组件在容器中逐行加入,行内自左向右,排满一行后换行;
不改变组件大小,按原始大小加入;
组件在容器中默认居中对齐,也能够经过构造方法设置对齐方式,行间距,组件间距;
GridLayout
GridLayout布局效果:
将容器划分为规则的矩形网格,按照组件的加入顺序自左向右逐行加入,行间自上而下,将组件放入单元格;
组件大小被强行控制,和单元格大小相同,随着容器的大小变化,组件大小自动调整,但相对位置不变;
CardLayout
将多个组件放在容器的同一区域内交替显示,就像落在一块儿的扑克牌只显示最上面的一张;
CardLayout能够按照名称显示某一张卡片,或者按照顺序依次显示每一张卡片,也能够直接定位到第一张、下一张、上一张或者最后一张;
GridBagLayout
GridBagLayout是创建在GridLayout布局管理器基础上的一种极为复杂和灵活的布局管理方式。
容器嵌套
容器嵌套可使得本来只能显示一个组件的区域能够显示多个组件;
5、GUI事件处理
引言:
图形用户界面设计并非咱们Java GUI程序设计的所有,甚至不是主要的部分,前面所讲的GUI界面不能用户交互,是静止的,这不是咱们想要的。GUI程序应该可以和用户很好的交互,也就是说经过图形界面可以接收来自用户的输入,而且可以按照用户操做作出相应的响应。
Java GUI事件处理机制:
GUI事件处理机制和异常处理机制相似,JDK为GUI组件的各类可能操做预先定义了事件类,若是用户触发了组件的某一操做,组件将产生对应事件类的事件对象,此时将根据事件对象执行注册在该组件上的监听器与事件对象相对应的方法(固然前提是对于咱们关心的组件事件,已经在组件上注册了对应的监听器并实现了事件处理方法)。
当用户与GUI交互,好比移动鼠标、按下鼠标键、单击Button按钮、在文本框内输入文本、选择菜单项或者关闭窗口时, GUI会接收到相应的事件,即各类可能的操做。
GUI事件处理的基本概念:
1、事件对象:事件就是描述发生了什么事,也能够说是对组件进行了什么操做,在Java中,用事件对象来描述事件,事件一旦被触发组件就产生对应的事件对象,事件对象对应的类通常均是Java API直接提供,自已不多构建事件对象类;例如:用户对按钮进行了单击操做,被单击的按钮组件将产生ActionEvent事件对象;
2、事件源:可以接收用户事件(用户操做)并产生事件对象的GUI组件都被当作事件源,事件源产生事件对象;如按钮、文本框等;
3、事件监听器:对事件进行处理的对象;该对象定义了可以接收、解析和处理事件的方法,该方法实现与用户交互;
每一种事件都对应专门的监听器中的某一方法。监听器中的方法负责接收和处理这种事件。一个事件源能够触发多种事件,若是它注册了某种事件的监听器,那么这种事件就会被接收和处理。
称为事件处理模型的三要素。
案例总结:GUI事件处理
1、定义监听器类,该类实现特定的接口中的对应抽象方法即编写本身的程序处理逻辑;
2、在相应组件上添加该监听器对象;
3、今后监听器将对该组件发生的某一操做进行监听,若发生对应事件将执行对应监听器的事件处理方法;
ActionEvent
当菜单或者按钮触发ActionEvent事件时,使用actionCommand属性来记录事件的相关指令信息;
从所讲案例中能够看出,GUI程序的运行结果做为开发者并不能控制,和用户操做有关,咱们称之为事件驱动程序;
GUI事件类型层次
java.util.EventObject
ActionEvent(点击时触发) ContainerEvent
java.awt.AWTEvent AdjustmentEvent FocusEvent KeyEvent
ComponentEvent InputEvent MouseEvent
ItemEvent WindowEvent
TextEvent
ActionEvent:指鼠标在菜单、按钮进行点击等
AdjustmentEvent:组件或者容器的大小发生变化或者重置
ItemEvent:组件条目发生变化时触发,例如当列表框中条目发生变化或者被选中;
TextEvent:当文本框或者文本域中内容发生变化时触发事件;
ContainerEvent:当向容器加入组件或者从容器移除组件时触发;
FocusEvent:焦点事件,例如组件得到或者失去焦点时触发的事件;
InputEvent:是父类,当用鼠标、键盘进行输入时触发;
KeyEvent:是InputEvent的子类,当用键盘进行输入时触发;
MouseEvent:是InputEvent的子类,当用鼠标进行输入时触发;
WindowEvent:当窗口初始化、最大化、最小化、关闭或者销毁都会触发这种事件;
事件及相应的监听器接口
1)windowActivated(WindowEvent e) //激活窗口
2)windowClosed(WindowEvent e) //调用dispose方法关闭窗口后
3)windowClosing(WindowEvent e) //试图利用窗口关闭框关闭窗口
4)windowDeactivated(WindowEvent e) //本窗口成为非活动窗口
5)windowDeiconified(WindowEvent e) //窗口从最小化恢复为普通窗口
6)windowIconified(WindowEvent e) //窗口变为最小化图标
7)windowOpened(WindowEvent e) //当窗口第一次打开成为可见时
1)keyPressed(KeyEvent e) //键已被按下时调用
2)keyReleased(KeyEvent e) //键已被释放时调用
3)keyTyped(KeyEvent e) //键已被按下并释放时调用
1) componentHidden(ComponentEvent e) //组件隐藏
2) componentMoved(ComponentEvent e) //组件移动
3) componentResized(ComponentEvent e) ///组件改变大小
4) componentShown(ComponentEvent e) ///组件变为可见
1)componentAdded(ContainerEvent e) ///容器内加入组件
2)componentRemoved(ContainerEvent e) //从容器中移走组件
6、Swing组件
处于java.swing.*;
Swing与AWT的关系:
Swing是创建在java AWT的基础上的加强型组件集或者说工具集,使用轻量级组件来替代AWT中绝大多数重量级组件;
JFC:Java Foundation Classes,java基础类库和想象的不同,JFC专指用于建立java 图形用户界面的API,具体包括Swing、AWT、Java 2D等;
重量级组件:调用操做系统底层组件完成功能,开销大效率低而且具备严重的平台相关性;
轻量级组件:经过java绘图技术实现,开销小效率高具备平台无关性;
Swing组件较AWT功能更强大,更复杂;Swing组件的根类JComponent继承自java.awt.Container;
使用JFrame和JTextField;
7、多重监听器:
一般状况下,事件源能够产生不一样的事件对象,于是能够注册(触发)多种不一样类型的监听器;
1、同一事件源能够注册多个监听器;
2、同一事件源的同一种事件能够注册多个监听器;
3、一个监听器能够被多个事件源注册。
8、适配器类:Adapter
Adapter是针对大部分的事件监听器接口所定义的对应的实现类,适配器类实现了相应的监听器接口中的全部方法,只不过全部的方法都是空实现即什么事情都不作。
例如:MouseMotionAdapter类的定义为:
package java.awt.event;
public abstract class MouseMotionAdapter implements MouseMotionListener{
public void mouseDragged(MouseEvent e) { }
public void mouseMoved(MouseEvent e) { }
}
为何要有适配器类?
经过前述实例能够看出,若是要实现GUI的事件处理,要在定义监听器类时实现监听器接口,既然是实现接口必须实现其中全部的方法,在实现的方法中可能有些在程序中根本用不到,固然用不到的方法也只是空实现,尽管是这样这也是程序员十分讨厌的事情。因此出现了Adapter。
主要适配器类介绍:
适配器类 实现的接口
MouseAdapter MouseListener
MouseMotionAdapter MouseMotionListener
FocusAdapter FocusListener
WindowAdapter WindowListener
KeyAdapter KeyListener
ComponentAdapter ComponentListener
ContainerAdapter ContainerListener
两点说明:
1、在JDK中定义的适配器类都是abstract的,其实这不是必须的,只是怕程序员误用。
2、适配器类不能彻底替代监听器接口。
假如一个监听器既要监听鼠标事件对象,又要监听单击事件对象应该怎么办??
9、监听器类常用内部类实现;
监听器类中方法所实现的功能:重用价值不大。
1、学会经常使用组件的使用;
2、习惯于查阅API文档;
软件工程:
计算器:
需求分析、设计、实现
利用GUI编程实现一个记事本。
ch10 线程
1、基本概念
程序:
程序是计算机指令的集合或者说一组指令序列,它以文件的形式存储在磁盘上。
进程:
进程是一个程序在其自身的地址空间中的一次执行活动,也能够说进程是运行中的程序;
进程是资源申请、调度和独立运行的单位,所以,它使用系统中的运行资源;而程序不能申请系统资源,不能被系统调度,也不能做为独立运行的单位,所以,它不占用系统的运行资源。
程序和进程是不一样的概念,一个程序对应多个进程;
计算机是支持多进程的;
线程
线程是进程中的一个单一的执行流程。
进程是程序的一次执行,程序执行过程当中可能有不少个执行流程,因此说:一个进程能够拥有多个线程。
在进程地址空间中,真正完成任务的是线程。
线程又称为轻量级进程,它和进程同样拥有独立的执行控制,由操做系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通讯远较进程简单。
因此说线程依附于进程,也就是说一个线程必有一个父进程。
计算机支持多线程;
为何设计多线程?
是否可使用多进程程序替代多线程程序?
Java语言是第一个语言级支持多线程的语言。
2、java中线程的概念模型(三要素):
虚拟的CPU:由java.lang.Thread封装和模拟;
Code:CPU要处理的代码,传递给Thread对象;
Data:CPU要处理的数据,传递给Thread对象;
3、线程的建立:
1)直接继承java.lang.Thread
查看java API了解Thread中的方法;
Thread-n
2)实现Runnable接口
run方法:线程体,线程所实现的业务功能代码;
start方法:启动一个线程,执行线程的run方法;
比较两种建立线程方式:
实现Runnable接口:推荐使用
1)实现接口的同时继承一个其余的java类;
2)将CPU、代码和数据分开;
继承Thread类:
1)编写简单
2)继承Thread的同时不能继承其余类;
区分几种线程:
1)用户线程User Thread:用户建立的线程;
2)main线程:程序的入口方法,程序的主线索;
3)后台线程Daemon Thread:也叫精灵线程,在后台运行,礼让其余线程执行,在系统空闲时运行;例如:JVM中的垃圾回收线程就是一个后台线程;
4)子线程Sub Thread:定义在其余线程中的线程;
3、线程的生命周期:
1)线程的实现有两种方式,一是继承Thread类,二是实现Runnable接口,不管哪一种方式,当建立了(new+构造方法)线程对象后,线程就进入了初始状态;
2)当该对象调用了start()方法,就进入可运行状态;
3)进入可运行状态后,当该对象被操做系统选中,得到CPU时间片就会进入运行状态;
4)进入运行状态后状况就比较复杂了
4.1、run()方法或main()方法结束后,线程就进入终止状态;
4.2、当线程调用了自身的sleep()方法或其余线程的join()方法或者发出了IO请求,就会进入阻塞状态(该状态既中止当前线程,但并不释放所占有的资源)。当sleep()结束或join()结束后或者IO操做结束或者调用线程的interupt方法,该线程进入可运行状态,继续等待OS分配时间;
4.3、线程调用了yield()方法或者时间片用完,意思是放弃当前得到的CPU时间片者时间片用完线程还没结束,回到可运行状态,这时与其余进程处于同等竞争状态,OS有可能会接着又让这个进程进入运行状态;
4.4、当线程刚进入可运行状态(注意,还没运行即将运行),发现将要调用的资源被synchronize(同步),获取不到锁标记,将会当即进入锁池状态,等待获取锁标记(这时的锁池里也许已经有了其余线程在等待获取锁标记,这时它们处于队列状态,既先到先得),一旦线程得到锁标记后,就转入可运行状态,等待OS分配CPU时间片;
4.5、当线程调用wait()方法后会进入等待队列(进入这个状态会释放所占有的全部资源,与阻塞状态不一样),进入这个状态后,是不能自动唤醒的,必须依靠其余线程调用notify()或notifyAll()方法才能被唤醒(因为notify()只是唤醒一个线程,但咱们由不能肯定具体唤醒的是哪个线程,也许咱们须要唤醒的线程不可以被唤醒,所以在实际使用时,通常都用notifyAll()方法,唤醒全部线程),线程被唤醒后会进入锁池,等待获取锁标记。
线程的优先级:
1、线程的优先级用一个整数表示1-10(从高到低);
2、线程的默认优先级为5;
java没有规定优先级低的线程就必定要让优先级高的线程先运行且直到线程结束,因此开发时不能利用优先级来控制线程的执行;
相关方法:setPriority和getPriority
属性:MIN_PRIORITY,MAX_PRIORITY,NORM_PRIORITY;
线程的串行化(join方法):
实际应用普遍,多用无参方法;
join();
A B--->B.join();
利用sleep方法实现数字时钟;
yield方法使用,线程让步给其余线程进行执行,使用该方法后线程并不进入阻塞状态而直接进入就绪状态;
t.yield();
主要用于在一个线程在释放已经用完的所占资源时调用,以便其余线程得到使用资源的机会;
实现线程终止,stop方法因存在不安全因素被废弃,必须寻求替代方法;
4、线程同步:
栈的操做实例
class Stack{
int index=0;//元素个数
char[] data=new char[6];
public void push(char c){
data[index]=c;
index++;
}
public char pop(){
index--;
return data[index];
}
}
同一时刻只容许一个线程访问的资源,称为临界资源;处理临界资源的代码称为临界区。
互斥锁:
在java中为了保证共享数据操做的完整性,引入了互斥锁的概念;
java中每个对象都有惟一一个互斥锁,一旦加上锁以后,保证了同一时刻只能有一个线程访问该对象及其所保护的临界区;
也能够理解为线程若是要访问一个对象及其所保护的临界区,首先应得到该对象的锁,得到对象锁后即得到了访问该对象及其所保护临界区的权力,在该线程没有释放对象锁以前即没有访问完该对象及其所保护临界区以前,其余线程就该对象没法访问该对象及其所保护临界区;
线程---》对象---》代码(临界)
使用关键字synchronied实现给对象加锁;
synchronized能够修饰方法也能够修饰代码块,用synchronized修饰的方法称为同步方法,用synchronized修饰的代码块称为同步代码块;
同步代码块是对this对象加锁;
5、线程死锁:
并发运行的多个线程彼此等待对方占有的资源,都没法运行的状态称为死锁;
A:x,y x
B:x,y y
String StringBuffer
String str="a"+"b"+"c";
"ab"-->"abc"
StringBuffer str="a"+"b"+"c";
"abc"
6、线程同步通讯:
为了在多线程并发运行时避免死锁,在线程阻塞时应该尽量的释放所占有的资源,使得其余线程得到运行的机会;
使用的方法wait(),notify();notifyAll();
wait():是线程自己中止执行等待,同时释放所占有资源;直到有其余线程调用notify或者notifyAll方法才有可能从新执行,不然永远不会执行;
notify:唤醒调用了wait方法而等待的线程中的某一个线程,至因而哪个不肯定;
notifyAll:唤醒调用了wait方法而等待的全部线程;
生产者消费者问题:
题意分析:做为生产者来生产产品而消费者来消费产品,当生产者生产出产品后将其放在一个仓库,而后通知消费者来拿产品并等待,等消费者拿走产品后生产者再往仓库放产品(消费者拿走产品后通知生产者继续放产品);消费者从仓库拿走产品后,通知生产者继续往仓库放产品并等待,等生产者放完产品后再来取产品(生产者放完产品后通知消费者来取产品)。
用多线程来解决这个问题:经过刚才上述对这个问题的分析,看该问题中有几个对象:生产者,消费者另外还有就是放置产品的仓库也是一个对象。仓库是用来存放产品的,以面向对象程序设计的思想,编写仓库这个类,将产品数据和操做产品的方法组织在一块儿,也就是说仓库类要提供放置产品和得到产品的方法。
生产者和消费者用线程来表示。
类和对象的叫法很差区分;
语境
注意:1、wait方法、notify方法放在同步块或者同步方法中,因为这是使用的是同步方法,因此咱们同步的对象是this;2、调用wait方法此时将线程放入this对象的等待队列中,notify方法唤醒的也是this对象的等待队列的线程;这里咱们必定要注意wait方法和notify方法必定要处于锁定同一对象的同步代码块中或者同步方法中,不然将会产一些问题。
ch11 I/O流
1、基本概念:
I/O:Input/Output,跨越了JVM边界,和外界进行数据交换;
数据源:数据的来源,一切能够提供数据的地方,例如:磁盘上的文件、键盘、网络链接等;
数据宿:数据目的地,一切能够接收数据的地方,例如:磁盘上的文件、显示器、打印机;
目前不少人将二者都称为数据源。
在java中把不一样的数据源和程序间的数据传输抽象的描述成“流”(Stream),计算机中处理的数据形式为“0”或者“1”这样的二进制位,称为数据流;
java.io包中定义了不少流类来实现数据I/O功能。
2、I/O流的分类:
1、按照数据的流向(或者操做类型)分:输入流InputStream和输出流OutputStream;
对于输入流只能从中读数据,不能向其写数据;对于输出流只能向其写数据,不能从中读数据;
区分输入流和输出流的最有效办法:
以当前程序做参照,若是是读数据就用输入流,写数据用输出流;
I/O流类java.io.RandomAccessFile类是个特例,该类便是输入流又是输出流;
2、按照流的功能分:节点流和功能流(或者过滤流、处理流);
节点流只能链接数据源;功能流是对已经存在的节点流进行链接和封装,经过封装来加强流的读写功能,功能流不能数据源直接链接;
3、按照操做的数据单位分:字节流和字符流;
字节流以字节为单位进行传输(读写),字符流以字符为单位进行传输(读写);
java I/O流命名惯例:以InputStream或者OutputStream结尾的流为字节流,以Reader或者Writer结尾的流为字符流;
3、流类的体系结构
4个顶层流类:
这四个均为抽象类,其中InputStream和OutputStram是字节流,Reader和Writer是字符流,InputStream和Reader是输入流,Writer和OutputStram是输出流,均为相应流的父类。
查阅以上流类的API文档熟悉相关方法:
4、经常使用I/O类:
1、FileInputStream和FileOutputStream:
FileInputStream以字节为单位读取本地文件的数据;FileOutputStream以字节为单位将数据写入到文件;
2、BufferedInputStream/BufferedOutputStream
二者是为字节输入流和输出流增长功能(缓冲);
3、DataInputStream/DataOutputStream
分别实现了DataInput/DataOutput接口;
DataInputStream:容许应用程序以与机器无关方式从底层输入流中读取基本 Java 数据类型和String类型数据;
DataOutputStream:容许应用程序以适当方式将基本 Java 数据类型或者字符串形式写入输出流中;
数据存储格式与JVM中内存中的数据存储格式相同
4、FileReader和FileWriter
FileReader以字符为单位读取本地文件的数据,FileWriter以字符为单位将数据写入文件;
5、BufferedReader/BufferedWriter
二者是为字符输入流和输出流增长功能;
6、InputStreamReader/OutputStreamWriter
InputStreamReader实现字节流向字符流的转换,OutputStreamWriter实现字符流转换为字节流;
流操做的基本步骤:
1)建立节点流实例,和数据源相连;
2)建立功能流实例对第一步建立的节点进行封装,以加强其功能,例如:缓冲功能,操做功能等;
3)操做流,从输入流中读数据,从输出流中写数据;
4)对于具备缓冲功能的流进行刷新操做;
5)关闭流,释放流对象自己占用的资源以及其中使用的其余资源。
PrintStream、PrintWriter
System.in System.out
7、RandomAccessFile类
RandomAccessFile类同时实现了DataInput和DataOutput接口,提供了对文件随机存取的功能,利用这个类能够在文件的任何位置读取或写入数据;
RandomAccessFile类提供了一个文件指针,用来标志要进行读写操做的下一数据的位置。
8、ObjectOutputStream/ObjectInputStream
对象的序列化
1、将对象转换为字节流保存起来,并在往后还原这个对象,该机制称为对象序列化和反序列化;
2、将一个对象保存到永久存储设备上称为持久化;
3、一个对象要想可以实现序列化,必须实现Serializable接口或Externalizable接口;
4、对象的序列化可利用ObjectOutputStream中的writeObject()方法;对象的反序列化可利用ObjectInputStream中的readObject()方法;
5、当一个对象被序列化时,只保存对象的没有transient修饰的非静态成员变量,不能保存任何的成员方法和静态的成员变量;
6、若是一个对象的成员变量是一个对象,那么这个对象的数据成员也会被保存。
7、当咱们利用对象的反序列化从新构建对象的时候,它并不会调用这个对象当中的任何构造器,它仅仅是根据咱们先前保存对象的状态信息在内存中从新还原这个对象;
8、若是一个可序列化的对象包含对某个不可序列化的对象的引用,那么整个序列化操做将会失败,而且会抛出一个NotSerializableException。咱们能够将这个引用标记为transient,那么对象仍然能够序列化。
9、PipedInputStream/PipedOutputStream
使用管道流进行线程间的数据传输;
10、Properties类的使用:
5、文件操做:
java.io.File类:
1)一个File类的对象,表示了磁盘上的文件或目录;通常状况下,File只表示文件,但在Java中它不只表示文件并且还表示目录;
2)File类提供了与平台无关的方法来对磁盘上的文件或目录进行操做。
查阅Java API文档,熟悉File类的相关方法。
//window下路径中分隔符为“\”,Unix下为"/";/ch04/a.txt
//File.separator在window下指的是“\”,Unix下为"/"
ch12 网络编程
基本概念:
1、计算机网络
计算机网络是相互链接的独立自主的计算机的集合,最简单的网络形式由两台计算机组成。
2、网络通讯
IP地址:
1)IP网络中每台主机都必须有一个唯一的IP地址;
2)IP地址是一个逻辑地址;
3)因特网上的IP地址具备全球惟一性;
4)32位,4个字节,经常使用点分十进制的格式表示,例如:192.168.0.16。
协议:
1)为进行网络中的数据交换(通讯)而创建的规则、标准或约定;(=语义+语法+规则) ;
2)不一样层具备各自不一样的协议。
端口号:
端口使用一个16位的数字来表示,它的范围是0--65535,1024如下的端口号保留给预约义的服务。例如:http使用80端口。
3、OSI(Open System Interconnection)参考模型
物理层:二进制传输,肯定如何在通讯信道上传递比特流;
数据链路层:增强物理层的传输功能,创建一条无差错的传输线路;
网络层:在网络中数据到达目的地有不少线路,网络层就是负责找出最佳的传输线路;
传输层:传输层为源端计算机到目的端计算机提供可靠的数据传输服务,隔离网络的上下层协议,使得上层网络应用的协议与下层无关;
会话层:在两个相互通讯的应用进程之间创建、组织和协调其相互之间的通讯;
表示层:处理被传送数据的表示问题,也就是信息的语法和语义,若有必要将使用一种通用的格式在多种格式中进行转换;
应用层:为用户的应用程序提供网络通讯服务;
OSI(Open System Interconnection)参考模型并非物理实体上存在这七层,这只是功能的划分,是一个抽象的参考模型。进行网络通讯时,每层提供本层对应的功能;
1)通讯实体的对等层之间不容许直接通讯,它们之间是虚拟通讯,实际通讯在最底层完成;
2)各层之间是严格单向依赖;
3)上层使用下层提供的服务 — Service user;
4)下层向上层提供服务 — Service provider。
5)对等层实体之间虚拟通讯;
6)下层向上层提供服务,实际通讯在最底层完成。
6、OSI各层所使用的协议
1)应用层:远程登陆协议Telnet、文件传输协议FTP(网上下载一个软件或者资料的时候就会使用该协议)、 超文本传输协议HTTP(使用较多,经过IE浏览一个网页的时候就使用该协议)、域名服务DNS(使用较多,经过网络访问一个计算机通常不使用该主机的IP地址,而是经过该主机的域名访问)、简单邮件传输协议SMTP(经过Formail发送邮件)、邮局协议POP3等(经过Formail收邮件);
2)传输层:传输控制协议TCP、用户数据报协议UDP;
TCP:面向链接的可靠的传输协议;在利用TCP协议进行通讯的时候,首先要通过三步握手创建起通讯双方的链接,一旦链接创建后就能够通讯了。TCP协议提供数据确认和重传的机制,保证数据必定可以到达数据接收端。像打电话。
UDP:是无链接的,不可靠的传输协议;采用UDP协议进行通讯时,不须要创建链接,能够直接向一个IP地址发送数据,至因而不是可以收到不能保证,发送过程当中数据有可能丢失、IP地址可能不存在、再者IP地址表明的主机没有运行等缘由均可能致使不能接收到数据。
3)网络层:网际协议IP、Internet互联网控制报文协议ICMP、Internet组管理协议IGMP。
基于TCP的Socket编程步骤:
1)服务器程序编写:
①调用ServerSocket(int port)建立一个服务器端套接字,并绑定到指定端口上;
②调用accept(),监听链接请求,若是客户端请求链接,则接受链接,返回通讯套接字;
③调用Socket类的getOutputStream()和getInputStream获取输出流和输入流,开始网络数据的发送和接收;
④最后关闭通讯套接字。
2)客户端程序编写:
①调用Socket()建立一个流套接字,并链接到服务器端;
②调用Socket类的getOutputStream()和getInputStream获取输出流和输入流,开始网络数据的发送和接收;
③最后关闭通讯套接字。
基于UDP的Socket编程步骤:
1)接收端程序编写:
①调用DatagramSocket(int port)建立一个数据报套接字,并绑定到指定端口上;
②调用DatagramPacket(byte[] buf, int length),创建一个字节数组以接收UDP包 ;
③调用DatagramSocket类的receive(),接收UDP包;
④最后关闭数据报套接字。
2)发送端程序编写:
①调用DatagramSocket()建立一个数据报套接字;
②调用DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port),创建要发送的UDP包;
③调用DatagramSocket类的send(),发送UDP包;
④最后关闭数据报套接字。
URL:
URL(Uniform Resource Locator统一资源定位器):表示Internet上资源的地址;
URL格式:<协议名><资源所在主机>[:端口号][资源名]
http://home.netscape.com/home/welcome.html
http://www.sun.com:80/
http://www.cs.tsinghua.edu.cn:8888/