JAVA学习笔记
一 JDK安装
1.1环境变量配置
1.1.1 永久配置环境变量
打开方式:计算机-高级-环境变量
JAVA_HOME:自己建的系统变量,添加到JDK目录即可 //切记,不是用户变量
path:系统默认环境变量,添加两个bin文件,jdk\bin和jdk\jre\bin
classpath:执行class文件时,指定优先搜索java类的存放路径
1.1.2 临时配置环境变量
JAVA_HOME:自己建的系统变量 //切记,不是用户变量
path:系统默认环境变量
set path //查看环境变量
setpath=d:\hello;%path% //设置环境变量,只在当前cmd窗口有效,关闭后不影响path原来值,帮助:helpset
classpath:执行Java程序时,优先搜索java类的存放路径
setclasspath=d:\hello //只在指定路径下搜索java类程序
setclasspath=.;d:\hello //只在指定路径下(当前路径和d:\hello两个)搜索java类程序,推荐使用此种方式
setclasspath=d:\hello; //优先在classpath指定路径下搜索,然后在当前路径搜索,一般不适用此种方式
1.1.3 JDK安装成功验证及DOS编译、执行
DOS下执行:
javac
javac -version //查询java版本:
DOS下java程序的编译、执行:
编译:javac hello.java // 编译完后,生成hello.class文件,即可执行文件
执行:java hello //执行编译过后的hello类,类名尽量和文件名一致,方便运行
二 JAVA基础
1.1 关键字修饰符
1.1.1public
公有,权限最大
权限修饰符,可修饰类、属性、方法,
全局都可被使用此类、属性、方法。
1.1.2 private
权限修饰符,用于修饰成员(成员变量、成员函数)。
私有内容只在本类中有效。
修饰方法时,不存在覆盖。
注意:子父类覆盖
子类覆盖父类方法时,子类方法权限必须大于或等于父类方法权限
子类或父类方法要么同时用static修饰,要么都不被static修饰
1.1.3 static (07)
修饰符,用于修饰成员(属性和方法);
static所修饰的成员,被所有对象所共有;
static优先于对象存在,因为static成员随类的加载就存在了;
static所修饰的成员,能够被类名直接调用,类名.静态成员名;
static所修饰的数据是共享数据,对象中的存储是特有数据;
1.1.4 final (09 04)
final可以修饰类,方法,变量;
final修饰的类不可以被继承;finalclass Fu;
final修饰的方法不可以被覆盖;
final修饰的变量是一个常量,只能被赋值一次。
内部类只能访问被final修饰的局部变量。
1.1.5 void:
权限修饰符,可修饰方法;
1.2 关键字、标识符、注释
关键字:赋予特殊java含义的单词,全部小写;
public
标识符:程序中自定义的一些名称
字母,数字、_、$组成,不支持空格;
数字不可以开头;
不可以使用关键字;
如:类名HelloJava
注释:解释说明代码中的文字,调试也能用到
单行注释://单行注释内容 # 可以嵌套注释
多行注释:/*多行注释内容*/
文档注释:/**文档注释*/ # 注释中的内容可以通过java工具javadoc提取出来,生成一个网页文件,包括说明文字和代码。java特有!
注释的应用:
1.3 基本数据类型及转换
常量:不能改变的数据
"字符串",'字符',""空字符串,null啥都没有
进制:二、八、十、十六进制
变量:内存中的一块存储区域
定义变量:先定义后使用
类型 变量名 = 初始化值;
int a = 2;
强制类型转换:
(int)(a+b)
1.4 运算符
算数:+、-、*、/、%、++、--、
赋值:=、+=、-=、*=、/=、%=
比较:>、<、>=、<=、==、!=,结果为true或false
逻辑:&、|、!、^、&&(短路)、||(短路)
位:<<、>>、>>>(无符号右移)、&、|、^、~(取反) // 转化为二进制后参与运算
举例:3<< 2 // 左移两位
三元:(条件表达式)?表达式a:表达式b; #条件表达式为true时,执行表达式a,否则执行表达式b
举例:
a =(x>y)?x:y;
1.5 程序流程控制
顺序结构:子上而下顺序结构执行
判断结构:if语句
选择结构:switch语句
循环结构:while、do...while、for
1.5.1判断结构if-else
if(条件1)
{}
----------------
if(条件2)
{}
else
{}
-----------------
if(条件3)
{}
else if(条件4) //else if()可有多个
{}
else
{}
1.5.2 选择结构switch
switch(表达式)
{
case 取值1: //case后不需要使用{}
执行语句;
break;
case 取值2:
执行语句;
break;
case 取值3:
执行语句;
break;
......
default:
执行语句;
break;
}
1.5.3 循环结构while、do…while、for
while(条件)
{
语句
}
----------------
do
{
执行语句
}
while(条件); # 不要忘记while后面的';'
----------------
for(初始化表达式;循环条件;循环后的操作表达式)
{
执行语句;
}
----------------
for(type element: array)
{
System.out.println(element);
}
1.5.4 if和switch区别
if:使用较多
1)对具体的值进行判断
2)对区间进行判断
3)对运算结果是boolean类型的表达式进行判断
switch:使用较少
1)对具体的值进行判断
2)值的个数相对较少,且固定
对于几个固定的值判断,建议使用switch语句,因为switch语句会将具体的答案都加载进内存,效率相对高一点。
1.5.5 局部代码块
在主函数中,作用是:可以定义局部变量的生命周期。
eg:
{
int a =1; // 局部变量,a离开此局部代码块,就不能被使用了,因为代码块执行完之后,就被释放了。
语句......;
}
1.5.6 break、continue
break适用范围:switch和循环语句中
break:1、直接跳出所在的当层循环语句,开始执行当层循环下面的语句;如果出现了循环嵌套
2、Java中循环标号后可跳出指定循环
eg:
biaohao1:for(;;)
{
biaohao2:for(;;)1
{
执行语句;
break biaohao1; //通过标号,直接跳出两层循环。
}
}
continue适用范围:循环语句中
continue:跳过本次循环continue之后的语句,继续下次循环
1.6 函数(方法)
定义在类中的具有特定功能的一段独立小程序;可以提高代码的复用性;和主函数同级,没有嵌套函数的说法。
函数格式:
修饰符 返回值类型 函数名(参数类型1参数1,参数类型2 参数2,...)
{
功能语句;
return 返回值;
}
函数的两个明确:
1、这个功能的结果是什么? 确定返回值
2、这个功能实现过程中是否需要未知内容参与运算? 确定参数列表
----------------------------------------------------------------
1.6.1 函数重载
条件:
同一个类;
同名;
参数列表中参数个数或参数类型不同;
注意:函数重载和返回值类型无关;
Java是严谨性语言,不允许出现函数调用的不确定性,会编译失败。
----------------------------------------------------------------
1.7 数组
一维、二位数组、排序算法
一维数组定义:
元素类型[] 数组名 = 元素类型[元素个数或数组长度];
注意:数组一旦建立,必须明确其长度;
格式1:需要一个容器,但是不明确容器的具体数据。
int[] a = new int[5];
a[]
格式2:需要一个容器,存储一致的具体数据。
int[] a = new int[]{1,2,3,4,5};
格式3:需要一个容器,存储一致的具体数据。
int[] a = {1,2,3,4,5};
二维数组:
格式一:指定二维和一维数组的长度
int[][] shuZu = new int[5][3];
格式二:指定二维的长度,不指定一维数组的长度
int[][] shuZu = new int[5][];
1.8 JVM内存空间
1、寄存器
cpu相关的
2、本地方法区
所在系统相关的
3、方法区
4、栈内存
存储的都是局部变量,变量所属的作用域一旦结束,该变量就自动释放。
5、堆内存
存储的是数组和对象(其实数组就是对象),凡是new就简历在堆中。
特点:
1、每一个实体都有首地址值;
2、堆内存中的每一个变量都有默认初始化值,更具类型的不同而不同,整数是0,小数0.0,boolean是false。
3、垃圾回收机制。
三 面向对象
1.1面向对象基本概念
面向对象的特征:
封装、继承、多态
类与对象的关系?
类:对事物的描述,用java语言对显示生活中的事物进行描述,通过类的形式来体现的。
怎么描述呢?
对事物描述通常只关注两方面:属性,方法;
只要明确该事物的属性和行为并定义在类中即可;
对象:该类事物实实在在存在的个体,即类的实例;对象一般都是名词;
Java中通过new来创建; // new实际上是用来开辟一块,指定类型的空间
eg:
class car //定义一个类
{
成员变量; // 属性
成员函数; // 行为
}
new car // 创建对象
car baoma = new car // 创建一个被baoma应用的对象,给对象起个名字
baoma.成员变量名 // 调用成员变量
baoma.成员函数名() // 调用成员函数
1.1.2 成员变量和局部变量的区别
成员变量:定义在类中,整个类中都可以访问;
存在于堆内存的对象中;
随着对象的创建而存在,随着对象的消失而消失;
都有默认初始化值;
局部变量:定义在函数、语句、局部代码块中,只在所属的区域有效;
存在于栈内存的方法中;
随区域的存在而存在,区域结束而结束;
没有有默认初始化值;
1.1.3 匿名对象
即没有名字的对象,当只对对象的方法进行过一次调用的时候使用
new Car(); //即匿名对象,
new Car().run(); //匿名对象调用函数
Car c = new Car() // 有名的对象
面向对象第一个特征:封装,用于隐藏细节
private,数据私有化只是实现封装的方式之一;
private:私有,是一个权限修饰符,权限最小,public权限最大,用于修饰成员,私有的内容只在本类中有效。
privateint age;
publicvoid setage(int a)
{}
publicvoid getage(int a)
{}
1.2 构造函数
构造函数:构建创造对象时调用的函数,可以给对象初始化;
如果类中没有定义过构造函数,那么该类中会有一个默认的空参数构造函数;
如果类中已经定义过构造函数,那么该类中的默认的构造函数就没了;
构造函数
特点:
1、函数名与类名相同;
2、不用定义返回值类型;
3、没有具体返回值;
作用:对对象进行初始化
class Person
{
Person() //构造函数名必须与类名一致
{
......;
}
}
Person zhangsan = new Person(); //在创建对象时,自动回调用执行构造函数Person()
一般函数和构造函数的区别?
构造函数:
在对象创建时,就会调用与之对应的构造函数,对对象进行初始化;
在对象创建时,只调用一次;
一般函数:
对象创建后,需要函数功能时才调用;
对象创建后,可根需要调用多次;
this关键字:代表当前对象
使用1:
this就是所在的函数所属对象的引用;
简单说:哪个对象调用了this所在的函数,this就代表哪个对象;
使用2:
使用this可以用于在构造函数中,调用其他构造函数,注意:只能定义在构造函数的第一行,因为初始化动作需要先执行。
1.1 子父类实例化过程(09 03)
person p = person();
1、JVM会读取指定的路径下的person.class文件,并加载进内存,并会先加载person的父类(如果有直接的的父类的情况下);
2、在堆内存中的开辟空间,分配地址;
3、并在对象空间中,对对象中的属性进行默认初始化;
4、调用对应的构造函数进行初始化;
5、在构造函数中,第一行会先到调用父类中构造函数进行初始化;
5、父类初始化完毕后,在对子类属性进行显式初始化;
7、再进行子类构造函数的特定初始化;
8、初始化完毕后,将地址赋值给应用变量;
子父类实例化加载图解
1.2 抽象类(09 06)
abstract class ClassName{
abstractvoid funcName();
}
1、方法只有声明没有实现时,该方法就是抽象方法,需要被abstract修饰,抽象方法必须定义在抽象类中,该类必须也被abstract修饰;
2、抽象类不可以被实例化,为什么?因为调用抽象方法没意义;
3、抽象类必须有其子类覆盖了所有的抽象方法后,该子类才可以实例化,否则,这个子类还是抽象类;
抽象类和一般类的异同点
相同点:抽象类和一般类都是用例描述事物的,都在内部定了成员
不同点:
1、一般类有足够的信息描述事物,抽象类描述事物的信息有可能不足;
2、一般类中不能定义抽象方法,只能定义飞抽象方法,抽象类中可以定义抽象方法,同时也可以定义非抽象方法;
3、一般类可以被实例化,抽象类不可以被实例化;
抽象类一定是父类吗?
是的,因为需要子类覆盖其方法后才可以对子类实例化;
1.2 接口(09 09)
当一个抽象类中的方法都是抽象类的时候,这是就可以将该抽象类用另一个形式定义和表示,就是接口interface;
接口的定义关键字是interface,不是class
对于接口当中常见的成员;而且这些成员都有固定的修饰符(系统会自动加上)
1、全局常量,public staticfianl
2、抽象方法,public abstract
由此得出结论,接口中的成员都是公共的权限。
interface Demo
{
publicstatic final int value = 4; //加黑处为系统固定加的
publicabstract void show1(); //
publicabstract void show2(); //
}
实现:相当于继承的extends
class DemoZi implementsDemo{ //实现
}
类与类直接是继承关系;类与接口之间是实现关系;
接口不可以实例化。
只能有实现了接口的子类并覆盖了接口中所有的抽象方法后,该子类才可以实例化,否则这个子类就是抽象类。
多实现:Java中不允许多继承,但允许多实现
class DemoZi implementsDemo,Demo1{ //多实现
}
在Java中不直接支持多继承,因为会出现调用的不确定性,所以java将多继承机制进行改良,在Java中变成了多实现。
一个类在继承另一个类的同时,还可以实现多个接口
classDemoZi extends Fu implements Demo1,Demo2{ //继承一个类,并且实现多个接口
}
接口与接口之间是继承关系(而且可多继承);类与类(抽象类)之间是继承关系;类与接口之间是实现关系。
接口特点:
对外暴露规则;
程序功能扩展;
降低耦合性;
可以用例多实现;
抽象类和接口的区别:
相同点:都是不断向上抽取而来的;
不同点:
抽象类需要被继承,而且只能单继承;接口需要被实现,而且可以多实现;
抽象类中可以定义抽象类方法和非抽象方法,子类继承后,可以直接使用非抽象方法;接口中只能定义抽象方法,必须有子类去实现;
抽象类的继承,是is a关系,在定义该体系的基本共性内容;
接口的实现是like a关系,在定义体系额外功能。
1.3 多态(10 02)
多态:某一类事物的多种形态
举例:猫种类事物即具备猫的形态,,又具备着动物的形态,这就是对象的多态性。
简单说:就是对象对应着不同类型。
多态在代码中的体现:
父类或者接口的引用指向其子类的对象。一个对象两种形态
多态的好处:
提高了代码的扩展性,前期定义的代码可以使用后期的内容
多态的弊端:
前期定义的内容不能使用(调用)后期子类的特有内容。
多态的前提:
1、必须有关系,继承,实现。
2、必须有覆盖。
多态转型:
向上转型:猫类型的猫,转为动物类型;Animal a = new Cat()
向下转型:动物类型的猫对象,转为猫类型;Cat b = (Cat)a
如果还想用具体动物猫的特有功能,可以将该对象进行向下转型,使用子类的特有方法。
注意:对于转型,自始至终都是子类对象在做着类型的变化
判断对象是何种类:
animala = new cat();
if(a instanceof cat)//为真
if(a instanceof dog)//为假
if(a instanceof animal)//为真
1.3.1 多态时,成员编译和运行的特点
1、成员变量
编译时,参考引用型变量所属的类中的是否有调用的成员变量,有,编译通过,没有,编译失败;
运行时,参考引用型变量所属的类中的是否有调用过的成员变量,并运行该所属类中的成员变量;
简单地说,编译和运行都参考等号左边。
2、成员函数(特殊)
编译时,参考应用型变量所属的类中的是否有调用的成员函数,有,编译通过,没有,编译失败;
运行时,参考对象所属的类中的是否有调用过的函数,并运行该所属类中的成员函数;
简单地说,编译看左边,运行看等号右边。
3、静态函数
编译时,参考应用型变量所属的类中的是否有调用的静态方法,有,编译通过,没有,编译失败;
运行时,参考引用型变量所属的类中的是否有调用过的静态方法,并运行该所属类中的静态方法;
简单地说,编译和运行都参考等号左边。
1.4 内部类
类的位置定义在类中。
内部类的访问特点:
1、 内部类可以直接访问外部类中的成员;
2、 外部类要访问内部类,必须建立内部类的对象;
一般用于类的设计:分析食物是,发现该事物描述中还有事物,而且这个事物还在访问被描述事物的内容;这时就是还有的事物定义成内部类来描述。
class Outer{
classInner{ //内部类
}
}
内部类的创建:
Outer.Inner= new Outer().new Inner();
1.4.1 内部类修饰符
private:
static:内部类相当于外部类,Outer.Inner = new Outer.Inner()
如果内部类是静态的,只能访问外部类中的静态成员;
如果内部类中定义了静态成员,则该内部类也必须是静态的;
为什么内部类能直接访问外部类中成员
那是因为内部类持有了外部类的引用,外部类名.this
内部类放在局部位置上
即内部类放在方法内,内部类在局部位置上只能访问局部中被final修饰的局部变量。
1.4.2 匿名内部类
就是内部类的简写格式
必须有前提:内部类必须继承或实现一个外部类或者接口
匿名内部类:其实就是一个匿名子类对象。
四 异常体系
Throwable:无论是error,还是异常,问题发生就应该可以抛出,让调用者知道并处理。
通过两个关键字来体现,throws、throw,被这两关键字曹锁的列和对象都具有可抛性。
Error:一般不可处理,JVM抛出,直接修改程序。
Exception:可以处理
异常分类:
1、 编译时监测异常:Exception和其子类,除特殊子类RuntimeException体系。
希望调用者对异常做处理
2、 编译时不检测异常(运行时异常):就是Excepton中的RuntimeException和其子类。
调用者调用时出现错误,异常不可做处理,功能无法继续,直接停止程序,需修改程正。
1.1 throws和throw
1、 throws使用在函数上;throws可抛出多个异常类,用逗号隔开;
2、 throw使用在函数内;throw抛出一个异常;
1.2 try …catch异常捕捉
不能处理就抛,能处理就try
对异常进行针对性处理的方式。
具体格式:
try{
需要检测的异常代码
}
catch(异常类 变量){ //变量用来接收发生的异常对象
处理异常的代码
}
finally{
一定会执行的代码
}
1.3 异常处理原则
1、函数内容如果抛出需要检测的异常,那么函数上必须要声明。否则必须在函数内用try catch 捕捉,否则编译失败
2、如果调用到了声明的异常的函数,要么trycatch 要么throws,否则编译失败。
3、try catch和throws什么时候用:
功能内容可以解决,用catch;
解决不了,用throws告诉调用者,由调用者解决。
3、 一个功能如果跑出了多个异常,那么调用时,必须有对应多个catch进行针对性的处理;
内部有几个需要检测的异常,就抛出几个异常,抛出几个就catch几个。
1.4 finally
catch、return执行完后,finally里的语句都会执行;
除了执行退出jvm虚拟机语句 System.exit(0)后,finally不会执行。
1、 try catch finally
2、 try catch ,当没有必要资源需要关闭时,可以不用finally
3、 try finally, 需要throws抛出,异常无法直接catch处理,但是资源需要被关闭。
1.5 异常的注意事项
1、 子类在覆盖父类方法时,父类的方法如果抛出了异常,那么子类的方法只能抛出父类的异常或者该异常的子类。
class A extends exception{}
class B extends A{}
class C extends exception{}
2、 如果父类抛出多个异常,那么子类只能抛出父类异常的子集。
简单说:子类覆盖父类只能抛出父类的异常或者子类或者子集。
注意:父类的方法没有抛出异常,那么子类覆盖时绝对不能抛;只能try。
1.6 多catch情况
一般抛几个,就有几个catch处理异常;但是可以使用Excetion接收所有异常,且必须放在最后一个cathc里,否则编译失败。
五 Object类
1.1 equals方法
equals方法复写,重点掌握。
1.2 hashCode方法
equals方法复写时,hashCode方法通常需要复写,以保证相同对象的哈希值相同。
1.3 getclass方法
1.4 toString方法
六 包(package)与修饰符访问范围
1、package 包名; // 创建包,在编译时会自动创建此文件夹。
2、不同包之间的访问:被访问的包中的类必须是public的,被访问的包中的类的方法也必须是public的;
3、protect权限:不同包中,类中的方法如被protect修饰,则其他类必须是此类的子类,才能继承被protcet修饰的方法。
范围\修饰符 public protected default private
同一类中 ok ok ok ok
同一包中 ok ok ok
子类中 ok ok
不同包中 ok
1.1 import 导入
import作用:为了简化类名书写。
导包的原则,用到哪个类,就导入哪个类。
import只能导入类,不能导入包
import packa.Demo
import packa.*
import packa.aaa.*
1.2 jar包
jar:java的压缩包。
打jar包;解压jar包。
运行jar包: java jar包
七 多线程
进程:正在运行中的程序,一个进程至少有一个执行路径;
线程:进程中一个程序执行的控制单元(执行路径)。
1.1 创建线程
创建线程方法之一-继承Thread类
1、创建一个类继承Thread类; class Test extends Thread
2、覆盖Thread中的run方法,将运行的代码放到run方法中;
3、直接创建Thread子类对象; Test t1=new Test()
4、调用start方法开启线程在,自动调用线程的任务run方法执行;t1.start()
创建线程的目的是为了开启一条执行路径,去运行指定的代码和其他代码实现同时运行;
运行的指定代码就是这个执行路径的任务;
jvm创建的主线程的任务都定义在了主函数中;
自定义的线程它的任务在哪呢?
Thread类用于描述线程,线程是需要任务的,所以Thread类也对任务的描述;
这个任务就是通过Thread类中的run方法来体现,也就是说,run方法就是封装自定义线程运行任务的函数;
run方法中定义就是线程要运行的任务代码。
开启线程是为了运行指定代码,所以只有继承Thread类,并复写run方法;
将运行的代码定义在run方法中即可;
创建线程方法二 -实现Runnable接口
1、创建一个类实现Runnable类;
2、覆盖Runnable中的run方法,将运行的代码放到run方法中;
3、直接创建Runnable子类对象d;
4、创建线程对象,并将Runnable子类对象作为构造函数的参数进行传递,Threadt1 = new Thread(d);
|--因为线程的任务都封装Runnable接口子类对象的run方法中,所以要在线程创建时就必须明确要运行的任务。
5、调用线程对象(t1)的start方法开启线程
实现Runnable接口,实现多线程的好处:
1、将线程任务从线程的子类中分离出来,进行了单独的封装,按照面向对象的思想将任务封装成对象。
2、避免了Java单继承的局限性
所以,创建线程的第二种方式较为常用。
线程名字:
可以通过Thread的getName方法获取线程的名字Thread-编号(从0开始)
主线程的名字固定为 main
线程运行图解:
线程与线程之间异常互不不影响
1.2 线程状态
cpu的执行资格:可被cpu的处理,在处理对列中排队;
cpu的执行权:正在被cpu的处理;
冻结:释放执行权的同时,释同时放执行资格
线程状态
wait和sleep区别:
http://blog.csdn.net/clam_clam/article/details/6803667
1、 wait可以指定时间也可以不指定。
sleep必须指定时间。
2、 同步中时,对cpu的执行权和锁的处理不同。
wait:释放执行权,释放锁
sleep:释放执行权,不释放锁
wait唤醒后如何运行:
如果一个线程调用了某个对象的wait方法,那么该线程进入到该对象的等待池中(并且已经将锁释放),
如果未来的某一时刻,另外一个线程调用了相同对象的notify方法或者notifyAll方法,
那么该等待池中的线程就会被唤起,然后进入到对象的锁池里面去获得该对象的锁,
如果获得锁成功后,那么该线程就会沿着wait方法之后的路径继续执行。注意是沿着wait方法之后
1.3 线程安全问题
安全问题:
1、多个线程在操作共享数据;
2、操作共享数据的线程代码有多条
当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算,就会导致线程安全问题的产生。
解决安全问题的方式:同步代码块,当线程在执行这些代码的时候,其他线程不可以参与运算。
同步的前提:必须有多个线程并使用同一个锁。
synchronize(obj){ //同步代码块
语句
}
或
synchronize void show(){} // 同步函数
或
Look look = new Look();
look.look(); // 获取锁
… //需要同步的代码
lock.unlock(); // 释放锁,通常需要定义在finally代码块中
释放锁条件:
同步代码块执行完时,会释放锁;
wait()等待时,会释放锁;
总结:当A、B线程使用同一把锁lock,当A线程获取锁后(还未释放锁)-> 此时B线程获取执行权,获取锁失败,在B线程获取锁处,进入锁池等待获取锁 -> A线程第二次获取执行权,任然持有lock锁,继续执行同步代码块,执行完后,释放锁(放回锁池) -> B线程第二次获取执行权,在锁池获取锁后,开始执行同步代码块.......
同步函数和同步代码块的区别:
同步函数的锁是固定的this;
同步代码块的锁是任意对象;
建议:使用同步代码块。
静态同步函数:
静态的同步函数使用的锁,是该函数所属字节码文件对象,可以用对象.getClass方法获取,也可以用当前类名.class 表示。
1.4 线程间通讯(1423)
特点:多个线程在处理同一资源(同一对象中),但是任务却不同(多个run任务 )。
等待唤醒机制:
涉及的方法:
1、wait():让线程处于冻结状态,被wait的线程会被存储到线程池中;
2、notify():唤醒线程池中一个线程(任意);
3、notifyAll():唤醒线程池中的所有线程。
注意:这些方法都必须定义在同步中(即明确是哪个锁),因为这些方法是用于操作线程状态的方法。必须要明确到底操作的是哪个锁上的线程。
锁名:r
r.wait();
r.notify();
r.notifyAll();
为什么操作线程的方法wait notify notifyAll定义了Object类中?
因为这些方法是监视器的方法,监视器其实就是锁,锁可以是任意的对象,任意的对象调用的方式一定定义在Object中
生产者、消费者问题(14 26)
多生产者,多消费者的问题。
if判断标记,只有一次,会导致不该运行的线程运行了。出现了数据错误的情况。
while判断标记,解决了线程获取执行权后,是否要运行!
notify:只能唤醒一个线程,如果本方唤醒了本方,没有意义。而且while判断标记+notify会导致死锁。
notifyAll解决了本方线程一定会唤醒对方线程的问题。
*/
classResource
{
private String name;
private int count = 1;
private boolean flag = false;
public synchronized void set(Stringname)//
{
while(flag)
try{this.wait();}catch(InterruptedExceptione){}// t1 t0
this.name = name + count;//烤鸭1 烤鸭2 烤鸭3
count++;//2 3 4
System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);//生产烤鸭1 生产烤鸭2 生产烤鸭3
flag = true;
notifyAll();
}
public synchronized void out()// t3
{
while(!flag)
try{this.wait();}catch(InterruptedExceptione){} //t2 t3
System.out.println(Thread.currentThread().getName()+"...消费者........"+this.name);//消费烤鸭1
flag = false;
notifyAll();
}
}
classProducer implements Runnable
{
private Resource r;
Producer(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.set("烤鸭");
}
}
}
classConsumer implements Runnable
{
private Resource r;
Consumer(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.out();
}
}
}
class ProducerConsumerDemo
{
public static void main(String[] args)
{
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);
Thread t0 = new Thread(pro);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(con);
Thread t3 = new Thread(con);
t0.start();
t1.start();
t2.start();
t3.start();
}
}
1.4.1 多生产者、多消费者问题JDK1.5解决办法(14 28、29)
是对synchronized的改造,出现了Lock、Condition;
jdk1.5以后将同步和锁封装成了对象,并将操作锁的隐式方式定义到了该对象中,将隐式动作变成了显示动作。
Lock接口:出现,替代了同步代码块或者同步函数,将同步的隐式锁操作变成显示锁操作,同时更为灵活,可以一个锁上加上多组监视器。
Locklock = new ReentrantLock();newCondition
Conditioncon = lock.newCondition();//可以创建多个监视器对象
lock.lock():获取锁
lock.unlock():释放锁,通常需要定义在finally代码块中
Condition接口:出现,替代了Object中的wait、notify、notifyAll方法,将这些监视器方法单独进行了封装,变成Condition监视器对象,可以任意锁进行组合。
await():
signal():
signalAll():
*/
importjava.util.concurrent.locks.*;
classResource
{
private String name;
private int count = 1;
private boolean flag = false;
// 创建一个锁对象。
Lock lock = new ReentrantLock();
//通过已有的锁获取该锁上的监视器对象。
//Conditioncon = lock.newCondition();
//通过已有的锁获取两组监视器,一组监视生产者,一组监视消费者。
Condition producer_con = lock.newCondition();
Condition consumer_con = lock.newCondition();
public void set(String name)// t0 t1
{
lock.lock();
try
{
while(flag)
// try{lock.wait();}catch(InterruptedExceptione){}// t1 t0
try{producer_con.await();}catch(InterruptedExceptione){}// t1 t0
this.name = name + count;//烤鸭1 烤鸭2 烤鸭3
count++;//2 3 4
System.out.println(Thread.currentThread().getName()+"...生产者5.0..."+this.name);//生产烤鸭1 生产烤鸭2 生产烤鸭3
flag = true;
// notifyAll();
// con.signalAll();
consumer_con.signal();
}
finally
{
lock.unlock();
}
}
public void out()// t2 t3
{
lock.lock();
try
{
while(!flag)
// try{this.wait();}catch(InterruptedExceptione){} //t2 t3
try{cousumer_con.await();}catch(InterruptedExceptione){} //t2 t3
System.out.println(Thread.currentThread().getName()+"...消费者.5.0......."+this.name);//消费烤鸭1
flag = false;
// notifyAll();
// con.signalAll();
producer_con.signal();
}
finally
{
lock.unlock();
}
}
}
classProducer implements Runnable
{
private Resource r;
Producer(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.set("烤鸭");
}
}
}
classConsumer implements Runnable
{
private Resource r;
Consumer(Resource r)
{
this.r = r;
}
public void run()
{
while(true)
{
r.out();
}
}
}
class ProducerConsumerDemo2
{
public static void main(String[] args)
{
Resource r = new Resource();
Producer pro = new Producer(r);
Consumer con = new Consumer(r);
Thread t0 = new Thread(pro);
Thread t1 = new Thread(pro);
Thread t2 = new Thread(con);
Thread t3 = new Thread(con);
t0.start();
t1.start();
t2.start();
t3.start();
}
}
1.5 wait和sleep的区别
1、wait可以指定时间也可以不指定时间;
sleep必须指定时间;
2、在同步中时,对cpu的执行权和锁的处理不同
wait:释放执行权,释放锁;
sleep:释放执行权,不释放锁;
1.6 停止线程
1、stop方法,已过时,有死锁倾向;
2、run方法结束,任务中都会有循环结构,只要控制住循环就可以结束任务,用定义标记来完成。
3、interrupt方法,将线程从冻结状态轻质恢复到运行状态来,让线程具备cpu的执行资格。
当时强制动作会发生InterruptedException,记得要处理
1.7 其他进程
守护线程:setDeamo方法,依赖于前台线程,前台线程执行完毕后,后台线程自动关闭。
join线程:join方法,线程申请加入当前线程,临时加入的线程执行完毕后,当前线程再执行。
线程组:
yield方法:释放执行权,让其他线程执行
String类(15 01-12)
特点:
1、字符串是一个特殊的对象;一旦初始化就不可以被改变;
2、存放在字符串常量池中有,直接用;没有就建立;
Stringstr = "abc"
Stringstr1 = new String("abc")
String类的方法:
a.length() //获取字符串长度
a.chartAt(index) //获取指定位置的字符
a.indexOf('a') //获取指定字符的第一个索引位置
1.1 StringBuffer类
字符串缓冲区,用于存储数据的容器;
特点:
1、长度是可变的
2、可以存储不同类型数据
3、最终要转成字符串进行使用
4、可以对字符串进行修改
容器对象应该具备的功能:
增、删、改查 CURD
1、添加:
append(data)
inster(index,data)
2、删除:
delete(start,end) 包含头,不包含尾
deleteCharAt(int index) 删除指定位置元素
3、查找:
charAt(index)
indexOf(string)
lastIndexOf(string)
4、修改:
replace(start,end,string);
1.2 StringBuilder类
在jdk1.5以后出现了功能和StringBuffer一模一样的对象。就是StringBuilder
与StringBuffer功能相同;
区别:
1、StringBuffer是线程同步的,通常用于多线程
2、StringBuilder是线程不同步的,通常用于单线程
jdk升级意义:
1、简化书写
2、提高效率
3、增加安全性
基本数据类型包装类(16 01-05)
为了方便操作基本数据类型值,将其封装成了对象,在对象中定义了属性和行为丰富了改数据的操作,
用于描述该对象的类就称为基本数据类型对象包装类。
基本数据类型 包装类
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
该包装对象主要用于基本类型和字符串之间的转换。
基本类型-->字符串
1、基本类型数值+“”
2、用String类中的静态方法valueOf(基本类型数值)
字符串-->基本类型
1、使用包装类中的静态方法xxx parseXxx(Xxx类型的字符串)
int parseInt
2、如果字符串被Integer进行对象的封装。
可使用另一个非今天方法,intValue()
将一个Integer对象转成基本数据类型值。
集合 (16 02)
1.1集合类
对象用于封装特有数据,对象多了就需要存储,如果对象的个数不确定,就是用集合容器进行存储。
特点:
1、用于存储对象的容器
2、集合的长度是可变的
3、集合中不可以存储基本数据类型
集合容器因为内部的数据结构不同,有多种具体的容器
不断向上抽取,就形成了集合框架。
集合框架类
框架的顶层Collection接口:
Collection的常见方法:
1、添加
boolean add(Object obj);
Boolean addAll(Collection coll);
2、删除
boolean remove(object obj);
boolean removeAll(Collection coll);
void clear();
3、判断
boolean contains(object obj);
bollean containsAll(Collection coll);
4、获取
int size();
Iterator iterator();取出元素的方式,迭代器
该对象必须依赖于具体容器,因为每一个容器的数据结构都不同,所以该迭代器对象就是在容器中内部实现的。
对于使用容器者而言,具体的实现不重要,只要通过容器获取到该实现的迭代器对象即可,也就是iterator方法。
Iterator接口就是所有的Colllection容器进行元素取出的公共接口。
5、其他
boolean retainAll(Collection coll);取交集
Object[] toArray():将集合转成数组
1.1.1集合框架-List(重点)16
Collection:
List:有序(存入和取出的顺序一致),元素都有索引(脚标),元素可重复。
Set:元素不能重复,无序。
list特有常见方法:
有一个共性特点库就是都可以操作角标
1、添加
void add(index,element)
2、修改
3、删除
4、获取
除了可以使用Iterator外,List还有它特有的迭代器:ListIterator。
Vector:内部是数组数据结构,是同步的。增删查询都很慢
ArrayList:内不是数组数据结构,是不同步的,替代了Vector。查询速度快。
LinkedList:内部是链表数据结构,是不同步的。增删元素的速度快
使用Linkedlist来模拟一个堆栈或者队列数据结构。
堆栈:先进后出Fisrst In Last Out FILO
队列:先进先出First In First Out FIFO
1.1.2集合框架-Set(17 18)
Set集合:元素不可以重复,是无序。
Set接口中的方法和Collection一致。
HashSet:内部数据结构是哈希表,是不同步的。
对于HashSet集合存储的元素,先判断hashCode再判断equals,有必要的话要重写hashCode和equals方法。
TreeSet:可以对set集合中的元素进行排序,是不同步的
对于存储的元素,必须实现Comparable接口,并实现compareTo方法。
1.2集合框架-Map(重点)
Map一次添加一对元素,也叫双列集合;Collection一次添加一个元素,也叫单列集合。
Map中存储的就是键值对,必须保证键的唯一性。
常用方法:
添加:value put(key,value):返回前一个和key关联的值,如果没有,返回null
删除:
void clear():清空map集合
valueremove(key):根据指定的key删除这个键值对。
判断:
bolleancontainsKey(key):
bolleancontainsValue(value):
bolleanisEmpty():
获取:
valueget(key):通过键取值,如果没有该键,返回null;当然也可以通过返回null,判断是否包含指定键。
intsize():获取键值对的个数。
常用Map子类:
HashTable:内部结构是哈希表,是同步的,不允许null作为键,null作为值。
properties:用来存储键值对性的配置文件的信息,可以和IO技术相结合。
HashMap:内部结构是哈希表,不是同步的,允许null作为键,null作为值。
TreeMap:内部结构是二叉树,不是同步的。可以对Map集合中的键进行排序。
泛型-类、方法、接口
泛型类:
创建泛型类:classShow<E>{
void say(E e){}
public <Q> void look(Q q){}
static <W> void sta(W q){}
}
使用泛型类:Show<String>show = new Show<String>();
泛型方法:
使用定义在类上的泛型方法:show.say(“hello”);
使用定义在方法上的泛型方法:show.look(“hello”);
静态方法,不能使用类上的泛型,只能使用定义在方法上的泛型:
泛型接口:
interfaceInter<T>(){
voidshow(T t){}
}
实现方式1:实现类已明确接口泛型
classInterImp1 implements Inter<String>{
voidshow(String str){}
}
实现方式2:实现类任未明确接口泛型,由创建实例是明确
classInterImp2<Q> implements Inter<Q>{
voidshow(Q q){}
}
常用类
System类:全都是static成员,getProperties()获取系统属性集合,getProperty()获取指定key的value值。
Runtime类:操作应用程序,包括打开、销毁等操作。
Data类:常与DataFormat或SimpleDataFormat时间格式化类配合使用。
Calendar类:处理时间更为国际化通用。
IO流
按方向:相对于内存设备而言
输入流,将外设中的数据读取到内存中
输出流,将内存的数据写入到外设中
按类型:
字节流 是字节数据,Byte
字符流 是字节流+编码表
1.1 字符流
Reader、Writer
1.1.1 Writer字符输出流
FileWriter类:会使用到flush、close方法。
flush:调用后,可以继续写操作
close:调用时,会先自动调用flush,然后再关闭打开的流文件,不可再使用写操作。
BufferedWriter类:写字符流缓冲区,需提供一个Writer类或其子类的缓冲对象,用来提高性能。
newline()
注意:FileWriter缓冲区大小为1024,而BufferedWriter默认缓冲区大小为8192
http://www.cnblogs.com/xjyh/p/4529809.html
1.1.2 Reader字符输入流
FileReader类:
BufferedReader类:读字符流缓冲区,需提供一个Reader类或其子类的缓冲对象,提高性能,可读一行。
-LineNumberReader类:跟踪行号缓冲字符输入流。
readLine()
1.1.3 复制文本文件图解
1.1.4 字符流缓冲区-装饰设计模式和继承的区别
都可以进行功能的扩展。
继承:继承体系越来越臃肿,不够灵活。
装饰设计模式:对一组对象的功能进行增强时,就可以使用该模式进行问题的解决。
装饰列和被装饰类都必须所属同一个接口或者父类。
1.2字节流
InputStream、OutputStream
1.2.1 InputStream字节输入流
FileInputStream类:
BufferedInputStream缓冲区,需提供一个InputStream类或其子类作为缓冲对象,可提高性能。21.22
1.2.2 OutputStream字节输出流
FileOutputStream类:无flush方法,直接写到目的地中,但有close方法
BufferedOutputStream缓冲区,需提供一个InputStream类或其子类作为缓冲对象,可提高性能。有flush方法,有close方法,。
1.2.3 键盘录入
InputStream r = System.in,使用InputStreamread()方法读即可。
1.3 转换流
字节流转换为字节流。
InputStreamReader:可指定charset(字符集)解码为字符。
OutputStreamWriter:可指定charset(字符集)编码为字节 。
1.4 流的操作规律
想要知道开发时用到哪些对象,只要通过四个明确即可。
1、 明确源和目的
源:InputStream Reader
目的: OutputStream Writer
2、 明确数据是否是纯文本数据。
源:是纯文本:Reader
否:InputStream
目的:是纯文本:Writer
否:OutputStream
到这里,就可以明确需求中具体使用哪个体系。
3、 明确具体的设备。
源设备:
硬盘:File
键盘:System.in
内存:数组
网络:Socket流
目的设备:
硬盘:File
控制台:System.in
内存:数组
网络:Socket流
4、 是否需要其他额外功能
a、 是否需要高效(缓冲区)
是:加Buffered
b、 是否纯文本
是:源:Reader
目的:Writer
c、 明确具体设备
源:硬盘:File
目的:硬盘:File
d、 需要额外功能么
需要,需要高效
BufferedReader、BufferedWriter
1.5 File文件类
常见方法:
1、 文件获取
获取文件名称
获取文件路径
获取文件大小
获取文件(修改)时间
2、 文件创建与删除
3、 判断
4、 重命名
1.6 对象输入、输出流
ObjectOutputStream、ObjectInputStream类,它们所处理的类必须实现Serialzable接口。
程序举例:
FileOutputStream fw = new FileOutputStream("C:\\Users\\obj.object");
ObjectOutputStream ow = newObjectOutputStream(fw);
ow.writeObject(new Person("zhagnsan",18)); // 一次写一个对象
// 读对象时,需获取已写的对象文件和对象所属的类文件。
FileInputStream fr = new FileInputStream("C:\\Users\\obj.object");
ObjectInputStream or = newObjectInputStream(fr);
Person zhangsan= (Person)or.readObject(); // 一次读一个对象
System.out.println(zhangsan.getAge()+zhangsan.getName());
1.6.1 Serializable接口
属于标记型接口。
Serializable作用:用于给被序列化的类加serialVersionUID号,用于判断类和对象是否属于同一个版本。
不参与序列化的情况:
被static修饰的成员,其值不被序列化,即成员的值不被写入到硬盘上。
被trantsient修饰的成员,非静态数据不想被序列化可以使用这个关键字修饰。
1.7 RandomAccessFile-非IO体系
未深入学习
1.8 DataOutputStream、DataInputStream
操作基本数据类型
DataOutputStream os =newDataOutputStream(new FileOutputStream("C:\\Users\\os.txt"));
os.writeUTF("你好啊");
os.close();
DataInputStream is = newDataInputStream(new FileInputStream("C:\\Users\\os.txt"));
System.out.println(is.readUTF());
os.close();
其他类:源和目的都是内存的对象,close()方法无效。
操作字节数组:ByteArrayInputStream、ByteArrayOutputStream
操作字符数组:CharArrayReader、CharArrayWriter
操作字符串:StringReader、StringWriter
1.9 编码、解码
特点:
1、 该对象既能读,有能写。
2、 该对象内部维护了一个byte数组,并通过指针可以操作数组中的元素。
3、 可以通过getFilePointer方法获得指针的位置,和通过seek方法设置指针的位置。
4、 其实该对象就是对字节输入流和输出流进行了封装。
5、 该对象的源或者目的只能是文件,通过构造函数就可以看出。
网络编程
1.1网络模型
OSI参考模型(开放系统互联)
TCP/IP参考模型
网络通讯三要素:IP地址、端口号、传输协议(TCP、UDP)
域名解析:127.0.0.1 localhost
1.2 IP对象:InetAddress类
InetAddress ipHost = InetAddress.getLocalHost(); //获取本机ip地址
ipHost =InetAddress.getByName("www.baidu.com"); //获取其他主机ip地址
ipHost =InetAddress.getByName("192.168.0.1"); //获取其他本机ip地址
1.3 Socket(套接字、插座)
网络服务提供的一种机制
通信两个端点就是Socket,网络通信其实就是Socket通信。
1.3.1 UDP传输
DatagramSocket类:建立UDPsocket服务
DatagramPacket类:封装发送或接受的数据包
创建UDP传输的发送端:
1、 建立udp的socket服务
DatagramSocket ds = new DatagramSocket(8888);
2、 将要发送的数据封装到数据包中
String str = “udp传输演示”;
byte[] buf = str.getBytes();
DatagramPacket dp = new DatagramPacket(buf,buf.length,InetAddress.getByName(“192.168.1.100”),10000);
3、 通过udp的socket服务将数据包发送出去
ds.send(dp);
4、 关闭socket服务
ds.close();
创建UDP传输的接收端:
1、 创建udp的socket服务,必须明确端口号
DatagramSocket ds = new DatagramSocket(10000); //接收发送端10000端口的数据包
2、 创建数据包,用于存储接收到的数据,方便用数据包的方法解析这些数据
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf,buf.length);
3、 使用socket服务的receive方法将接受的数据存储到数据包中
ds.receive(dp); //阻塞式的
4、 通过数据包的方法解析数据包中的数据
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort(); //得到的端口为8888
String test = new String(dp.getData(),0,dp.getLength());
System.out println(ip+”:”+port+”:”+test);
5、 关闭资源
ds.close();
1.3.1.1 广播:192.168.1.255
1.3.1.2 多线程udp
1.3.2 TCP传输
Socket:客户端
ServiceSocket:服务器端
TCP传输:客户端建立过程
1、 创建tcp客户端socket服务,使用Socket对象。建议创建该对象时就明确目的地,要连接的主机。
Socket socket = new Socket(“192.168.0.110”,1001);
2、 如果连接成功,说明数据传输通道已建立。该通道就是socket流,是底层创建好的。
既然是流,说明这里既有输入,又有输出。
想要输入或者输出流对象,可以找Socket对象来获取,getOutputStream()和getInputStream()
OutputStream out = new socket.getOutputStream();
3、 使用输出流,将数据写出到网络中的指定主机上。
out.write(“tcp演示”.getBytes());
4、 关闭资源。
socket.close();
TCP传输:服务端建立过程
1、 创建tcp客户端socket服务,使用ServerSocket对象。服务端必须对外提供一个端口,否则客户端无法连接。
ServerSocket ss = new ServerSocket(1001);
2、 获取连接过来的客户端对象。
Socket s = ss.accept(); //阻塞式
3、 通过客户端对象获取socket流读取客户端发来的数据,并答应在控制台上。
InputStream in = s.getInputStream();
byte[] buf =new byte[1024];
int len = in.read(buf);
String text = new String(buf,0,len);
System.out.println(“server:”+text);
4、 关闭资源。关客户端,关服务端。
s.close();
ss.close();
1.3.2.1多线程TCP
1.3.3 常见客服端、服务端及其原理
常见的客户端
浏览器:IE
常见的服务端
服务器:Tomcat(web服务器)
自定义服务端
使用已有的客户端IE,了解一下客户端给服务端发了什么请求?
发送的请求是:
1.3.4 模拟浏览器获取信息
1.3.5 URL类
1.3.6 常见网络结构
1、C/S
特点:该结构的软件,客户端和服务端都需要编写;
开发成本较高,维护较为麻烦。
好处:客户端在本地可以分担一部分运算;
2、B/S
特点:该结构的软件,只开发服务器端,不开发客户端,因为客户端直接由浏览器取代;
开发成本相对低,维护更为简单。
GUI 图形化用户界面
Awt与Swing
Awt:abstract windowToolKit(抽象窗口工具包),需要调用本地系统方法实现功能。属于重量级控件。
Swing:在AWT 的基础上,建立的一套图形界面,其中提供了更多的巨剑,而且完全由java实现。增强了移至性。增强了移至性,属轻量级控件。
继承关系图
Container:为容器,是一个特殊的组件,该组件中可以通过add方法添加其他组件进来。
1.1布局管理器
容器中的组件的排放方式,就是布局。
常见的布局管理器:
FlowLayout(流式布局管理器)
从左到右的顺序排列。
Panel默认的布局管理器。
BorderLayout(边界布局管理器)
东,南,西,北,中
Frame默认的布局管理器。
GridLayout(网格布局管理器)
规则的矩阵
CardLayout(卡片布局管理器)
选项卡
GridBagLayout(网格包布局管理器)
非规则的矩阵
1.2建立一个简单的窗体
Frame f = new Frame("myFrame");//创建窗体
f.setSize(500, 600);//窗体设置
f.setLocation(20, 20);
f.setLayout(new FlowLayout());//窗体布局设置
Button b = new Button("一个按钮");
f.add(b);//给窗体添加组件
f.setVisible(true);//显示窗体
1.3 事件监听机制
监听机制组成:
事件源(组件)
事件(event)
监听器(listener)
事件处理(引发事件后处理方式)
Frame f = new Frame("myFrame");//创建窗体
f.setSize(500, 600);//窗体设置
f.setLocation(20, 20);
f.setLayout(new FlowLayout());//窗体布局设置
Button b = new Button("一个按钮");
f.add(b);//给窗体添加组件
f.addWindowListener(new WindowAdapter() {
@Override
publicvoid windowClosing(WindowEvent e) {
// TODO Auto-generatedmethod stub
System.exit(0);
}
});//事件监听机制,关闭窗口
f.setVisible(true);//显示窗体
System.out.println("over");
1.3.1 鼠标和键盘事件
import java.awt.Button;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
publicclass Mousetest {
private Frame f;
private TextField tf;
private Button b;
public Mousetest(){
init();
}
privatevoid init() {
// TODO Auto-generatedmethod stub
f = new Frame("演示鼠标和键盘监听");
f.setBounds(400, 200, 500, 400);
f.setLayout(new FlowLayout());
tf = new TextField(15);
b = new Button("一个button");
f.add(tf);
f.add(b);
myEvent();
f.setVisible(true);
}
privatevoid myEvent() {
//给文本框添加键盘监听
tf.addKeyListener(new KeyAdapter() {
@Override
publicvoid keyPressed(KeyEvent e) {
// TODO Auto-generatedmethod stub
System.out.println("key pressed ::::" + e.getKeyChar() + "::::" + e.getKeyCode());
}
});
// TODO Auto-generatedmethod stub
f.addWindowListener(new WindowAdapter() {
@Override
publicvoid windowClosing(WindowEvent e) {
// TODO Auto-generatedmethod stub
System.exit(0);
}
});
//鼠标活动监听
b.addActionListener(new ActionListener() {
@Override
publicvoid actionPerformed(ActionEvent e) {
// TODO Auto-generatedmethod stub
System.out.println("button action:");
}
});
//在按钮上添加一个鼠标监听事件
b.addMouseListener(new MouseAdapter() {
privateintcount = 0;
@Override
publicvoid mouseEntered(MouseEvent e) {
// TODO Auto-generatedmethod stub
//System.out.println("moustentering!!!!"+"count:" + count++);
tf.setText("count:" + count++);
}
});
//鼠标单击事件监听
b.addMouseListener(new MouseAdapter() {
@Override
publicvoid mouseClicked(MouseEvent e) {
// TODO Auto-generatedmethod stub
System.out.println("mouse click ");
if(e.getClickCount()==2){
System.out.println("mouse click two ");
}
}
});
}
publicstaticvoid main(String[] args){
new Mousetest();
}
}
1.3.2 Swing演示-装插件
反射机制
在运行状态中,对于任意一个类(class文件),都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能成为java语言的反射机制。
简单的说就是:动态获取类中的信息,就是java反射。
可以理解为对类的解剖。
1.1应用场景
Tomcat:提供了处理请求和应答的方式。因为具体的处理动作不同,所以对外提供了接口,由开发者来实现具体请求和应答方式。对外提供的接口interface Servlet,开发者的类继承此接口即可,并配置web.xml文件。
学习框架:1)框架是干嘛的;2)框架中的配置文件。
1.2 反射细节
反射就是获取Class文件,并进行处理。
获取字节码文件的三种方法:
1) Object类中的getClass方法,想要用这种方式,必须要明确具体的类,并创建对象。
2) 任何数据类型都具备一个静态的属性.class来获取器对应的Class对象。相对简单,但还是要明确用到类中的静态成员。还是不够扩展。
3) 只要通过给定的类的字符串名称就可以获取该类,更为扩展。可以用Class类中的方法完成;该方法就是Class.forName();这种方式只要有名称即可,更为方便,扩展性更强。
1.3 反射机制创建对象
1.3.1创建不带参数列表的对象
String name=”cn.itcast.bean.Person”;
Class clazz =Class.forName(name);
Object obj = clazz.newInstance();
等价于
cn.itcast.bean.Personobj = new cn.itcast.bean.Person();
1.3.2创建带参数列表的对象
String name=”cn.itcast.bean.Person”;
Class clazz =Class.forName(name);
Constructorconstructor = clazz.getConstructor(String.class,int.class);
Object obj = constructor.newInstance(“小强”,39);
等价于
cn.itcast.bean.Personobj = new cn.itcast.bean.Person(“小强”,39);
1.3 获取Class中的字段(属性)
String name=”cn.itcast.bean.Person”;
Class clazz = Class.forName(name);
//Field field = clazz.getField(“age”); //只能获取公共权限的
Field field = clazz.getDeclaredField(“age”);//可以获取所有权限的,age为private
field.setAccessible(ture);//对私有字段的访问取消权限检查,暴力访问
Object obj =clazz.newInstance();
field.set(obj,89); //设置age=89
Object o =field.get(obj);
System.out.println(o);//输出 89
1.4 获取Class中的方法
String name=”cn.itcast.bean.Person”;
Class clazz = Class.forName(name);
//Method[] methods = clazz.getMethods();//获取的都是公有的方法,包括本类和父类中的
//Method[] methods = clazz.getdeclaredMethods();//只获取本类中多有方法,包括私有的
Method method = clazz.getMethods(“show”,null);//获取空参数一般方法
//Method method = clazz.getMethods(“show”,int.class);//获取带参数方法
Object obj =clazz.newInstance();
method.invoke(obj,null);//获取空参数一般方法
// method.invoke(obj,89);//获取带参数方法
1.5反射举例
正则表达式
主要用来操作字符串数据,通过一些特定的符号来体现的,所以我们为了掌握正则表达式,必须要学习一些符号。虽然简化了,但是阅读性差。
1.1常见的正则表达式
java.util.regex.Pattern类,正则表达式摘要
1.1.1匹配
其实使用的就是String类中的matches()方法,将字符串匹配正则规则。
1.1.2切割
其实使用的就是String类中的split()方法
String str = “zjamgsam xaoqiang zhaoliu”;
组:()
1.1.3替换
其实使用的就是String类中的replaceAll()方法。
1.1.4获取
使用类:
java.util.regex.Pattern
java.util.regex.Matcher
典型的调用顺序是:
Pattern p =Pattern.compile("a*b");//将正则封装成正则对象
Matcher m = p.matcher("aaaaab");//使用正则对象matcher方法,获取匹配器对象
m.find();//开始匹配查找
m.group();//获取查找的子序列
HTML
1.1 html特点
超文本标记语言,是最基础的网页语言。
是通过标签来定义的语言。
代码由<html>开始</html>结束,头部分<head></head>,体部分<body></body>
<html>
<head>
<title>这是我的html学习文件</title>
</head>
<body>
你好,html!<fontcolor="red" size="8">红色8号字体</font>默认字体颜色<br/>内部闭合,换行啦!
<!--html标签注释。 -->
</body>
</html>
格式:
<标签名 属性名=”属性值”>数据内容</标签名> //外部闭合
<标签名 属性名=”属性值” /> //内部闭合
操作思想:
为了操作数据,都需要对数据进行不同标签的封装,通过标签中的属性对封装的数据进行操作。标签就相当于一个容器,对容器中的数据进行操作,就是在不断地改变容器的属性值。
1.2常用标签
javaEE视图,或DW工具。学习时使用aptana插件。
1.2.1列表标签 dl
dl
上层项目:dt
下层项目:dd,带有自动缩进效果
<body>
<dl>
<dt>上层项目内容</dt>
<dd>下层项目内容</dd> //dd带有自动缩进效果
<dd>下层项目内容</dd>
</dl>
<body/>
1.2.2有序ol和无序ul项目列表
有序:<ol>
无序:<ul>
无论有序和无序,条目的封装用的都是<li>
而且他们都有缩进效果
<body>
<ul>
<li>无序项目内容</li>
<li>无序项目内容</li>
<li>无序项目内容</li>
</ul>
<oltype="a">
<li>有序项目内容</li>
<li>有序项目内容</li>
<li>有序项目内容</li>
</ol>
</body>
1.2.3图形标签 img
<img>
<body>
<imgsrc="img\1.png" htght=300 width="500" border="10"alt="啊,乱了" />
</body>
1.2.4表格标签 table
格式化数据
<table>
<body>
<table border=1bordercolor="0000FF"> //表格标签
<tr> //行标签
<td> 姓名:张三</td> //单元格
</tr>
<tr>
<td> 姓名</td>
<td> 年龄</td>
</tr>
<tr>
<td> 张三</td>
<td> 49</td>
</tr>
</table>
</body>
1.2.5超链接 href
作用一:连接资源
当有了href属性才有了点击效果,href属性的值的不同,解析的方式也不一样;
如果在改制中没有指定任何协议,解析时,是按照默认的协议解析该值的,默认协议是file协议。
<body>
<ahref="http://www.sina.com.cn" target="_blank">
新浪网站
</a>
<hr/>
<ahref="img/1.png" target="_blank">
美女
</a>
<hr/>
<ahref="mailto:abc@sina.com" target="_blank">
联系我们
</a>
<hr/>
<ahref="http://www.xunlei.com/mobies/fczlm.rmvb" target="_blank">
复仇者联盟
</a>
<hr/>
<ahref="thunder://sdfw.xusdfnlei.cosdfm/msdfobies/fczlsfdm.rmvb"target="_blank">
复仇者联盟
</a>
<hr/>
<ahref="javascript:void(0) οnclick=”altert(“我弹”)”target="_blank">
取消超链接的默认点击效果,并自定义效果,加时间监听即可
</a>
</body>
作用二:定位标记,专业术语:锚
<body>
<aname=”top”>顶部位置</a>
<hr/>
<ahref="http://www.sina.com.cn" target="_blank">
新浪网站
</a>
<hr/>
<ahref="mailto:abc@sina.com" target="_blank">
联系我们
</a>
<hr/>
<ahref="http://www.xunlei.com/mobies/fczlm.rmvb"target="_blank">
复仇者联盟
</a>
<hr/>
<ahref="thunder://sdfw.xusdfnlei.cosdfm/msdfobies/fczlsfdm.rmvb"target="_blank">
复仇者联盟
</a>
<aname=”center”>中间位置</a>
<hr/>
<ahref="javascript:void(0) οnclick=”altert(“我弹”)”target="_blank">
取消超链接的默认点击效果,并自定义效果,加时间监听即可
</a>
<ahref="#top">
顶部位置连接
</a>
<ahref="#center">
中间位置连接
</a>
</body>
1.2.6 html框架 frame
frame
1.2.7画中画 iframe
iframe
<body>
<iframesrc="htmlTest.html">这是画中画标签</iframe>
</body>
1.2.8 表单标签form
form:是最常用的标签,用于与服务端的交互。
1.2.8.1 input
1.2.8.2 select、testarea
1.2.8.3 表单格式化
格式化
get和post提交的区别?
1、
get提交:提交的信息都显示在地址栏中;
post提交:提交的的信息不显示在地址栏中。
2、
get提交:对于敏感数据信息不安全;
post提交:对于敏感数据信息安全;
3、
get提交:对于大数据信息不行,因为地址栏存储体积有限;
post提交:可以提交大体积数据。
4、
get提交:将信息封装到了请求消息的请求行中;
post提交:将信息封装到了请求体中。
在服务端的区别:
1.2.9 其他常用标签
头标签都放在<head> </head>之间
title
base
meta
link
1.3 XTML和XML
1.4标签的分类
div:区域标签,没有直接含义,只为封装数据。自带换行
span:同上,不带自动换行。
p:同上,段落之间自带空行。
标签分为两大类:
1、 块级标签(元素):标签结束之后都有换行;如:div 、p、dl、table、title
2、 行内标签(元素):标签结束之后没有换行;如:font、span、img、input、select a
CSS
CSS 是层叠样式表(CascadingStytle Sheets)用来定义网页的现实效果,可以解决html代码对样式定义的重复,提高了后期样式代码的可维护性,并增强了网页的现实效果功能。简单一句话:CSS将网页内容合显示样式进行分离,提高了显示功能。
1.1 CSS和html结合方式
1.1.1 html标签中style样式属性
每个html标签中都有一个style样式属性,该属性的值就是css代码。
<body>
<div style=“background-color:#06F; color:#F00”>这是一个div区域</div>
</body>
1.1.2 使用style标签
放在head头标签内,一开始就加载。
<html>
<head>
<title>form表单标签</title>
<style type="text/css">
div{
background-color:#000;
color:#FFF
}
</style>
</head>
<body>
<div style=“background-color:#06F; color:#F00”>这是一个div区域</div>
<div >这是一个div区域</div>
</body>
</html>
1.1.3 导入css文件方式
<head>
<title>form表单标签</title>
<style type="text/css">
@import url(div.css);
</style>
</head>
div.css文件内容:
div{
background-color:#000;
color:#FFF
}
1.1.4 html链接方式
<head>
<title>form表单标签</title>
<linkrel “stylesheet” href=”div.css” type=“text/css” />
</head>
1.2 选择器
样式优先级: 由上到下,由内到外,优先级由低到高。
选择器:指定css要作用的标签,哪个标签的名称就是选择器;共3种。
1、 html标签名选择器,使用的就是html的标签名;就是css和html结合的几种方式。
2、 class选择器,其实使用的是标签中的class属性。
<head>
<title>form表单标签</title>
<style type="text/css">
div{
background-color:#000;
color:#FFF
}
.haha{ //预定样式,实现动态加载
background-color:#000;
color:#FFF
}
</style>
</head>
<body>
<divstyle=“background-color:#06F; color:#F00”>这是一个div区域</div>
<div class=”haha”>这是一个div区域</div>
<span class=”haha”>这是一个span区域</span>
</body>
3、 id选择器,其实使用的是标签中的id属性;通常id的取值在页面中是唯一的,因为给属性除了给css使用,还可以被js使用;id通常都是为了去标识页面中的一些特定区域使用的。
<head>
<title>form表单标签</title>
<style type="text/css">
div{
background-color:#000;
color:#FFF
}
#qq{ //一般id是页面唯一的,不像此处使用方式
background-color:#000;
color:#FFF
}
</style>
</head>
<body>
<divstyle=“background-color:#06F; color:#F00”>这是一个div区域</div>
<div id=”qq”>这是一个div区域</div>
<span id=”qq”>这是一个span区域</span>
</body>
优先级:标签选择器<类选择器<id选择器<style属性
1.3 其他选择器
1.3.1关联选择器
选择器中的选择器
<head>
<style type="text/css">
divb{ //div中的b选择器
background-color:#000;
color:#FFF
}
</style>
</head>
<body>
<div >这是一个<b>区域</b></div>
</body>
1.3.2组合选择器
多种选择器进行相同样式定义
<head>
<style type="text/css">
.haha,divb{ //.haha和div b用逗号将两个选择器隔开
background-color:#000;
color:#FFF
}
</style>
</head>
<body>
<div >这是一个<b>区域</b></div>
<div class=”haha”>这是一个div区域</div>
</body>
1.3.3伪元素选择器
多种选择器进行相同样式定义
L V H A
<head>
<style type="text/css">
a:link{ //点击之前效果
background-color:#0F0;
color:#FFF
}
a:hover{ //鼠标悬停效果
background-color:#000;
color:#FFF
}
a:active{ //点击效果
background-color:#000;
color:#F0F;
font-size:36px;
}
a:visited{ //访问之后效果
background-color:#000;
color:#FFF
text-decpration:line-through;
}
</style>
</head>
<body>
<a herf=http://www.sina.com.cn target=”_blank”>这是一个伪元素</a>
</body>
JavaScript
1.1 JavaScript概述
JavaScript是基于对象和时间驱动的脚本语言,主要应用在客户端。
JavaScript和java的不同:
1、 JS是Netscape公司的产品,前生是livescript;Java是Sun公司的产品,现在是oracle公司的产品;
2、 js是基于对象,java是面向对象;
3、 js只需解释就可以执行,java需要先编译成字节码文件,再执行;
4、 js是弱类型,java是强类型。
1.2 JavaScript与HTML结合方式
1、将JavaScript代码封装到<script>标签中;
2、将JavaScript代码封装到js文件中,并通过<script>中的src属性进行导入;
注意:如果<script>标签中使用src属性,那么该标签中封装的javascript代码就不会被执行。所以通常导入js文件都是用单独<script>来完成。
<html>
<head>
<title>这是我的JavaScript</title>
</head>
<body>
<scripttype="text/javascript" src="jsdemo.js"></script> //导入js代码
<script type="text/javascript" > //封装在<script>标签内
alert("hellojavascript");
</script>
</body>
</html>
jsdemo.js文件内容
alert("hello javascript demo22");
1.3 JavaScript语法
通常高级程序设计语言所包含的语法内容:
1、 关键字:该种语言中被赋予了特殊含义的单词。
2、 标识符:用于标示数据表达式的符号,通常可以理解为程序中自定义的名称,如变量名、函数名。
3、 注释:注释说明解释程序,用于调试程序。
4、 变量:用于标示内存中以便空间,用于存储数据,该空间中的数据是可以变化的。
什么时候使用变量,当数据不确定的时候。
5、 运算符:可以让数据进行运算的符号。
6、 语句:用于对程序的运行流程进行控制的表达式。
7、 函数:用于对功能代码进行封装,便于提高复用性。
8、 数组:对于数据进行存储,便于操作,就是传说中的容器。
9、 对象:只要是基于对象的语言,或者是面向对象的语言,就存在对象的概念。
对象就是一个封装体,既可以封装数据,又可以封装函数。
这些都是高级程序设计语言具备的共性内容,只不过各种语言对这些内容的表现形式有所不同,但是基本使用思想是一致的。
1.3.1JS 变量
Js是弱类型的;
关键字:var
举例:
<scripttype="text/javascript">
var x = 3;
alert(“x=”+x);
</script>
全局变量和局部变量
<script type="text/javascript">
for(varx=0;x<3;x++){ // x在当前脚本页面都有效的变量,是全局变量
dpci,emt.write(“x=======”+x);
}
function show(){
var x= 6; //函数局部的X变量,局部变量
}
dpci,emt.write(“x=======”+x);
</script>
<script type="text/javascript">
dpci,emt.write(“x=======”+x);
</script>
1.3.2 JS 运算符
1、算数运算符:+ - * / % ++ --
2、赋值运算符:= += -= *= /= %=
3、比较运算符:> < > = <= == != 运算完的结果是false或true
4、逻辑运算符:&& || ! 用来连接两个boolean型的表达式
5、位运算符:& | ^ >> << >>>
6、三元运算符:?:
1.3.3 JS语句
1、顺序结构:
2、判断结构:if
3、选择结构:switch
4、循环结构:for while
5、其他语句:break跳出选择和跳出循环;continue用于循环结构,结束本次循环,继续下次循环
if选择结构
switch选择结构
while for循环结构
1.3.4 JS数组
数组用于存储更多的数据,是一个容器。
特点:
1、 长度时可变的;
2、 元素的类型是任意的,建议在使用数字时,存储同一类型的元素,操作起来较方便。
定义数组的两种方式:
1、 var arr = []
var arr= [1,3,2,4];
alert(typeof(arr)); //Object对象类型
alert(“len=”+arr.length); //4数组长度,可用于遍历数组
2、 使用了JavaScript中的Array对象来完成定义
var arr = new Array(); //vararr = []
var arr = new Array(5); //数组定义并长度是5
var arr = new Array(5,6,7) //定义一个数组,元素是5,6,7
1.3.5 JS函数
函数:就是一个功能的封装体。先定义,后调用。
定义功能通常需要两个明确:
1、 功能的结果
2、 功能实现中的参与运算的位置的内容
JavaScript中定义函数的格式:通过指定的关键字来定义。
function 函数名(参数列表){
函数体;
return返回值;//如果没有具体的返回值,return语句可以省略不写
}
举例1:不带参数、不带返回值的函数
//定义函数
function demo(){
alert(“demorun”);
return;
}
demo(); //调用函数
举例2:带参数、带返回值的函数
//定义一个带参数的函数
function demo(x,y){
alert(arguments.length);
return x+y;
}
var sum = demo(4,5); // arguments.length=2
alert(“sum=”+sum); //9
var sumObj = demo;
alert(sumObj(4.5)); //9
函数细节1:
1、 只要使用了函数的名称,就是对这个函数的调用;
2、 函数中有一个数组在对传入的参数进行存储,这个数组就是argument
函数细节2:
function getSum(){
return100
}
//var sum = getSum(); //getSum函数运行,并将返回的结果赋值给sum
var sum = getSum; //getSum本身是一个函数名,而函数本身在js中就是一个对象,getsum就是这个函数对象的引用。相当于这个函数对象有两个函数名称。
alert(“sum=”+sum); //打印的时候如果sum指向的是函数对象,那么会将该函数对象的字符串表现形式打印出来。
举例3:js函数的其他表现形式
动态函数:使用的是js中内置的一个对象Function
只不过用的不是很多。
参数列表,函数体都是通过字符串动态指定的。
var add = new Fuction(“x,y”,”var sum; sum = x+y;return sum;”);
var he = add(4,8);
alert(“he=”+he);
对比:
function add2(){
varsum;
sum= x+y;
returnsum;
}
举例4:匿名函数
没有名字的函数,通常是函数的简写形式。
var sumObj = function(a,b){
return a+b;
}
alert(sumObj (7,8)); //15
等价于
function demo(x,y){
alert(arguments.length);
return x+y;
}
var sumObj = demo;
alert(sumObj(4.5)); //9
1.3.6 JS对象
1.3.6.1 Object对象
类似java
1.3.6.2 String对象
两种表现形式:
1、 var str = new String(“abc”);
2、 var str = “abc”;
String属性:length、prototype
既然trim方法是用来操作字符串的方法,可不可以像字符串已有?的方法一样,将该方法也定义到字符串对象中呢?直接用字符串对象调用就可以了。
prototype属性:原型,就是该对象的一个描述,该描述中如果添加了新功能,那么该对象都会具备这些新功能。而prototype就可以获取到这个原型对象。
alert(“ abc ”.trim()); //abc
1.3.6.3 Array对象
var arrObj = new Array();
var arrObj = new Array(size); //数组长度为size
var arrObj = new Array(element0,element1,…..); //创建时,带数组元素
var arr = [“asd”,”sdf”,”asdf”];
1.3.6.4 Date对象
1.3.6.4 with特有语句
为了简化对象调用内容的书写,可以使用js中的特有语句with来完成。
格式:
with(对象){
在该区域中可以直接使用指定的对象的内容,不需要写对象。
}
1.3.6.5 Math对象
1.3.6.6 Math对象
1.3.6.7 forin特有语句
格式:
for(变量 in 对象){ //对对象进行遍历的语句。
}
1.3.6.6 自定义对象
如果想要对自定义对象,应该先对对象进行描述。
js是基于对象,不是面向对象,不具备描述事物的能力。
就要县描述,在js中,可以用函数来模拟面向对象中的描述。
第一种定义方式
function Person(){ //相当于构造器
alert(“personrun”);
}
var p = new Person(); //通过描述进行对象的建立,new
//动态给p对象添加属性,直接使用p.属性名即可。
p.name = “zhangsan”
p.age = 29;
//如果定义的p对象的属性赋值为一个函数,即是给p对象添加一个方法。
p.show = function(){
alert(“showrun”+ this.name);
}
p.show();
var obj = new Object();
obj.name = “godfather”;
obj.age = “2012”;
第二种定义方式:更多的是描述事物
function Person(name,age){
//给Person对象添加了两个属性
this.name = name;
this.age = age;
this.setName=function(name){
this name = name;
}
this.getName=function(){
return this.name;
}
}
第三种定义方式:直接使用{}定义属性和值的键值对方式,键与值通过:连接,键与键之间用,隔开
var pp = {
//定义一些成员
“name”:”xiaoming”,
“age”:38,
“getName”:function(){
return this.name;
}
}
alert (pp[“age”]+”-”+pp.name); //两种调用成员方式:对象.属性名;对象[“属性名”]
for(x in p){
document.write(x+”:”+p[x]);
}
DOM
document object model(文档对象模型)
用来将标记型文档封装成对象,并将标记型文档中的所有内容(标签,文本,属性等)都封装成对象,封装成对象的目的是为了更方便的操作这些文档以及文档中的所有内容。
因为对象的出现就可以有属性和行为被调用。
文档:标记型文档;
对象:封装了属性和行为的实例,可以被直接调用。
模型:所有标记型文档都具备的一些共性特征的一个体现。标记型文档(标签,属性,标签中封装的数据)
只要是标记型文档,DOM这种技术都可以对其进行操作。
常见的标记型文档:html xml
1.1 DOM技术的解析方式
DOM解析方式的好处:可以对树中的节点进行任意操作,比如:增删改查。
弊端:这种解析需要将整个标记型文档加载进内存,意味着如果标记型文档的体积很大,较为浪费内存空间。
简介另一种解析方式:SAX:是一些组织定义的一种民间常用的解析方式,并不是w3c标准,而DOM是w3c标准。
SAX解析方式:基于事件驱动的解析,获取(查)数据的速度很快,但是不能对标记进行增删改动作。
DOM模型三种:
DOM level 1:将html文档封装成对象。
DOM level 2:在level 1基础上加入了新功能,比如解析名称空间。
DOM level 3:将xml文档封装成了对象。
1.2 DHTML:动态的HTML
不是一门语言,是多项技术综合体的简称。
其中包含了HTML/CSS/DOM/JavaScript。
这四个技术在动态html页面效果定义时,都处于什么样角色呢?
HTML:负责提供标签,对数据进行封装,目的是便于对该标签中的数据进行操作。
简单说:用标签封装数据
CSS:负责提供样式属性,对标签中的数据进行样式的定义。
简单说:对数据进行样式定义
DOM:负责将标记型文档进行解析,并封装成对象,在对象中定义了更多的属性和行为,便于对对象操作。
简单说:将文档和标签以及其他内容变成对象。
JavaScript:负责提供程序设计语言,对页面中的对象进行逻辑操作。
简单说:负责页面的行为定义,就是页面的动态效果。
所以说JavaScript是动态效果的主力编程语言。
DHTML+XMLhttpRequest = AJAX // XMLhttpRequest:和服务端通讯的对象
BOM:浏览器对象模型;这个模型方便与操作浏览器。
浏览器对应的对象就是Windows对象,这个可以通过查阅dhtmlapi获取。