What is java
-----------------------------------------------------------------------------------------------------
java 语法
MODULE 1
===============================================================================================================================================
Java语言的特性:
------------------------------------------------------------------------------------------------------
1.提供了一个解释性的环境 一次编写,到处运行
1)java ---编译中间语言,byte code字节码 ==.class文件
类似于汇编语言,不受操作系统和cpu影响
2)byte code ---机器指令,与特定的操作系统相关
2.对比c/c++的优势:
1)消除了指针,改用引用来代替指针,保留了指针中好的特性
2)代码中消除了内存管理,
c/c++:中开发人员需要自己申请和释放内存
java:自动内存管理机制 所有的对象都是用new操作符建立在内存堆区
JVM --- 解释性的环境
------------------------------------------------------------------------------------------------------
源程序从开发到最终运行经历的两个步骤:
1.编译---做简单的语法检查
命令:javac ***.java
功能:.java --> .class(字节码)
.class文件可以跨平台
2.运行
命令:java ***
1)class loader --- 类加载器
将字节码文件加载到内存中
2)byte code cerifier --- 字节码校验器
验证字节码是否合法
3) 执行:
解释器 --- 将字节码逐行翻译成机器指令
每次都要逐行翻译并运行,效率低
JIT(Just intime technology) -- 即时翻译技术
找出20%的热点代码,一次编译成机器指令
GC(Gabage Collection) --- 垃圾回收机制,提供了自动的内存管理
目的:开发人员无需关注内存释放
1)GC始终运行在后台的 优先级最低的 系统级线程
大部分时间不工作,只有系统闲置或内存不够时工作
2)开发人员可以在代码中,建议JVM进行回收,但是是否执行由JVM决定(suggest,not force)
System.gc(); 或 Runtime.gc();
-----------------------------------------------------------
path:执行命令的目录
classpath:程序员写的类库
-----------------------------------------------------------
类加载器
------------------------------------------------------------------------------------------------------
1.启动类加载器
bootstrap class loader
加载jdk核心类库$JDK\jre\lib\rt.jar
2.扩展类加载器(第三方)
extensible class loader
加载扩展API:$JDK/jre/lib/ext/*.jar
3.系统类加载器
system class loader
加载自定义的类:$CLASSPATH
双亲委托机制
1)可以避免同名的类重复加载,当上一级已经加载到该类时,不会再向下加载
2)考虑到安全性,否则自定义的类可动态替代java核心API
打jar包命令:
jar -cvf hello.jar
解压包命令:
jar -xvf hello.jar
字节码校验器
-----------------------------------------------------------------------------------------------------
检验代码中非法的或破坏性的操作
1)验证版本是否兼容
2)验证代码不会破坏系统的一致性
确保所有操作指令不会对操作系统进行非法的操作
3)不会在内存中发生栈下溢和栈上溢
4)方法调用时的参数类型合法,不能超过其合理的数据范围
5)数据类型转换是否正确
第一个java程序:Hello.java
--------------------------------------------------------------------------------------------------------
编译:当前目录ch01
javac -d bin src\Hello.java
-d:指定编译后的字节码文件的存放路径
运行:java -cp bin com.briup.ch01.Hello
-cp:指定字节码文件的搜索路径
构建java源程序的三要素:
package import class 顺序不能错
1.package 包(可省略)
语法:package com.briup.ch01; //用分隔
命名:小写
package不是目录,但编译后以目录形式存在运行时需要完整的类名:包名.类名
2.import 导入(可省略)
两种情况无需import
1)java.lang包中的类
2)同一个package中的类
3.class定义类
语法: class 类名 {...}
命名:类名首字母大写
知识点:
1)一个java源文件中可以定义多个class,但是只能有一个public类
2)源文件名称一定要和public类的类名一致
3)运行的程序必须要有main方法,该方法是程序的唯一的执行入口,只能有一个main方法。
main方法的定义:public static void main(String[] agrs){....}
jdk中常用的包
------------------------------------------------------------------------------------------------------------
1.java.lang -- 最常用的类,不需要import
2.java.awt/javax.swing/java.awt.event
--开发图形用户界面
3.java.io -- 输入/输出流
4.java.net -- 网络
5.java.util -- 常用的工具类
Module 2 标识符 关键字 数据类型
===============================================================================================================================================
1.Comments注释
-------------------------------------------------------------------------------
---增强程序的可读性
三种注释:
1)单行注释://紧挨着要注释的代码
2)多行注释:/*
...
*/
3)javadoc注释:可以生成javadoc文档,
/**
...
*/
可以写html标签,生成的是html格式的网页
@author 作者
@version 版本
@since 从哪一个版本的jdk开始应用
@param 参数
@return 返回类型
@throws ---@exception 异常
命令:javadoc -d doc src\*.java
2.标识符--表意性强
---------------------------------------------------------------------------------------------------
在程序中给类,方法或变量命名
1)以 字母,“_”,“$”开始
2)后跟字母,"_",“$”,或数字
3)大小写敏感
4)没有长度限制
类名---首字母大写,后续单词首字母大写
方法名/变量名---首字母小写,后续单词首字母大写
常量---都是大写
5)回避java中的关键字
java中的关键字:
1)goto/const---非关键字,属于保留字,需要回避
2)true false null --- 具有特殊含义,回避
注:java程序中的数据一定存在类型
3.java中的数据类型
--------------------------------------------------------------------------------------------------
1.基本数据类型--四类八种
整形:byte short int long
浮点型:float double
布尔型:boolean
字符型:char
boolean: true/false 不能用0或非0
char:无符号的16位整型数
1)单引号表示:char c='A';
2)用整型表示: char c = 96;
3)unicoded表示:char c ='\u0060';
整型:三种表示法
1)十进制:默认是十进制int型 123
2)八进制:前面加0 0123
3)十六进制:前面加0x 0x123
浮点型:3.1415926
默认为double类型
数据类型的转换规则:
1.隐式转换 窄 -->宽
byte,short,char -->int-->long-->float-->double
2显示转换 宽-->窄
强制转换:(目标类型)变量
存在精度丢失问题,由开发人员自己负责
java中内存分区:
1)堆区
new操作符创建的对象都存在堆区
特点:所有程序公用,空间不连续,容量大,速度慢
存放对象和成员变量等
2)栈区
特点:存储空间连续,容量小,速度快
存放局部变量,引用型变量(声明的对象)和基本数据类型变量等
3)代码区
存放代码块,方法体等
4)静态/常量区
存放静态变量,常量等
2.引用类型(类类型)
Teacher zhao; //声明 栈区
zhao = new Teacher(...);//堆区创建一个Teacher对象
引用型变量:Person p;在栈区开辟空间
注:引用型变量指向一个具体的对象
自动封装包装
----------------------------------------------------
jdk<=1.4中:
Integer i1 = 123 //illegal
Integer i2 = new Integer(123);
jdk>=5.0中:
Integer i3 = 128;
Integer i4 = 128;
System.out.println("i3==i4:"+(i3==i4)); //i3==i4:false
Integer i7 =127;
Integer i8 =127;
System.out.println("i7==i8:"+(i7==i8)); //i7==i8:true
int i5 = 128;
int i6 = 128;
System.out.println("i5==i6:"+(i5==i6)); //i5==i6:true
Ingeger类型的数据,当值小于128时,不会维护缓存 ;即Ingeger类型的数据<=127时,共用同一个常量区。另:
/*
* Float Double :不维护缓存
* Byte Boolean :全部维护缓存
* Character Integer Short Long:维护一个字节的缓存 -128~127
*/
------------------------------------------------------
类-class
---------------------------------------------------------------------------------
生活中:
同种类型的一个群体,具有 共同特征 和 共同的行为
程序中:
群体--(抽象)-->class
共同特征--(抽象)-->成员变量(属性)
共同行为--(抽象)-->方法
定义:public class Person{
//Person具有的共同属性,成员变量
String name;
int age;
boolean gender;
//Person具有的共同的行为
public void ear(){....}
public void shout(){...}
}
对象 -- object
-----------------------------------------------------------------------------------
生活中:
群体中一个独立的个体,具有特定的属性取值和行为
程序中:
new + 类名(param1,param2,...);
类的一个实例化对象
class PersonTest{//测试程序
public static void main(String[] args){
Person person ;//变量声明
person = new Person();//创建Person
person.name = "fenghb";
person.age=22;
person.eat();
}
}
构造器:
---------------------------------------------------------------------------------------
构造器是对成员变量进行初始化,不属于类的行为
构造器允许定义多个,参数类型或个数不同
类中没有显示定义构造器时,java会默认分配一个无参的构造器
类中由于显示定义了构造器,java不会在分配无参的构造器
类中的语法成分:
---------------------------------------------------------------------------------------
1)成员变量
2)构造器
3)普通方法
作业:构建一个矩形类Rectangle.java
成员变量:长 宽
行为:求周长 求面积
写测试程序
命令:(RectangleTest中调用了Rectangle类,-cp bin 需要制定Rectangle类的字节码的搜索路径)
javac -d bin -cp bin src\RectabgleTest.java
Module 3
================================================================================================================================================
1)成员变量(实例变量)和局部变量
2)操作符
3)流程控制语句
1.局部变量
1)定义在方法内部
2)没有默认的初始化值,使用前必须赋值
3)只作用方法内部
2.成员变量
1)定义在类的内部,方法的外部
2)具有默认的初始化值:
a)基本数据类型
整型:0
浮点型:0.0
char型:'\u0000'
boolean型:false
b)引用类型
默认null
Operators操作符
---------------------------------------------------------------------------------------------------
1.算数运算符
+ - * /
两边的类型要一致,否则小类型自动转换为大类型,结果类型也为大类型
5/3 = 1
2.赋值操作符
=
复合赋值操作符:
int i=5; i+=3 ==>i=i+3;
i++;==>先使用i,然后再自增
++i;==>先自增,在用新的i进行运算
3.比较操作符
结果是boolean类型
4.移位操作符
针对的是二进制串进行移位操作
>> --- 右移,高位按符号位
<< --- 左移
>>> --- 无符号的右移,高位填0
i=3; 0000...0011(32位)
i>>2;0000...0000 ==> 0
i<<2;0000...1100 ==> 12
i=-3; 1111...1101
i>>2; 1111...1111 ==>-1
i>>>2;0011...1111
5.位操作符
针对二进制数进行操作
int i =3,j=5;
i: 0000...0011
j: 0000...0101
1)位与&: 0000...0001 ==> 1
2)位或|: 0000...0111 ==> 7
3)异或^: 0000...0110 ==> 6
相同为0 不同位1
4)取反~: 针对一个二进制数操作,每位取反
6.逻辑操作符
参与运算的都是boolean型数据,结果也是boolean
逻辑与&&:
A&&B : A和B都为true时,结果为true,否则false
短路规则:当A为false时,B不参与运算
逻辑或||:
A||B:A或B中有一个味true,结果true
短路规则:当A为true时,B不参与运算
7.条件运算符:
A?B:C
A---boolean型结果
当A为true时,整个表达式结果为B,否则为C
num1>num2?num1:num2;
注:冒号两边类型要一致,否则小类型自动转换为大类型
int a=2,b=5;double c =3.14;(a>b)?(int)c:b==>5.0
流程控制语句
----------------------------------------------------------------------------------------
1.if/else
2.switch/case
1)temp取值:byte short char int (jdk1.5枚举类型)
2)case 是程序的分支入口,一旦进入会顺序执行下去
3)case的出口:break;
4)default可任意放置,习惯放最后
3.循环控制语句:
代码反复执行多次
1)for循环
for(A;B;C){code block;}
执行A(只执行一次)
-->B(条件判断)--->false,跳出for循环
--->true --- >code block ---> C-->B
2)while循环
先判定boolean表达式结果,结果为true进入循环体
3)do/while循环
循环代码体至少执行一次,在判断表达式
附加作业:
实现功能:计算出下一天的年月日addDay();
Module4 数组Array
================================================================================================================================================
数组Array
------------------------------------------------------------------------------------------------
也是一种数据结构,用来存储【指定长度】的【相同类型数据】的【集合】
1)数组声明时必须指定数组中元素;
2)指定长度且不能再更改
3)属于引用类型,使用前必须用new创建,length可看做数组对象的属性
声明
基本数据类型
int[] array;或 int array[]
引用类型
Student[] arrays;或 Student arrays[];
创建
用new操作符创建数组
基本数据类型:
int[] array = new int[7];
引用类型:
Student[] arrays = new Student[7];
注:创建数组只是指定元素的最大个数,开辟空间,但是数组中的元素需要单独创建
初始化
默认初始化
数值型 :0
boolean: false
引用型:null
动态初始化
1)声明,创建,初始化独立分开
int[] array;//声明
array = new int[2];//创建
array[0] = 0;//初始化
array[1] = 1;
2)同时声明,创建,初始化
int[] array = {1,2,3,4};
错误:int[] array; array={2,3};
int[] array = new int[]{1,2,3,4};
不可以再[]里面指定数
错误:int[] array = new int[4]{1,2,3,4};
引用类型:
Student[] ss = new Student[]{
new Student("fenghb"),
new Student("lisi")
};
Student[] students ={new Student("fenghb"),new Student("lisi")};
数组元素的访问
数组名[元素下标]
元素下标:0~length-1;
数组的遍历
for(int i =0;i<array.length;i++){
array[i];
}
多维数组
---------------------------------------------------------------------------------------------------------
1)java中的数组都是一维数组,多维数组就是存放数组的数组
2)最多可以定义255维度
一维数组反应的是线性关系,在内存中也是一段地址连续的线性内存空间
二维数组
---------------------------------------------------------------------------------------------------------
1.对称数组(矩阵)
int[][] array = new int[2][3]
注意:第一个维度代表数组array的长度。一定要在创建该数组时指定
2.非对称数组(锯齿形)
每个元素都是一个一维数组,需要单独创建
int[][] array = new int[3][];
array相当于一个一维数组
array[0] = new int[2];
array[1] = new int[5];
array[2] = new int[3];
array.length = 3;//二维数组的长度由第一维度决定
3.二维数组的遍历
int[][] array = new int[3][5];
for(int i=0;i<array.length;i++){
for(int j=0;j<array[i].length;j++){
array[i][j] = i*j;
}
}
数组拷贝
-------------------------------------------------------------------------------------------------
System.arraycopy(from,fromIndex,to,toIndex,count)
from --- 源数组
fromIndex -- 源数组的索引位置
to -- 目标数组
toIndex -- 目标数组的索引位置
count -- 要拷贝的元素个数
注:只是浅层拷贝,当元素为引用类型时,复制出来的对象不能
独立于原对象,当原来的对象属性值改变时,目标数组中的元素也相应的改变
类中的set方法作用是供用户更新数据l
重写toString()方法打印所需要的内容字符
对象可以自动调用toString方法
不重写会输出对象在堆区的内存地址
Module 5 OOP--Object Oritention Programming
==================================================================================================================================================
面向对象编程的三大特性:
class类:具有相同属性和行为的一组对象的集合
人:---(抽象)-->class Student{}
静态属性:-->成员变量
姓名 性别 年龄
动态行为:-->方法
学习 吃饭 考试
Object对象:
Student s = new Student("feng",20);
s.study(); zx.exam();
s = new Student("feng",20);
Encapsulation--封装
--------------------------------------------------------------------------------------------------------------------------------------
目的:实现信息隐藏
1)静态属性的信息隐藏
2)方法的实现细节的隐藏
Inheritance--继承
-----------------------------------------------------------------------------------------------------------------------------------------
1)对象间具有一定的相似性
a)子类具有父类的属性和行为
b)子类可以具有自己特有的属性和行为
class Point{
int x;
int y;
}
class Circle{
int x;
int y;
int ridius;
}
Circle 继承 Point
2)父子类之间一定要满足“is a ”的语义关系
子类 is a 父类
Circle is a Point? //错误的继承关系
注:父类 代表一个大群体,子类 是大群体中的一个小群体
语法:
class Teacher extends Person{}
1.一定要满足“is a”的语义关系
2.单继承,子类只能有一个父亲
3.子类继承父类的那些语法成分?
1)成员变量
2)普通方法
子类继承父类的(除私有)方法
直接调用
3)构造器?
构造器不能被继承,但是子类一定会调用父类的构造器
a)隐式调用
子类构造器中没有显示调用父类的构造器时,JVM会默认调用父类的无参构造器
相当于子类构造器中执行了super();
b)显示调用
super(param1,param2);
一定要放在构造器中的第一个语句
注:父类的构造函数中用到的方法和子类的中的方法一样时,只调用子类的方法
super的用法
--------------------------------------------
1.在子类中要调用父类的同名方法,用super.method();
2.在子类构造器中调用父类的构造器super(...);
Polymorphism--多态
------------------------------------------------------------------------------------------------------------------------------------
对于不同的对象,相同的行为产生不同的结果
例:
BasketBall FootBall 继承 Ball
play() play() play()
用手玩 用脚踢
1)对象只有一种类型 new Teacher()
2)变量可以有多种形态
Person p;
p = new Teacher();
p = new Student();
p.display()
多态存在的三个必要条件:
---------------------------------------
1)要有父子类的【继承】关系
2)要有子类重写父类的同名方法;Overriding
3)父类的引用指向子类的对象(上转型)
练习:
创建 Cat Bird 继承Animal
eat() eat() eat()
catch() fly()
创建测试程序AnimalTest
Overriding重写(覆盖)
---------------------------------------
1)在父子类之间,区别于Overloading
2)定义了同名的方法,参数列表,返回类型都相同
3)可见范围不能被子类缩小 (包括static修饰符)
4)异常不能被放大(不能一个有异常一个没有异常)
重写是运行时多态
方法的重载Overloading
-------------------------------------------------------------
1)在一个类的内部
2)定义多个同名的方法
3)参数的类型或个数不同
4)返回类型不做要求
外部用户无需关注编译器调用的是哪个方法,有JVM自己判断使用的方法
重载是编译时多态
instanceof操作符
----------------------------------------
1)boolean型
用法:引用型变量 instanceof 类名
判断前面的引用变量的动态类型是否是后面的类自身或者是其子类,是返回true,否则返回false
Person p = new Teacher()
p instanceof Person? true
p instanceof Teacher? true
p instanceof Student? false
---------------------------------------
1.操作名称的多态
重载是多态的一种
在一个类的内部有多个操作具有相同的名,参数的类型和个数不同的方法
2.和继承有关的多态
子类重写父类的方法
方法的参数类型和返回类型都一致
同一个方法被不同对象调用时产生的结果不同
方法的定义和调用
-----------------------------------------------------------------------------------------------------------------------
方法定义:
1)修饰符:允许存在多个,无顺序要求
public static ==== static public
2)返回类型
方法一定存在返回类型,没有返回值用void
存在返回类型的方法,要求方法中的任一分支都有返回值 (return)
int method(){
if(){
return 0;
}else{
return 1;
}
}
3)参数列表:更具需求,可有可无
用于接收外部传入的数据
一定要指定参数的数据类型
参数的作用域范围仅限方法内部
int add(int a,int b){}
方法的调用:
1)同一个类中调用
2)在外部类中调用
class A{
int methodA(){}
}
classbB{
int methodB(){
//创建A的实例化对象
A a = new A();
a.methodA();
}
}
注意:方法定义时,参数没有明确的取值
方法调用时,给参数传值
形参:方法定义时的参数
实参:方法调用时给形参传值
***
1)基本数据类型
传值:实参的值拷贝一份传递给形参
2)引用类型
传递的是引用的地址
***
this关键字
------------------------------------------------------------
1) 当成员变量名和局部变量名相同时,用this区分
this指向的是当前类或对象
this.name ---> 成员变量name
name --> 局部变量
2)在一个构造器中要调用另一个构造器时,用this(...)
构造器中的this()语句必须放在第一行
创建对象
-------------------------------------------------------------
new Person("feng",22)
1)在内存堆区开辟空间
2)为成员变量进行默认初始化0,false,null
3)显示初始化
缺乏灵活性,类的所有对象都具有相同的属性值
class Person{
private String name = "unknown";
private int age =18;
}
4)构造器
可以为不同的对象赋予不同的初始化值
设计目的:只对属性进行简单的初始化,不涉及复杂的业务代码
1)一个类中一定存在构造器,没有显示定义时,JVM会自动分配默认的无参构造器
2)显示定义了构造器的类,JVM不在分配无参构造器
3)允许定义多个,构造器重载,提供多种初始化方案
如何简化构造器中的代码?? this();
Module 6 高级语言特性
====================================================================================================================================
1.static/final修饰符
2.==和equals()比较
3.访问权限控制
4.抽象类和接口(*)
5.内部内
6.集合(*)
7.反射(*)
static修饰符 -- 特点:类的所有对象共享
-----------------------------------------------------------------------
1.修饰成员变量(非局部变量)
class A{
int a;
static int b;
}
类的普通成员变量是和对象关联
A a = new A(); a.a
A b = new A(); a和b都共享静态变量b
静态变量可以直接用类名直接调用
静态变量赋值:
1)在类中可以直接赋值也可以再static语句块中赋值
2)在类的构造器中用参数赋值
2.修饰方法---静态方法
1)只能访问静态的语法成分(静态变量/静态方法)
2)访问非静态的语法成分,一定先创建该类的对象
静态的方法可以用类名直接调用
3)不能被子类重写为非静态的方法
对于工具类和工具方法,通常定义为static
3.修饰代码块 -- 静态初始化代码块
1)静态代码块只能被执行一次,在 类加载 时一次性执行
2)允许定义多个静态代码块,编译器会合并执行
3)优先于main()和构造器
用法:
通常用于对静态变量进行一次性的初始化
final修饰符
---------------------------------------------------------------------------------------
特点:不可更改性
1.修饰变量 -- 常量
一经赋值,不能更改
2.修饰方法
该方法在子类中只能被继承,不能被重写
3.修饰类
不能被继承 String
常见用法:
static final --- 静态常量
例题:
Employee中添加基本工资 -- static
1)永远不会更改基本工资 static final
2)允许调整 static
==和equals()比较
-------------------------------------------------------
1.“==”比较
1)基本数据类型 比值
2)引用类型
Person p = new Person("zhangsan",25);
Person p1 = new Person("zhangsan" 25);
p==p1? false
==比较地址,比的是对象在内存中存放的地址
p = p1;
p==p1; true
2.boolean equals()----适用于引用类型
Object 祖先类
java中的所有类默认继承Object类
equals(Object o)
----比较两个对象的类型和内容是否相同
比较类类型的时候必须重写equals()方法
1)java提供的类的比较
jdk对这些类已经重写了equals(),可以直接比较
2)自己开发的类的比较
需要重写equals()方法
1)先比两个对像的动态类型 instanceof
2)比两个对象的各个属性取值是否相同
总结:只有类型和属性值都相同,才认为两个对象相同
注
String m = "abc"
String n = "abc"
String在内存中搜索的是同一地址
new String("abc") 是在堆区开辟新的存储空间
m==n? true
Access Control 访问权限
------------------------------------------------------------------------------------
class Student{
private Sting name;
int id;
protect int age;
public String sex;
}
private:
另外一个类中创建Student对象时不能访问private变量和方法
friend:
任何与Student同一包中的类创建的对象,都可以访问friend变量和方法
如果不是在同一包中类创建的对象就 不能访问 friend变量和方法
protected:
任何与Student同一包中的类创建的对象,都可以访问protected变量和方法
如果不是在同一包中类创建的对象就 不能访问 protected变量和方法
public:
任何 一个类中创建Student对象时都能访问public的变量和方法
继承的访问
1.子类和父类在同一包中的继承
子类继承了父类不是private的所有变量和方法(除构造方法)
2.子类和父类不在同一包中的继承
子类只继承了父类的protected和public的变量和方法(除构造方法)
不继承friend和private变量和方法
抽象类和抽象方法
--------------------------------------------------------------------------------------
关键字:abstract
1.抽象类
语法:public abstract class A{}
思想:
现实对象 -- (抽象) --->具体类 Cat Dog
具体类 --- (抽象)--->抽象类 Animal
特点:
1)不能实例化对象(不能用new操作符)
Animal a = new Animal();//非法
Animal a ;//变量声明 合法
a = new Cat();// 合法
设计目的:用抽象父类的引用型变量操作具体的子类对象
2)满足“is a”的关系
Cat is a Animal
3)单继承
问:抽象类中能否存在构造器?
答:存在,给子类调用
抽象类可以实现(implements)接口,抽象类是否可继承实体类,但前提是实体类必须有明确的构造函数。
2.抽象方法
语法:abstract void play();不能用private修饰
特点:
1)只有方法的声明,不提供实现
设计目的:
定义了一种规范,规定了所有 子类 具有的共同行为
2)子类必须对这些抽象方法提供实现
知识点:
1)有抽象方法的类必须是抽象类;
2)抽象类中可以包含0~多个抽象方法;
3)具体类 继承 抽象类?
4)abstract 和 final 同时修饰类?不能
abstract --> 用来继承
final --> 不能被继承
abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?
答案:都不能
接口 interface
---------------------------------------------------------------------------------------------------
定义接口:interface A{}
特点:
1)间接满足多继承
2)不能实例化 new A();//非法
语法成分:
1)成员变量
都是static final静态常量
2)方法
都是抽象的
interface A{
int i = 10; //static final int i = 10;
public void method(){} //非法
public void method(); //abstract
}
设计目的:
定义了一种规范,定义了该接口的所有 实现类 所具有的共同行为,接口是对行为的抽象
例:
Cat Dog Bird Plane
eat() eat() eat() fly()
fly()
设计:Animal 抽象类 eat()
abstract class Animal{
public abstract void eat();
}
public class Cat extends Animal{
public void eat(){}
}
public interface IFlyable{
public void fly();
}
public class Bird extends Animal implements IFlyable{
public void eat(){}
public void fly(){}
}
知识点:
1)类可以实现多个接口
class A implements B,C{}
2)接口之间的关系
接口可以继承多个接口
A extends B,C{}
A,B,C:接口
问:1)接口可以继承类? 不可以 抽象到具体 合法 具体不能到抽象
2)接口中是否存在构造器? 不存在
特殊的接口:
1)常量接口(全是常量) 不推荐使用
2)标识接口(接口里没有任何方法和常量) 序列化接口
3)构造器
没有构造器
练习:
Door PanpanDoor
open()
close()
面试题
抽象类和接口的区别
---------------------------------------------------------------------------------
1.共同点
1)不能创建实例化对象
2)包含未实现的方法的声明(抽象方法)
3)子类或实现类必须提供这些方法的实现
2.不同点
语法:
抽象类 接口
关键字 abstract interface
变量 成员变量/static/final 只有static final
方法 抽象方法/普通方法 只有抽象方法
构造器 存在,可自定义 不存在
编程思想:
抽象类 接口
is a
具体类--(抽象)-->抽象类 行为 ---(抽象)--->接口
练习:
实现List链表,根据索引号存取数据,元素有顺序
操作:增删改查
实现:用数组的形式实现
考虑:
内部类 Inner Class
-------------------------------------------------------------------------------------------------
把一个类定义在另一个类的内部
class A{
int i;
class B{
int j=10;
void method(){...}
}
}
B就是A的内部类
设计目的:精确控制类的使用范围
作用:
1)减少命名冲突,可以再不同的类中定义同名的类
class A{class C} class B{class C}
2)缩小类的使用范围,使其比包还小,可以在一个类的内部或者方法内部甚至表达式内部使用
3)内部类可以共享外部类的语法成分
例:
class 发动机{
void produce(){
//生产发动机
}
}
class 汽车装配厂{
void 装配(){
new 发动机();
new 轮胎();
}
}
1)改造一:汽车发动机只能在汽车装配厂中运用
class 汽车装配厂{
class 汽车发动机{ //成员内部类
void produce(){
//生产发动机
}
}
void 装配(){
new 发动机();
new 轮胎();
}
}
2)改造二:进一步缩小使范围,汽车发动机只能装配方法中使用到
class 汽车装配厂{
void 装配(){
class 发动机{ // 局部内部类
void produce(){
//生产发动机
}
}
new 发动机();
new 轮胎();
}
}
3) 改造三:如何避免对此创建内部类对象?匿名内部类
无名可调
四种内部类
--------------------------------------------------------------------------------
1.静态内部类
定义在类的内部,参考静态成员变量
1)不依赖于外部类对象,可以独立构建
2)只能访问外部类的静态语法成分
class Outer{
int i = 10'
static int j = 20;
static void method(){
Inner inn = new Inner();
}
static class Inner{ //静态内部类
void method(){
i++;//非法
j++;//合法
Outer.method();// 访问外部类的同名方法
}
}
}
应用:
1)在外部类 内部 如何创建内部类对象
Inner inn = new Inner();
2)在外部类 外部 如何创建内部类对象
Outer.Inner inn = new Outer.Inner();
Outer o = new Outer();//只创建了外部类对象
练习:
一个数组中存放了一系列整数,要求一次性从该数组中同时获取最大值和最小值
分析:
getMaxMin()一个方法同时返回两个值?
2.成员内部类
参考成员变量或普通方法
定义在类的内部,没有static
1)成员内部类对象必须紧密依赖于外部类对象
2)可以访问外部类的所有语法成分,包括私有
class Outer{
private int i;
class Inner{
void method(){
i++;
Outer.method();//非法 如果method()在外部类中是static可以用Outer.method()调用外部类的方法method()方法
Outer.this.method();//访问外部类同名方法
}
}
public void method(){}
public void method1(){
Inner inn = new Inner();
inn.method();//
}
}
应用:
1)在外部类内部
Inner inn = new Inner();
2)在外部类外部
1)声明
Outer.Inner inn;
2)创建
inn = new Outer.Inner();//非法
inn = (new Outer()).new Inner();//合法
3.局部内部类
参考局部变量
定义在方法内部
1)能访问外部类的所有语法成分
2)只能访问局部常量,final修饰
3)不能加public/protected/private修饰符;无意义
4)局部内部类作用域范围仅限方法内部
class Outer{
int i = 10;
void method(){
int j = 20;
final int a = 2;
class Inner{
i++;//非法
void method1(){
i++;
a;
j++;//非法
}
}
Inner inn = new Inner();//合法
}
}
问:如何避免多次创建局部内部类对象?
4.匿名内部类
定义在方法内部
1)只允许在方法内一次性运用,类的定义和运用同步
2)通常会继承一个父类或实现一个接口
3)无类名,无构造器,无class/extends/implements
借用的是父类或接口名称
new 接口(){...};
注:匿名内部内运用最广泛,GUI事件监听中
class 汽车装配厂{
void 装配(){
//new 汽车发动机();
new 发动机();//非法,接口不能实例化
new 发动机(){
void produce(){
//生产汽车发动机
}
};
new 轮胎();
...
}
}
Collection集合框架
--------------------------------------------------------------------------------------
对数据结构的实现,半成品对象,在此基础之上进行二次开发
要求:
1) 理解常用数据结构的特点
2)会查询API,包java.util
3)能够对数据结构进行增删改查操作
注: 存储的都是对象
接口
1.Collection接口 --- 存储没有依赖关系的一组对象
List接口--- 数据按照顺序存放,以索引号方式存取,
允许对象重复,允许为null
Set接口 --- 对象无顺序,不允许重复
SortedSet---允许排序的Set
2.Map接口---以键值对的形式管理一组成对的对象
key~value key唯一不重复
选择Map,需要找出唯一不重复的标识
SortedMap---具有排序功能的Map,根据key排序
实现类:
List实现类
ArrayList --- 采用数组实现,增删低效,查询高效
LinkedList --- 双向链表,增删高效,查询低效
Vector --- 线程安全的ArrayList
Set实现类
HashSet --- 无序不重复
SortedSet实现类
TreeSet -- 具有排序功能
练习:
1.List的应用
自定义一个类Account,
属性: int code;
String name;
double balance;
方法:toString()输出账户信息
2.Set的应用
Set set = new HashSet();
Account中重写equals()方法
Set中不能重复过滤的Account
Set存储数据的方式:
数据按照hashtable的散列算法进行存放
Set中比较两个对象是否相同,需要重写两个方法:
1)hashcode()
2)equals()
3.SortedSet的应用
具体排序功能的Set
思考:对象如何排序?
对象存在多个属性,根据哪个属性进行排序,需要开发人员制定
SoctedSet set = new TreeSet();
练习:
1)创建比较器CodeComparator,实现Comparator接口,提供对账户的账号进行正序排列
2)创建比较器BalanceComparator。提供对账户余额
Map实现类
------------------------------------------
1)HashTable
线程安全的,类似Vector和ArrayList
2)HashMap
线程不安全
HashMap和Hashtable区别
主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。
SortedMap实现类
TreeMap -- 具有排序功能的Map
key ---Object,也是对象,唯一不重复
value -- Object,允许重复
put(key,value)
Set entrySet()
--拿到所有key~value的对应关系,返回Set,其中的每个元素都是Map.Entry类型的对象,代表一个键值对,可以通过Map.Entry获取key和value值
Set keySet()
--获取Map中所有key的值,key值不重复,返回Set
Collection values()
--获取Map中所有的value值,允许重复,无序
Re
collection values()flection 反射机制
--------------------------------------------------------------------------------------------
核心机制:
允许程序在 【运行时】 获取以知名字的class类的相关信息,动态构建该类的对象,获取类中的所有语法成分(成员变量,构造器,方法),可
以动态修改属性取值,或调用其方法
类中语法成分:
--------------------------------
package/import
class 类名{ --->class的镜像
属性:修饰符 类型 标识符 --->属性镜像
方法:修饰符 返回类型 标识符 参数列表-->方法镜像
构造器:修饰符 参数列表 -->构造器的镜像
}
反射常用的类:
--------------------------------
java.lang.class --- 类的镜像
java.lang.reflect.Field --- 属性的镜像
java.lang.reflect.Method --- 方法的镜像
java.lang.reflect.Constructor --- 构造器的镜像
看透class的能力 --- introspection
A a = new A();
method(String classname){
//1.拿到类的镜像
Class c = Class.forName("java.lang.String");
//2.
}
获取类的镜像的方法:
1)知道类名,根据类名得到镜像
方法:类名.class
例:Class c = String.class;
Class i = int.class;
2)知道引用型变量
方法:变量名.getClass();
例:String str = "abc";
Class c = str.getClass();
3)知道字符串给定的类名
方法:Class.forName(String classname);
例:Class c = Class.forName("java.lang.String");
getMethods()
getFields()
返回的是公共的属性和方法,包括继承的
getDeclareMethods()
getDeclareFields()
返回的是所有的属性和方法(public/protected/default/private),不包括继承的
反射的用处
1)通过类的镜像获取类的信息
2)程序运行时动态创建类的对象
3)破坏封装,可以获得类的私有属性和方法
newInstance()----调用的是共有的无参的
Module7 Exception异常
============================================================================================================================================
程序执行过程中可能出现的意外情况,不能期望外部用户应用始终正确,应该在程序中进行相关处理,确保在错误发生时,程序采取理智行为,不会意外终止
1)数组访问越界异常;
2)除以0;
异常都是类
异常发生,改变程序原有的正常流程
--> 抛出某个特定类型的异常
-->捕获异常,采取相应的处理
getMessage()---返回异常的简单描述信息
printStackTrace()---打印出异常完整的传播路径
异常的传播:
异常在它发生的位置开始会一级级向上传播,在整个传播路径的任意有一个位置都可以捕获处理,一旦被处理,它的上层调用者不在受影响
异常的体系结构
------------------------------------
1.Error
---不是程序本身的错误,由外部因素引发,程序无法恢复,直接终止
2.Exception
RuntimeException---unchecked exception
是程序无法自我恢复的异常,用try/catch无意义,只能在编码时避免这样的应用
如:
Student s = null;
s.display();//空指针异常
非RuntimeException ---checked exception
一定要进行try/catch处理的异常
如:
ATM取款,超出余额,不能系统崩溃
如何在原有异常基础上添加自己的异常描述信息
1)捕获了别人的异常,将它包装起来,添加自己的描述信息,扩展异常
2)unchecked exception -->checked exception,给异常添加更多的信息
getCause() --- 获取引发本异常的异常对象,即被包装的异常
java 高级应用
Module 8 GUI图形用户界面
=============================================================================================================================
常用的包:
1)java.awt.*;
2) java.swing.*;
3) java.awt.event.*;
要求:
1.开发GUI的步骤
2.常用的布局管理器的特点
开发GUI图形界面的步骤
-----------------------------------------------------------
1.选择容器
1)常见容器
JFrame容器 --- 有缩小,最大,关闭按钮,通常作为顶层容器
JDialog对话框---需要依赖其他容器,通常不独立出现
JApplet --- 淘汰,运行在浏览器中
JPanel --- 轻量级容器,没有缩小,最大等按钮,将大容器需要分割成多个小容器,给每个小容器设置自己特有的布局风格
无滚动条
JScrollPane --- 带滚动条的小容器
2)
2.设置布局管理器
1)setLayout()
2) 根据组件信息,决定组件在容器中的排序位置和大小
3)setLocation setSize setBounds
4) 容器默认的布局管理器
Window --- BorderLayout
Panel --- FlowLayout
Frame --- BorderLayout
3.往容器中添加组件
1) 创建组件对象
Button btu = new Button("+");
2) 把组件对象加入容器
add(btu);
图形界面完成
4.给组件添加事件监听器
btn.addActionListener(...);
练习:
常见的布局管理器
---------------------------------------------
1.FlowLayout -- 流式布局管理FlowLayout(int align)
组件安行排列,一行放不下自动换行,窗口大小改变时自动排列, 默认居中排列
align --指定左/中/右排列
hgap/vgap -- 设置横向纵向间距值
2.BorderLayout
容器划分为五大区域
BorderLayout.CENTER
BorderLayout.EAST
BorderLayout.WEST
BorderLayout.SOUTH
BorderLayout.NORTH
每个区域只能放一个组件,且组件充满整个区域,所以组件设置大小无意义,
要实现放置多个组件,需要给每个区域放置轻量级小容器,给这些小容器设
置不同的布局管理器
3.GridLayout --- 网格布局管理器
把一个容器划分为若干行若干列大小相同的网格,每个网格只能放一个组件,
且该组件充满整个网格,组件不能设置大小
4.CardLayout -- 卡片状布局管理器
每个卡片只能放一个组件,且该组件充满整个组件
Module 9 事件监听机制
==========================================================================================================
按钮 点击 产生响应
事件源(产生) 事件(传给) 监听 ==>执行响应代码
事件处理机制的三要素:
1.事件源:
能产生事件的组件 addBtu
2.事件对象:
把组件产生的事件包装成事件对象ActionEvent
3.事件监听器:
接受事件对象,产生响应 ActionListener actionPerformed()
三者如何协同工作?
例:
feng 送花 girlfriend
---------------------------------------------------
事件源 事件对象 监听器
结论:
1)事件源要维护监听器列表,要知道事件的接受者是谁
2)事件对象要携带有事件源的信息
3)监听器根据不同的事件源做出不同的响应
事件源:Girl
Set boys = new HashSet();
addEmotionListener(Boy boy){}
happy(){}
sad(){}
事件对象:EmotionEvent
Object source;
监听器:interface Boy{
void actionPerformed(EmotionEvent);
}
Module 10 Threads
===============================================================================================================================
进程:
计算机运行过程中的任务单元
1)CPU在一个时间点上只能执行一个进程
2)每个进程执行时需要【独享资源】
线程:
程序运行时的最小执行单位
1)一个进程可以划分为多个线程
2)多个线程可以【共享资源】
多个线程共享资源引发的问题:
线程的互斥和同步问题
java.lang.Thread
线程的创建:
1.继承Thread类
class MyThread extends Thread{
public void run(){}
}
2.实现Runnable接口
class MyThread implements Runnable{
public void run(){}
}
特点:run()方法必须要存在,线程一旦启动,该方法会自动被调用
线程的启动:
1) 继承Thread
MyThread th = new MyThread();
th.start();//调用Thread中的方法
2)实现接口:
MyThread runnable = new MyThread();
Thread th = new Thread(runnable);
th.start();
实现方式和继承方式有什么区别呢?
-------------------------------------------------
实现方式好处:避免了单继承的局限性,在定义线程时,建议使用实现方式。
资源可以独立共享,共享数据资源
两种方式区别:
继承---线程代码存放Thread子类run方法中
实现---线程代码存在接口的子类的run方法中 】
线程的状态转换
-------------------------------------------------------------------------
1.Runnable就绪状态
th.start()-->Runnable
等待JVM调度
2.Running执行状态
JVM采取时间分片策略,根据Scheduler调度程序调度等待中线程
Runnable--->Running(执行run()方法)
时间片结束,JVM收回该线程的执行权,交由其他等待的线程
Running --->Runnable
3.Dead死亡状态
run()执行结束
4.Blocked阻塞状态
1)stop()--结束线程,不推荐使用,导致使用的资源不会被释放
2)设置标志变量,让线程主动结束(常用方式)
join()方法
调用另一个线程的join方法,本线程进行阻塞状态,直到另一个线程执行结束,本线程才能离开blocked状态
人为使线程从blocked --->Runnable
1)interrupt()---线程从blocked --->Runnable
2)isInterrupted()---判断线程是否被中断,true表示被中断
如何让线程知道是被中断的
本线程可以通过捕获异常知道自己被打断
其他线程通过isInterrupted()判断
3)interrupted() --- 清除中断标记
总结:
1.Running -->Blocked
1).sleep()
2).其他线程.join();
2.Bloack-->Runnable
1)sleep睡眠时间结束
2)其他线程执行结束,本线程回到就绪状态
3)人为中断:interrupt();
线程的并发访问问题
------------------------------------------------------------
解决方法
synchronized(object){}
1)找出公有对象,多个线程同步竞争该公有对象的访问锁,一次只能有一个线程拿到锁(操作该对象)
2)精确控制临界区,确保多线程的执行效率
注:如果方法中所有的代码需要加锁,可在方法定义前加synchronized,否则不建议对整个方法加锁,影响程序性能
多线程的同步问题
---------------------------------
并发访问:多个线程地位均等,同步竞争公有对象的访问权
同步问题:解决的是多个线程对公有对象访问的先后顺序问题,相互协同工作
举例:打黑车到镇上
1)公有对象: 车
2)等待的线程: 打车的人
通知的线程:司机 通知所有等待的线程
3)先有等待的线程
解决同步问题的思路:
1)找出公有对象,所有的线程都通过公有对象进行通讯
2)分析出哪个线程wait,哪个线程notify
3) 确保wait在notify之前
练习:
有两个线程,一个Calculate线程负责计算1~100的和,放到公有对象Result中,另一个Print线程获取结果并打印输出
测试程序,创建这两个线程并启动
public class Result{
private int value;
}
class CalculateThread extends Thread{
private Result result;
public CalculateThread(Result res){}
}
class PrintThread extends Thread{
private Result result;
public PrintThread(Result res){}
}
public class CalculateTest{
public static void main(String[] args){
Result res = new Result();
CalculateThread ct = new ...
PrintThread pt = new...
}
}
2)Print线程wait Calculate线程notify
3) 确保wait在notify之前,添加标志变量hasWait
注意:
1)synchronized里面不能有sleep,否则抱着公有对象的锁睡觉,其他等待的线程无法拿到对象的访问锁
2)wait()在加入对象的等待队列之后,会释放该对象的访问锁
synchronize(result){
//result.wait();
1)unlock(result)
2)lock(result)
3)entryQueue(result); //加入对象的等待队列
4)unlock(result); //进入blocked之前解锁对象
5)进入blocked状态 <------notify()
6)lock(result);
7)leaveQueue(result); //离开对象的等待队列
}
isAlive()---判断线程是否存活,除了dead状态,其他都为true
setPriority()---设置线程的优先级
Thread.yield()---将执行权让给优先级比自己高的线程来执行
死锁问题
--------------
哲学家就餐问题
解决方式:
确保线程获取多个资源的顺序相同
Module 11 I/O
==================================================================================================================================
I/O输入/输出流
------------------------------------------------------------
java中采取流的概念,在应用程序和外围设备之间建立一个流对象,应用程序只单一地通过流对象进行数据的输入/输出,
而不与外围数据源/数据目的地直接交互
按照流的方向划分:
输入流InputStream
---程序从输入流中【读取】数据,不能写入,read()
输出流OutputStream
---程序往输出流中【写入】数据,不能读取,write()
按传输的数据单位划分:
字节流
以字节作为基本传输单位,一个个字节进行传输通常带有Stream的都是字节流
字符流
以字符作为传输单位,字节的可读性差,希望以文本的方式读写数据通常带有Reader/Writer的都是字符流
具有缓存功能的流
在流对象中设置缓存区,将数据先放入缓存区,再一次性提交给外围设备优势: 提高输入/输出的性能
过滤器
对流中的数据进行进一步包装,借助过滤器可以把流中提供的字节或字符拼成程序需要的数据类型
readInt readDouble ...
注:【不能单独使用】,要结合基本字节流或字符流
常用方法
read()---每次返回一个字节,返回-1表示流中的数据读完
read(byte[])--一次可以读取多个字节,放入byte[]中,返回一次读取成功的字节数
字节流的层级结构
-------------------------------------------------------------------
通常前面代表的是数据源/数据目的地的类型
FileInputStream---数据源是File,从file中读取数据
FileOutputStream---往file中写入数据
PipedInputStream---从管道中读取数据
PipedOutputStream---往管道中写入数据
FilterInputStream---过滤器,不能单独使用
BufferedInputStream---具有缓存功能的流
PushBackInputStream---把流中的数据退回去
DataInputStream---把流中的字节包装成程序需要的基本数据类型(四类八种),以结构化的方式传输数据
包:java.io
异常:IOException
练习:
完成文件内容的拷贝功能 Copy.java
要求:以提高性能的方式进行文件的拷贝
BufferedInputStream(FileInputStream(filename))
BufferedOutputStream(FileOutputStream(destname))
练习:
将一个整数以提高性能的方式写入文件中 MyCal.java
int i = 6;
分析:
1) DataOutputStream(
BufferedOutputStream(
FileOutputStream(destfile))
2) 思考不用过滤器,如何一个个字节进行传输?
管道流
---------------------------------------------------------------------
PipedInputStream--管道输入流
从管道中读取数据
PipedOutputStream--管道输出流
往管道中写入数据
管道:内存中开辟的一块公共区域
PIS(POS) POS(PIS)
练习:
构建两个线程
Sender.java ---把100个整数写入管道中
Fetch.java ---从管道中读取并打印输出
分析: Sender
---DataOutputStream(BOS(PipedOutputStream))
Fetch
----DIS(BIS(PipedInputStream))
测试程序PipedTest,构建以上两个线程对象,启动
字符流
------------------------------------------------
和字节流的体系结构相似
基本的字符流
包装后的过滤器
1.BufferedReader/BufferedWriter
功能:
1)开辟缓存区,提高传输性能 类似BIS/BOS
2)能在字符流和字符串之间进行转换 类似DIS/DOS
方法:
String readLine()
write(String,int,int)
2.InputStreamReader/OutputStreamWriter
功能:
1)桥梁流,字节流<--->字符流
InputStreamReader--- 字节流-->字符流
OutputStreamWriter--- 字符流--->字节流
2)提供java标准编码utf8和其他指定编码之间的转换
练习:
把一个中文字符串写入文件中
编译时指定编码格式: -encoding utf8
分析: String--->file
字符串--->字符流 BufferedWriter
字符流--->字节流 OutputStreamWriter
BW(OSW(FOS(filename),charSet))
3.FileReader/FileWriter
ISR/OSW的子类,父类具有的功能它们都具有
1)字符流<--->字节流
2)具有操作文件的功能
3)自动将编码转换为和操作系统对应的编码
练习:
将一个中文字符串写入文件中,再从文件中读取并打印输出
写入文件:BufferedWriter(FileWriter(filename))
读取文件:BufferedReader(FileReader(filename))
System.out--标准输出
System.in --标准输入
System.err--标准错误
File file = new File();
FileInputStream(String filename);
File file = new File(String filename);
File.seperator---路径分隔符,自动与操作系统匹配
windows: c:\doc\
linux: /etc/
对象的持久化和序列化
-----------------------------------------------------------------------
对象的持久化:
对象的寿命通常随着程序的终止而消亡,有时需要将对象的属性信息永久保存下来,在需要时再将该对象恢复,这个过程就叫对象的持久化
对象的序列化:
将一个对象转变成字节流 Object--->File
ObjectInputStream
Object readObject()--- 反序列化 得到一个对象
ObjectOutputStream
writeObject(Object o)---序列化,将对象写入外围
需要序列化的对象要实现接口:Serializable
练习:
class Company implements Serializable{
String name;
int tel;
transient Address address; //该属性无法持久化
}
class Address{
String city;
String street;
int code;
}
RandomAccessFile随机访问文件
--------------------------------------------------------------------------
可以跳到文件任意一个位置开始读/写
1)实现了两个接口:DataInput/DataOutput 具有过滤器功能
readInt writeDouble ....readLint
2)读/写功能都具有 read write
3)操作文件的功能
4)可随意在任一点读写
skip(long)---跳过指定的字节数,但还是从文件起始位置开始遍历
seek(long)---直接跳到指定位置开始读写
构造器参数mode:
"r" --- read
"w" --- write
"rw"---read/write
InputStream
FileInputStream(String name)
PIpedInputStream(PipedOutputStream src)
ByteArrayInputStream(byte[] buf)
ObjectInputStream(InputStream in)
FileterInputStream
DataInputStream(InputStream)
bufferedInputStream(InputStream)
Reader
PipedReader(PipedWriter src)
InputStreamReader(InputStream in) ---- 桥梁流
FileReader(String fileName)
CharArrayReader(char[] buf)
BufferedReader(Reader in)
Module 12 网络编程
================================================================================================================================
1.基于TCP/IP协议的编程
2.基于UDP协议的编程
IP地址:可以唯一定位网络上的一台主机
Port端口号:人为制造的16位整型数,只能用1024之后的
包:
1.java.net
2.java.io
3.java.lang
IP
特点:无连接的,数据可靠性不能保证
TCP---解决的事数据传输的可靠性问题
特点: 1)面向连接的
2)【完全可靠的数据传输】
3)点对点的
4)同一连接既可以发送也可以接收
5)面向字节流的
6)连接的建立和关闭经过双方确认
UDP---解决的是数据传输效率问题
视频点播
邮递员送信
1.DatagramSocket
--只负责报文的发送/接收
2.DatagramPacket
--负责将数据打成报文对象