Java知识总结


来源:
一、 java开发工具Editplus:Editplus与jdk的连接配置,如:

javac(编译)、java(运行)、javap(查看字节码)
a) 配置内容:
i. javac(编译):参数为 -d .  $(FileName);初始目录

$(FileDir)
ii. java(运行):参数为 $(CurSel).$(FileNameNoExt);初始

目录:$(FileDir)
iii. javap(查看字节码):参数为 $(FileNameNoExt);初始目录

:$(FileDir)
二、 java初始:
a) 通过HelloWorld类讲解了关键字、命名规范、修饰符;
pubic class HelloWorld{
    public static void main(String[] args){
       System.out.println("Hello World!");
    }
}
b) jdk与jre的区别;内容、范围///开发、运行//里面包含了各

种类库和工具、java程序的运行环境JVM
           jar;java下的压缩文件
           javac;编译
           javadoc;可形成帮助文档
     共有:java;运行
           native2ascii;本地码改成ASCII码
           javap;查看字节码文件
c) 字节码;是java跨平台的一个机制,是一段二进制代码,是一

种包含执行程序、
由一序列 op 代码(操作码)/数据对组成的二进制文件。字节码是

一种中间码,它比机器码更抽象,是包含一个执行程序的二进制

文件(.class)
数据单位的进制;K是千 M是兆 G是吉咖 T是太拉 8bit(位)

=1Byte(字节)
              1024Byte(字节)=1KB 1024KB=1MB 1024MB=1GB

1024GB=1TB
  java中,字节码是CPU构架(JVM)的具有可移植性的机器语

言。
d) 四个目标;
   1、java简介;历史和地位---跨平台纯面向对象的语言--第三

代语言:继承、封装、多态:方法同名,体不同
                      C++  ---  类函数
                      .NET---跨语言的平台
                      SQL--结构化查询语言--第四代语言
                      Lisp、Prolog人工智能语言---第五代语


      自身发展:95年后变成javaSE
      java体系:javase、javaee、javame
      特点:面向对象、平台无关、健壮性:无指针、内存的申

请与释放(内存分配)
   2、工作原理
        I java虚拟机
Java虚拟机(JVM)是以 字节码 为机器指令的系统,编译虚拟机

的指令集与编译微处理器的指令集非常类似。
Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个

垃圾回收堆和一个存储方法域。------堆,栈,本地方法栈,方

法区,pc寄存器
    .java---.class
        Ii 垃圾回收机制(GC);不再使用的内存空间应该回收起


    java 的垃圾回收机制:Java的垃圾回收机制是Java虚拟机提

供的能力,用于在空闲时间以不定时的方式动态回收无任何引用

的对象占据的内存空间。需要注意的是:垃圾回收回收的是无任

何引用的对象占据的内存空间而不是对象本身
         1.垃圾回收是由虚拟机自动执行,不能人为地干预。
         2.系统比较空闲(垃圾回收线程)执行
         3.对象不在被引用.对象处于引用的隔离岛状态(隔离

引用),对象具备了回收的条件
         4.gc()方法,可以建议虚拟机执行垃圾回收,但是不能

确定是否会执行回收。
   iii、开发环境搭建
tools:JCreator\Eclipse\MyEclipse\Jbuilder\NetBeans
   
iv、第一个java程序
        java源文件;.java
基本组成是class,只能有一个public类,命名与其一致
java运行(JVM): 类装载器、字节码校验、解释器
java中只有值传递
三、 数据类型与转换(标示符和关键字、常量与变量、基本数据

类型,自动转换,强制转换、转义字符、表达式)
a) 标示符:标示符的格式要求:
i. 定义:java对各种变量、方法和类等要素的命名时使用的字符

序列,均须遵守标示符的规则
ii. 规则:
1. 由字母、下划线_、美元符$、数字组成
2. 开头不能是数字
3. 大小写敏感,长度无限制(区别C)
4. 类名首字母一般要大写,方法名一般要小写,并且遵循骆驼命

名规则,如:ActiveDemo
b) 关键字
i. 定义:java中一些赋以特定的含义,用作专门用途的字符串
ii. 所有关键字都必须小写
iii. 常用的关键字用
1. 用于数据类型的:int、long、short、String、byte、char、

float、double、boolean
2. 用于流程控制的:if、else、for、switch、case、do、while

、break、continue
3. 访问控制符:public、protected、default、private
4. 用于异常的:try、catch、finally、throw、throws
5. 返回类型的:native、super、null、void、return、

synchronized(同步)
6. 实例:instanceof、this、new
7. 面向对象:class、extends、interface、abstract、final、

implements、import、package、static
8. goto和const用来破坏程序入口,也是关键字
c) 常量与变量
i. 常量:(public static final 常量名;)
1. 定义:始终不变的值,可以是数值、字符、字符串
2. 规则:习惯上命名时要大写
ii. 变量:(type varName  [=value];)
1. 注意:局部变量使用前必须先初始化不然编译失败!
iii. 调用格式:
1. 调用同文件中的其他类的变/常量格式为:对象.变量
2. 同类中调用其它函数的实例变/常量格式为:new 对象().变

量名
3. 同类中调用其它函数的类变/常量格式为: 类名.变量名
d) 数据类型
i. 基本数据类型:byte、short、int、long、char、float、

double、boolean
1. 默认值(范围是-2^(n-1)∽2^(n-1)-1)
a) Byte//1、short//2、int//4、long//8------默认值为0
b) char //2--------字符0-----范围是0~65535---unicode编码
c) float//4、double//8--------0.0
d) Boolean//2---------------false
ii. 引用数据类型:数组、类、接口
e) 自动转换(隐式转换)(由小转大)
i. 定义:自动类型转换,也称隐式类型转换,是指不需要书写代

码,由系统自动完成的类型转换
ii. 转换规则:byte?short(char)?int?long?float?double
iii. 示例代码:
1. int i = 4;
2. float n = i;
f) 强制转换(由大转小)
i. 转换规则:double→float→long→int→short(char)→byte
ii. 格式:(转换到的类型)需要转换的数值
iii. 示例代码:
1. double d = 3.10;
2. int n = (int)d;
iv. 注意:强制转换通常都会导致精度的损失
g) 转义字符
i. \b退格
ii. \n换行
iii. \r回车
iv. \’单引号
v. \”双引号
vi. \\反斜杠
h) 运算符------表达式
i. 定义:表达式是由数字、算符、数字分组符号(括号)、自由变

量和约束变量等以能求得数值的有意义排列方法所得的组合。约

束变量在表达式中已被指定数值,而自由变量则可以在表达式之

外另行指定数值
ii. 算术运算符:
1. 单目: ++(自加1)、--(自减1)、+(取正)、-(取负)
2. 双目: + 、- 、* 、/、 %
3. 三目:   ?:     如:a>b?a:b
iii. 关系运算符:-------返回结果true/false
1. 等于符号:==
2. 不等于符号:!=
3. 大于符号:>
4. 小于符号:<
5. 大于等于符号:>=
6. 小于等于符号:<=
iv. 逻辑运算符:------返回结果true/false
1. 与(&&):假短路
2. 或(||):真短路
3. 非(!):
v. 位运算符:-----将原数转化为二进制计算
1. 与(&):     如  1100&1010=1000
2. 或(|):     如  1100|1010=1110
3. 非(!): 如  !1100=0011
4. 异或(^): 如  1100^1010=0110
5. << 带符号左移 ------相当于乘以2
6. >>带符号右移 -------相当于除以2
7. >>> 无号右移
8. 异或的规律:
a) a ^ a = 0
b) a ^ b = b ^ a
c) a ^ b ^ c = a ^ (b ^ c) = (a ^ b) ^ c;
d) d = a ^ b ^ c 可以推出 a = d ^ b ^ c.
e) a ^ b ^ a = b
vi. 赋值运算符:
1. =、+=、-=、*=、/=、%=、&=、^=、|=、<<=、>>=
vii. Intanceof:----归属
1. 定义:为双目运算符,左边操作元是一个对象,右边是一个类

。当左边的对象是右边类的对象时,返回true
2. 格式:result = object instanceof class 如:a = b

instaceof B;//true
viii. 优先级:(从高到低、从左到右)
1. () []
2. ! +(正) -(负) ~ ++ --
3. * / %
4. +(加) -(减)
5. << >> >>>
6. < <= > >= instanceof
7. == !=
8. &(按位与)
9. ^(位异或)
10. |(位非)
11. &&
12. ||
13. ?:
14. = += -= *= /= %= &= |= ^= ~= <<= >>=>>>=
四、 流程控制语句(分支、循环)
a) If…else:    例1.1:
i. If(a>b){
ii.   System.out.println(a);
iii. }else if(b>c){
iv.   System.out.println(b);
v. }else{
vi.   System.out.println(b);
vii. }
b) 分支:(switch)
i. 格式:switch(条件语句){
case :
case :
…..
default :
}
ii. 例1.2:switch(month){
case 1:System.out.println(“spring”);break;
case 1:System.out.println(“spring”);break;
case 1:System.out.println(“spring”);break;
case 1:System.out.println(“spring”);break;
default: System.out.println(“spring”);break;//一定会执

行的语句
}
c) For循环  
i. 格式:For(初始化语句;条件语句;控制语句){
循环体;
}
ii. 例1.3:for(int i=1;i<101;i++){
   int sum = 0;
   sum += i;
}
d) while
i. 格式:while(条件语句){
//初始化语句;
循环体;
//控制语句;
}
ii. 例1.4:int i=1;
while(i<101){
  int sum=0;
  sum += i;
}
e) Do….while()
i. 格式: do{
循环体;
}while(条件语句);
ii. 例1.5:int i =1;
do{
int sum = 0;
 sum += i;
}while(i>101);
f) 增强型for循环----------主要用于打印数组元素
i. 格式:for(e:数组名){
循环体
}
ii. 例1.6:int[] a = new int[10];
                for(e:a){
  System.out.println(e);
}
五、 方法与递归
a) 方法---函数
i. 定义:一段用来完成特定功能的代码片段
ii. 声明格式:【修饰符】返回类型 方法名(形参列表){
方法体;
}
iii. 语法解释:
1. 形式参数:在方法被调用时用于接收外界输入的数据
2. 实参:调用方法时实际传给方法的数据
3. 返回值:方法在执行完毕后返回给调用它的环境的数据
4. 返回值类型:事先约定的返回值的数据类型,无返回值,必须

给出返回类型void
5. return语句中止方法的运行并指定要返回的数据
iv. 调用格式:
1. 静态方法(又称类方法)的调用:类名.方法名(实际参数)
2. 实例方法的调用:对象名.方法名(实际参数)
3. 调用中传递参数时,遵循的规则是:基本数据类型是该数据本

身,引用数据类型传递的是对象的引用(地址),不是对象本

身----基本数据类型:值传递;引用数据类型:地址传递。
v. 例1:
public class DemoMethod{
public static void main(String[] args){//静态方法(又称类

方法)的调用:类名.方法名(实际参数)
        show("i am a girl");
//实例方法的调用:对象名.方法名(实际参数)//如何产生对象

(Object),格式:new 构造方法()
        //和类同名的方法称为构造方法
//什么是构造方法(Constructor)?每个类都有一个和类名相同的

构造方法,且自动产生
      // new DemoMethod().display();
 new DemoMethod().visiable(12,"aaa",3.0f);
}
    //静态方法的定义【有关键字static修饰的方法】
public static void show(String s){//自定义方法
       System.out.println(s);
}
    //实例方法的定义【没有关键字static修饰的方法】
public int display(){System.out.println("welcome to

jiangxi");return (85);//返回结果,可以用括弧,也可以不用}
    //多个参数的实例方法
public void visiable(int x,String y,float f)

{System.out.println("=======================");}
}
b) 递归----------必须要有出口
i. 定义:递归用于让一个函数从其内部调用其自身
ii. 特点:
1. 程序代码简练,易于理解但浪费内存
2. 一定要有返回类型
3. 一定有if…….else……且if中有终止条件
六、 类(面向对象技术基础、类的声明与使用、对象的声明与使

用、构造方法)
a) 面向对象技术基础
i. 面向对象设计的方法论【OOA(分析)?OOD(设计)?OOP(编程

)?Test(测试)?部署】
ii. 面向对象(Object Oriented,OO)特点:
1. 对象唯一性:每个对象都有自身唯一的标识,通过这种标识,

可以找到相应的对象。在对象的整个生命期中,它的标志都是不

改变的,不同的对象不能有相同的标识(地址)。
2. 封装性(抽象性):把客观事物封装成抽象的类,并且类可以

把自己的数据和方法只让可信的类或者对象操作,对不可信的进

行信息隐藏。
3. 继承性:继承性是子类自动共享父类数据结构和方法的机制,

这是类之间的一种关系,java中的类只支持单继承,接口支持多

继承
4. 多态性(多形性):多态性是指相同的操作或方法、过程可作

用于多种类型的对象上并获得不同的结果。不同的对象,收到同

一消息可以产生不同的结果,这种现象称为多态性
5. 总结作用:封装可以隐藏实现细节,使得代码模块化;继承可

以扩展已存在的代码模块(类);它们的目的都是为了——代码

重用。而多态则是为了实现另一个目的——接口重用!多态的作

用,就是为了类在继承和派生的时候,保证使用“家谱”中任一

类的实例的某一属性时的正确调用。
iii. 面向对象(OO)基本特征
1. 封装(package)
2. 继承(inheritance)------关联关系
a) 继承(泛化generalize)
i. 实现继承
ii. 可视继承
b) 组合(聚合)
i. 接口继承
3. 多态(Polymorphism)
a) 重写(override)
i. 方法
ii. 接口(interface)
b) 重载(overload)
i. 同名函数
b) 类的声明和使用
i. 声明格式:
【修饰符】class【类名】{
方法体;
}
ii. 例1:
public static class Demo{
System.out.println();
}
c) 对象的声明与使用
i. 格式:类名 对象的引用变量 = new 类名();
ii. 例2:Demo d = new Demo();
d) 类与对象的比较
i. 类就是对象的模板,对象是类的实例
e) 构造方法
i. 定义:定义在类中,用来初始化对象的成员变量的方法,返回

的是内存地址
ii. 格式:
1. 【修饰符】方法名(){}
2. 例3:public Demo(){}
iii. 要求:
1. 与类同名;2、没有返回值(无void 的修饰);必须要先创建

对象,在对象上进行调用(new)
七、 UML
a) UML定义:(Unified Modeling Language)统一建模语言,一

种用于面向对象的软件工程的分析与设计阶段的一种可视化建模

语言
b) UML关系(类与类之间的关系):关联对属性,依赖对方法
i. 关联关系:菱形指向整体   has a
1. 关联关系------若在逻辑上A是B的“一部分”(a part of)

,则不允许B从A派生,而是要用A和其它东西组合出B
2. 聚合(aggregation)---实线空心菱形
3. 组合---整体与部分不可分开,实线实心菱形
ii. 泛化(Generalization)关系(继承):用实线空心三角形

指向父类    is a
1. 若在逻辑上B是A的“一种”,并且A的所有功能和属性对B而言

都有意义,则允许B继承A的功能和属性
iii. 实现关系(接口):虚线
iv. 依赖(Dependency)关系:  A”————>”B(A依赖于B)    

use a  虚线箭头
c) 修饰符图形
i. +  public -   private #   protected ~  默认访问
d) 建模图形(9种):
i. 用例图(Use Case Diagram):展示系统外部的各类执行者与

系统提供的各种用例之间的关系
ii. 类图(Class Diagram):展示系统中类的静态结构(类是指

具有相同属性和行为的对象),类图用来描述系统中各种类之间

的静态结构
iii. 对象图(Object Diagram):是类图中的一种实例化图(是

对类图的实例化)
iv. 顺序图(时序图)序列图(Sequence Diagram):展示对象

之间的一种动态协作关系(一组对象组成,随时间推移对象之间

交换消息的过程,突出时间关系)
v. 协作图(合作图)(Collaboration Diagram):从另一个角

度展示对象之间的动态协作关系(对象间动态协作关系,突出信

息收发关系)
vi. 状态图(Statechart Diagram):描述一类对象具有的所有

可能的状态及其转移关系(展示对象所具有的所有可能的状态以

及特定事件发生时状态的转移情况)
vii. 活动图(Activity Diagram):展示系统中各种活动的执行

流程(各种活动的执行顺序、执行流程)
viii. 构件图(Component Diagram):展示程序代码的物理结构

(描述程序代码的组织结构,各种构件之间的依赖关系)
ix. 部署图(Deployment Diagram):展示软件在硬件环境中(

特别是在分布式及网络环境中)的配置关系(系统中硬件和软件

的物理配置情况和系统体系结构)
八、 自定义类
a) 类的定义:类是具有相同属性和相同操作的对象集合,类是对

象的模板,一个类可以产生对个对象,产生单个对象的话就是单

例模式,类是对现实世界中实体的抽象,对象是对现实世界中实

体的实例
b) 类的组成:字段(成员变量)+方法+初始化块(静态初始化块

+对象初始化块)
c) 命名规则:类名的首字母大写;变量名和方法名(构造方法除

外)的首字母小写,采用骆驼名命名标识
d) 字段(实例变量+类变量(静态变量))的定义格式:
【修饰符(4p、static、final)】 数据类型 属性名【=默认值

】;
e) 方法的定义格式:【修饰符(4p、static、final、abstract

)】 返回值 方法名(【参数列表】){ 代码块;}
f) 初始化顺序:静态初始化块?类变量,实例变量初始化?对象初

始化块和成员变量初始化(在程序代码中的先后顺序来定)?构造

方法
g) JavaBean规范:
i. 必须是公共类,并将其访问属性设置为public,如:public

class Stu{}
ii. 必须有一个空的构造方法(public、无参):必须有一个不

带参数的公共构造器
iii. 字段(实例变量)要私有化,首字母要小写,用private修

饰 如:private int id;
iv. 字段应该通过一组存取方法(getter和setter)来访问,一

般是用Eclipse、JBuilder、IDE等工具生成getter和setter方法
v. setter和getter规范:字段首字母小写------如:
1. public class Demo{
a) private String name;
b) public Demo(){}
c) public Demo(){
System.out.println(“不错”);
d) }
e) public void setName(String name){
this.name = name;
f) }
g) public String getName(){
return name;
h) }
}
九、 数组(一维数组、二维数组、排序、Arrays.sort)
a) 一维数组
i. 定义:数组就是相同类型元素的集合
ii. 数组变量是引用类型,栈stack(FILO,自动回收)引用堆

heap(new出来的,树形结构,JVM回收)中的数据;
iii. 格式:int[] a = new int[3];
int[] a = {1,2,4};
iv. 使用for循环遍历输出,获得数组长度length,访问元素
For…each: 增强型for循环
for(String i:a){//增强型for循环System.out.println(i);}
//冒泡排序
public class SortTest {
 public void sort(int[] args){
    System.out.println("排序前 ");
for(int m : args){System.out.print(args[m]+",");}
  int time1 = 0,time2 = 0;
for(int i = 0 ; i < args.length-1 ; i++){for(int j = i+1

; j < args.length ; j++){int temp ;if(args[i] > args[j])

{temp = args[j];args[j] = args[i];args[i] = temp;}}}

System.out.println();System.out.println("排序后 ");for

(int n : args){System.out.print(n+",");}}public static

void main(String[] args) {int[] arg = new int[]

{2,1,4,5,8,7,6,3,9,0};new SortTest().sort(arg);}
}
b) 二维数组-----实质是一维数组引用另一维数组
i. 声明:Int[][] arr;//4个字节
ii. 创建时必须创建行,初始化就是对每个元素进行初始化,使

用增强型for循环
十、 Object类
a) Object类是所有类的超类;
b) 常用方法:HashCode()----哈希值,如:
i. IntegertoHexString(p1.hashCode());//把哈希码的无符号十

六进制转换成十进制
c) getClass()//获取运行时的类
d) toString()//返回字符,相当于getClass().getName()+”@”

+Integer.toHexString(HashCode());
e) clone()//创建一个与源对象完全相同的对象,但新对相象与

源对象不相等
i. 子类重写clone()要求:1、创建一个类A实现cloneable接口

;2、重写Object的clone(),调用super.clone()
ii. 代码实现:如
public class Person implements Cloneable{
int as ;
protected Object clone() throws

CloneNotSupportedException{Person p = (Person)

super.clone();
}
}
public class PersonDemo{public static void main()throws

CloneNotSupportedException{Person p = new Person

();p.as=11;System.out.println(“Before

clone”+p.as);Person p1 = (Person)p1.clone

();p1.as=22;System.out.println(“After clone”+p.as);}}
十一、 包装类(Integer)
a) 常用方法:
i. Integer.MAX_VALUE();//获取int的最大值
ii. Integer.MIN_VALUE();//获取int的最小值
iii. toBinaryString()//转二进制
iv. toHexStrng()//转十六进制
十二、 抽象类
a) 抽象类的特点:
i. 抽象方法一定在抽象类中;
ii. 抽象方法和抽象类都必须被abstract关键字修饰;
iii. 抽象类不可以用new创建对象,因为调用抽象方法没意义;
iv. 抽象类中的方法要被使用,必须由子类复写起所有的抽象方

法后,建立子类对象调用;
v. 如果子类只覆盖了部分抽象方法,那么子类还是一个抽象类
b) 格式:【访问控制符】class 类名{
属性;
访问控制符 返回类型 方法名(形参列表){
//方法体;【return 返回值】
}
访问控制符 abstract 返回类型 方法名(形参列表);
}
例:package b;
public class  AbstractDemo{
public static void main(String[] args){Chinese c = new

Chinese();}
}
abstract class Chinese{
public abstract void show();
}
abstract class D{
public void show(){System.out.println("213");}
}
十三、 接口(interface)--------不能实例对象,也就是不能

new接口
a) 定义:当抽象类中的方法都是抽象的,那么该类可以通过接口

的形式来表示
b) 格式:
1、 接口中常见定义:常量、抽象方法
2、 接口中的成员都有固定修饰符
常量:public static final
方法:public abstract
  接口中的成员都是public的
c) 接口不可以建立对象,需要被子类实现时,子类对接口中的抽

象方法都覆盖后,才可以实例化,否则子类就是一个抽象类
接口支持多实现implements,但接口不能实现接口,可以继承(

多继承)接口
d) 例子
public class InterfaceDemo{
public static void main(String[] args){SubInter si = new

SubInter();System.out.println(si.NUM);System.out.println

(SubInter.NUM);System.out.println(Inter.NUM);}
}
interface Inter{
public static final int NUM = 3;public abstract void

show();
}
class SubInter implements Inter{//实现接口
public void show(){}
}
十四、 单例设计模式
a) 定义:是对同一种问题的固定解决方式,单例就是只创建一个

对象
b) 想要保证对象唯一:1、为了避免其他程序过多建立该类对象

,先控制其他程序建立该类对象;2、为了让其他程序可以访问,

在本类中自定义该对象;3、为方便访问,提供访问方式
c) 使用场景:仅需要创建一个对象时
d) 定义步骤:
1、private 的构造方法
2、private static 的实例对象
3、public static外界访问方法
i. 代码实现:
1. 第一种:饿汉式-----先初始化
private int a;
private A(){};
private static A a = new A();
public static get(){
Return a;
}
2. 第二种:懒汉式----调用时初始化—延时加载
private int a;
private A(){};
private static A a = new A();
public static get(){
if(a==null){a == new A();
}
return a;
}
e) 好处:
i. 控制资源的使用
ii. 控制实例的产生数量
iii. 让多个不相关的两个线程或进程之间实现通信
十五、 package
a) 定义:就是把字段和方法包裹起来,并用一定的修饰符加以修

饰从而达到对外信息隐藏,并暴露可以暴露的方法
b) Java.lang.*;--------基础包,默认导入
c) 要求:1、必须放在非注释的第一行;2、包名通常是域名的倒

置,包名必须小写,不含关键字,不能以java、javax开头
d) 作用:1、便于管理;封装的需要;防止类名冲突
e) 包的导入用import关键字;
f) 常用包有; java.lang.annotation\java.net\java.nio

\java.sql\java.util\javax.sql\
javax.xml\javax.swing
十六、 继承(extends)-----类与类之间是属于关系-----关联

关系
a) 实现方式:继承(inheritance)和组合(composition)
i. 继承的实现方式有:实现继承、可视继承----------类与类之

间是继承(泛化)关系
1. 实现继承是指使用基类的属性和方法而无需额外编码的能力;
2. 可视继承是指子窗口(类)使用基窗口(类)的外观和实现代

码的能力;
ii. 组合(聚合关系):接口继承和纯虚类继承
1. 接口继承是指仅使用属性和方法的名称、但是子类必须提供实

现的能力。
b) 初始化顺序:先父类静态初始化块--》子类静态初始化块---

》父类的对象初始化块---》父类的构造方法--》子类的对象初始

化块---》子类的构造方法,如:
package a;
public class  B extends A{
static{System.out.println("-------------4

------------");}{System.out.println("-------------5

------------");}public B(){System.out.println

("-------------6------------");}public static void main

(String[] args){B b = new B();new B();}
}
class A{
static{System.out.println("-------------1

------------");}{System.out.println("-------------2

------------");}public A(){System.out.println

("-------------3------------");}
}
十七、 多态(向上转型)
a) 多态的坏处
i. 向上转型后,会丢掉子类的新方法
ii. 向上转型是安全的,但向下转型却是不安全的
iii. 例:
package a;
//向上转型------------打印的类型看右边
//缺点:损失掉了子类新增的方法、属性
public class A extends Super{
public void f(Super s){System.out.println(s);}public

static void main(String[] args) {//Super a = new A

();//a.A@82764b-----打印出A型变量//System.out.println

(a);/*A a = new A();a.f(a);//a.A@82764b-------向上转型

*///Super[] s = new Super[](new A(),new Super

());//System.out.println(a.length);Super[] s = new Super

[]{new A(),new Super()};System.out.println

(s.length);Object o = new int[3];int[] b = (int[])

o;System.out.println(b.length);//编译出错,损失掉了子类新

增的方法、属性}
}
class Super{}
b) 后期绑定
i. 将一个方法调用同一个方法主体关联起来被称为绑定。若在程

序执行前绑定,叫前期绑定,java中除了static和final方法,其

他所有的方法都是后期
ii. Overload-----前期绑定--------静态绑定------编译阶段
Override-----后期绑定--------动态绑定------运行阶段
例:Super a = new subclass();//向上转型-------overload看

左边,override看右边
c) 实现多态的方式
i. 重写override:指子类重新定义父类的方法的做法
ii. 重载(overload):是指允许存在多个同名函数,而这些函

数的参数表不同(或许参数个数不同,或许参数类型不同,顺序

或许两者都不同)
iii. 协变重写:子类方法可以比父类方法的返回类型更具体(子

类的返回类型是父类方法返回类型的子类)
d) 只有普通方法具有多态,final、static、private方法不具备

多态性
Field(域成员==字段)不具备多态性-----它们都是前期绑

定----同变量的声明类型绑定
c) 设计原则:
1、开闭原则---对扩展开放,对修改封闭,实现关键在于抽象化
2、里氏代换原则---面向基类原则---任何基类可以出现的地方,

子类一定可以出现
十八、 String(声明,创建,初始化,操作(比较equals/==,

转换,查找,截取,分割,拆分,替换,连接))
a) 在java中使用的是unicode码;字符串的内存空间大小跟它的

属性有关,String创建初始化时在JVM中数据流动,
b) 声明创建初始化
i. 格式:String 变量名 = 初始值;
ii. String 变量名 = new String(初始值);
c) 操作:
i. 比较(equals与==)
1. equals比的是内容,==比的是地址,equalsIgnoreCase()---忽

略大小写
2. 例1:String d = “123”;
  String d1 = new String(“123”);
  System.out.println(d.equals(d1)); //true
System.out.println(d==d1);//false
ii. charAt(int index)------返回指定索引处的char值
iii. length()--------返回字符串的长度
iv. 转换
1. toString()------返回本身
2. toLowerCase()---将所有字符串转换为小写
3. toUpperCase()---将所有字符串转换为大写
v. 查找
1. indexOf(String key)------从前查找返回的第一个key的索引
2. indexOf(String key,int formindex)----返回从指定位置开

始查找到的第一个key的索引
3. lastIndexOf()---------从后查找返回最后一个key的索引
vi. 截取
1. substring(int bindex,int eindex)----截取源字符串

(begin,end)并返回一个新String
vii. 拆分
1. split(String regex)-----根据regex将源字符串进行分割成

若干个新字符串
viii. 替换
1. replace(char oldchar,char newchar);
ix. 连接
1. + 或concat连接---在源字符串尾部连接新字符串,返回新字

符串
2. “a“+”b”;
x. 创建对象
1. String str1 = "abc";
  System.out.println(str1 == "abc");
步骤:
1) 栈中开辟一块空间存放引用str1,
2) String池中开辟一块空间,存放String常量"abc",
3) 引用str1指向池中String常量"abc",
4) str1所指代的地址即常量"abc"所在地址,输出为true
2. String str2 = new String("abc");
  System.out.println(str2 == "abc");
步骤:
1) 栈中开辟一块空间存放引用str2,
2) 堆中开辟一块空间存放一个新建的String对象"abc",
3) 引用str2指向堆中的新建的String对象"abc",
4) str2所指代的对象地址为堆中地址,而常量"abc"地址在池中

,输出为false
3. String str3 = new String("abc");
  System.out.println(str3 == str2);
步骤:
1) 栈中开辟一块空间存放引用str3,
2) 堆中开辟一块新空间存放另外一个(不同于str2所指)新建的

String对象,
3) 引用str3指向另外新建的那个String对象
4) str3和str2指向堆中不同的String对象,地址也不相同,输出

为false
4. String str4 = "a" + "b";
  System.out.println(str4 == "ab");
步骤:
1) 栈中开辟一块空间存放引用str4,
2) 根据编译器合并已知量的优化功能,池中开辟一块空间,存放

合并后的String常量"ab",
3) 引用str4指向池中常量"ab",
4) str4所指即池中常量"ab",输出为true
5. final String s = "a";
  String str5 = s + "b";
  System.out.println(str5 == "ab");
步骤:
同4
6. String s1 = "a";
  String s2 = "b";
  String str6 = s1 + s2;
  System.out.println(str6 == "ab");
步骤:
1) 栈中开辟一块中间存放引用s1,s1指向池中String常量"a",
2) 栈中开辟一块中间存放引用s2,s2指向池中String常量"b",
3) 栈中开辟一块中间存放引用str5,
4) s1 + s2通过StringBuilder的最后一步toString()方法还原一

个新的String对象"ab",因此堆中开辟一块空间存放此对象,
5) 引用str6指向堆中(s1 + s2)所还原的新String对象,
6) str6指向的对象在堆中,而常量"ab"在池中,输出为false
7. String str7 = "abc".substring(0, 2);
 
步骤:
1) 栈中开辟一块空间存放引用str7,
2) substring()方法还原一个新的String对象"ab"(不同于str6

所指),堆中开辟一块空间存放此对象,
3) 引用str7指向堆中的新String对象,
8. String str8 = "abc".toUpperCase();
  步骤:
1) 栈中开辟一块空间存放引用str6,
2) toUpperCase()方法还原一个新的String对象"ABC",池中并未

开辟新的空间存放String常量"ABC",
3) 引用str8指向堆中的新String对象
十九、 this
a) this是只指向当前对象的指针;
b) 使用:
i. 如果用在构造方法中,表示当前构造方法正在初始化的对象,

如:
1. Person p = new Person();
2. public Person(int id){
this.id = id;//相当于是p.id = id;
3. }
ii. 如果用在方法中,表示当前正在调用该方法的对象,如:
1. public show(int id){
this.id = id;//相当于是p.id = id;
2. }
------------p.show();
二十、 Static------数据共享
a) Static修饰符可以用于修饰类的成员变量和方法-----只在类

加载时加载一次
i. 修饰成员变量时,该变量成为类变量或静态变量,隶属于类,

类的所有对象共享同一个静态变量(生命周期长,类加载时确立

,保存在方法区中)
ii. 修饰方法时,该方法成为类方法或静态方法,可以直接用类

名.方法名()调用,也可以使用创建对象后通过对象引用名.方

法()调用
iii. 静态方法不能访问非静态方法:
1. 静态方法也称类方法,它在调用时直接使用类名.方法来调用

;非静态方法在调用时必须先创建对象,在对象上调用,格式为

:对象名.方法名();
2. 在静态方法被调用时可能没有实例对象,也就无法调用非静态

方法
二十一、 区别与联系:
a) break与continue与return
i. continue和break都可以结束本轮循环,但continue结束本轮

后继续下一轮循环,break则直接跳出循环
ii. break可以用在多重循环中用来跳出离它最近的循环,也可以

用在多分支语句swtich中用来跳出循环
iii. continue只能用在循环语句中,用于结束本轮循环,执行下

一次循环;
iv. continue与break之后的语句都不执行
v. return是终止方法并返回数据,在方法体内return后的语句都

不执行
b) 类变量(static)、实例变量、局部变量
i. 定义:类变量和实例变量定义在类中方法外,局部变量定义在

方法内、形参、代码块中
ii. 修饰符:类变量必须要用static修饰,实例变量不用static

修饰,类变量和实例变量可以不赋值,局部变量必须要先初始化
iii. 使用:类变量调用格式为:类名.变量名;实例变量调用时

必须要先创建实例对象,在该对象上调用(对象.变量名);局部

变量可以直接使用
iv. 加载:类变量(栈中)在类加载时加载,类结束时结束;实

例变量(堆中)在对象调用时加载,调用结束时结束;局部变量(

栈中)在方法开始调用时开始,方法结束时结束
c) this与super
i. 操作属性--------this.属性:表示调用本类中的属性,如果

本类中的属性不存在,则从父类开始查找;super.属性:表示调

用父类中的属性
ii. 操作方法--------this.方法():表示调用本类中的方法,

如果本类中的方法不存在,则从父类开始查找;super.方法()

:表示调用父类中的方法;
iii. 调用构造方法----this();调用本类中的其他构造方法,

super():表示调用父类的构造方法
iv. 查找范围---------this先从子类查找,如果没有从父类查找

,super不查子类直接查父类;
v. 特殊:this可以表示当前对象
d) String与StringBuffer、StringBuilder
i. String是不可变的对象,每次对String类型进行改变都相当于

产生了一个新的对象,StringBuffer是可变长度的字符序列,修

改后不会产生新对象
ii. StringBuffer的实质是它有容量这个属性,默认容量为16,

当初始化长度大于16时,其容量为初始化长度的2倍。
iii. String操作字符的方法有”+”、concat;StringBuffer操作

字符的方法有insert、append、delete(开始int,endint)
iv. 初始化格式:
1. String st = “234”; String s = new String();
2. StringBuffer sb = new StringBuffer();
v. StringBuffer与StringBuilder都是可变长度的字符序列,在

多线程中,前者是安全的,后者是不安全的
e) equals与==
i. 如果是基本类型比较,那么只能用==来比较,不能用equals;
ii. 对于基本类型的包装类型,比如Boolean、Character、Byte

、Short、Integer、Long、Float、Double等的引用变量,==是比

较地址的,而equals是比较内容的;
iii. 在String或重写equals方法的类中:equals是比内容,==是

比地址
iv. 在其他类中没有重写equals方法时,equals与==用法相同,

都是比地址
f) 重载与重写
i. 重载与重写都是类的多态表现形式,重载是一个类的多态表现

形式,重写是子类继承父类的多态表现形式,重载与重写都是针

对方法;
ii. 重载要求同名不同参数列表(类型、个数、顺序),与返回

类型无关,重写要求同名同参数列表(类型、个数、顺序),同

返回类型(协同----引用数据类型,是其子类或相同,基本数据

类型是相同),访问修饰符大于或等于父类,抛出异常要小于或

等于父类(当抛出的异常是RuntimeException时,则都可以编译通

过)
iii. 重载可以用在构造方法和普通方法中,重写只能用在普通方

法中
g) Integer与int
i. 类型:int是基本数据类型,Integer是引用数据类型;
ii. Integer是对int的包装,属于包装类;
iii. 默认值:int的默认值是0,Integer的默认值是null.
h) 类、抽象类、interface
1、抽象类需要有abstract修饰,类则不需要
2、抽象类中可以有普通方法和抽象方法,但普通类中只能有普通

方法
3、 抽象类和普通类都可以继承,但抽象类的子类必须重写其父

类的所有抽象方法,而普通类则不要求
4、抽象类不能被实例化,普通类可以被实例化
5、接口是抽象类的抽象,接口中只能有抽象方法和常量,接口支

持多继承,不含有构造方法和初始化块
i) final、finally与finalize
i. final用于声明属性方法和类,分别表示:属性不可变,方法

不可覆盖,类不可继承
ii. finally是异常处理语句的一部分,表示总是执行
iii. finalize是Object的一个方法,在垃圾收集器执行的时候会

调用被回收对象的此方法。
二十二、 不能共存的
a) super()与this():都必须放在方法的非注释第一行
b) final与abstract:一个最终的,一个是抽象的
c) abstract与private
 
 一、内部类(局部内部类、成员内部类、匿名内部类)

1、定义:内部类就是在类的内部定义一个类,它的分类有成员内

部类、局部内部类、匿名内部类,
它可以定义在类中方法外,也可以定义在类中方法内,内部类的

好处是可以访问外部类的私有成员,但外部类无法访问内部类的

私有成员
通过使用内部类可以确保程序的结构清晰和代码精炼

编译后的内部类名称:InnerTest$A.class

2、分类:成员内部类(静态成员内部类)、局部内部类、匿名内

部类
a、成员内部类(非静态内部类):与外部类的属性和方法并列,

成员内部类可以看作是外部类的实例变量
在内部类中访问实例变量:this.字段;
在内部类中访问外部类的实例变量:外部类名.this.字段
成员内部类中不能有静态字段或方法(final修饰的常量除外),

因为Static在加载时就创建,此时内部类可能还没被实例化
在外部类的外部实例化对象:
Foo foo = new Foo();
Koo koo = foo.new Koo();
Foo.Koo koo = new Foo().new Koo();

b、静态内部类
静态内部类可以直接访问外部类的静态成员,不能访问外部类的

实例成员,但可以通过外部类的实例(new 对象)来访问
静态内部类里面可以定义静态成员(其他内部类不可以)
静态内部类不可以使用private修饰
静态内部类的对象可以直接生成
Foo.Koo koo = new Foo().new Koo();
c、局部内部类
在方法中定义的内部类称为局部内部类,类似局部变量,不可以

加修饰符public、protected、private,其范围为定义它的代码


可以访问外部类的所有成员,还可以访问所在方法中的final修饰

的参数和变量,但不能访问方法体中的局部变量
d、匿名内部类
匿名内部类没有类名,它必须继承一个类或者实现一个接口,并

且不能显示的extends或implements关键字
匿名内部类不能有构造方法,因为它没有类名。可以通过new<父

类名>的方法创建实例对象,匿名类的创建与定义同时进行
匿名内部类只能一次性的创建其对象
匿名内部类既可以在方法体中,也可以在参数列表中
注意:匿名内部类一定是在new的后面隐含实现一个接口或继承一

个类,匿名内部类不是抽象类
      匿名内部类必须实现他的父类抽象接口或接口里的所有的

抽象方法
new 父类的构造器(实参列表)|实现接口(){
//类体
}
new Object(){
}

3、内部类的访问规则:内部类可以直接访问外部类中的成员,包

括私有
                    最近的外部类要访问内部类必须建立内部

类对象new Inner().fumction()来访问内部类中的成员
               如: Outer.Inner in = new Outer().new

Inner();
                    in.function();

4、使用:当描述事物时,事物的内部还有事物,该事物用内部类

来描述,因为内部事物在使用外部事物的内容。
内部类定义在局部时,不能使用成员修饰符、static修饰,使用

时需要new—
可以直接访问外部类中的成员,但不可访问它所在的局部中的变

量,只能访问被final修饰的局部变量

5、代码分析:例1:----分类
public class Demo2 {
class B{//成员内部类------Demo2$B.class
}
static class A{//静态成员内部类------Demo2$A.class
}
void show(){
class C{//局部内部类-------Demo2$1C.class
}
}
public static void main(String[] args) {
class C{//局部内部类----Demo2$2C.class
}
System.out.println();
}
}



例2:-----匿名内部类

1、  匿名内部类其实就是内部类的简写格式
2、  定义前题必须继承一个类或实现一个接口
3、  匿名内部类的格式: new 父类或接口(){定义子类的内容}
4、  匿名内部类定义的方法最好不要超过三个

public class Test{
       public static void main(String[] agrs){
              Test t=new Test();   //new了 一个Test对象
              t.te(new A(){                //调用实例方法

并且声明一个匿名内部类类作为一个参数传入
                            public void as(){
                                   System.out.println("我

是实现了接口A的匿名类");
                            }
                     }
              );
      }         
      void te(A a){    //实例方法
              a.as();
      }
}
interface A{    //声明了一个接口类
       void as();    //抽象方法
}

 

例3:
class A{
       void as(){
              System.out.println("我是内部类A");
       }
}
class B{
       void bs(){
              System.out.println("我是内部类B");
       }
}
public class MultipleExtends {
       private class C extends A{}
       private class D extends B{}
       public static void main(String[] args) {
              MultipleExtends m=new MultipleExtends(); //

声明一个外部类的对象
              MultipleExtends.C c=m.new C(); //让外部类对

象持有一个
              MultipleExtends.D d=m.new D();//内部类对象

的引用
              c.as();                                     

                                                          

                           
              d.bs();                                     

                                                          

                           
       }
}


例4:-----内部类是可以被私有的
public class MemberClass {
   private int i=10;  //定义一个私有字段
    private static int j=20;      
    public static void main(String[] args) {
MemberClass mc=new MemberClass();//new 一个外部类的对象
A a=mc.new A();//A a=new MemberClass().new A();//new 一个

内部类的对象
a.as();//调用内部类的实例方法
    }
private class A{
//static int j=6;
//int i=5;              //定义一个内部类的实例字段    
void as(){     //定义一个内部类的实例方法
System.out.println("这里是内部类A");   
System.out.println("调用外部类私有实例字段i:"+i);
System.out.print("调用外部类私有静态字段j:"+j);
}
}
}

//---------- java ----------
//这里是内部类A
//调用外部类私有实例字段i:10
//调用外部类私有静态字段j:20




例5:----静态内部类
public class StaticClass {         
       private static int i=10; //定义一个私有静态字段
       //private int j=7;
       public static void main(String[] args) {
              StaticClass sc=new StaticClass();//new 一个

外部类的对象
              A a=new StaticClass.A(); //new 一个静态内部


              a.as();            //调用静态内部类的实例方


              A.at        //调用静态内部类的静态方法
       }
       static class A{       
              int i=5;
              static at(){   //定义静态内部类的静态方法
                     System.out.println("这里是静态内部类

的静态方法");
              }
              void as(){                 //定义静态内部类

的实例方法
                     System.out.println("这里是内部类A");
                     System.out.print("调用外部类私有静态

字段i:"+i);
              }
       }
}

 
例6:------局部内部类
public class InteriorClass {
         private int i=5;
         public static void main(String[] args) {
                   InteriorClass ic=new InteriorClass();  

 //new 一个对象
                   ic.as();             //调用实例方法
                   //      B b=ic.new B();
         }
         void as(){
                   final int y=5;        //常量       
                   int u=1;            //局部变量
                   class B{
                            void bs(){
                                     System.out.println("

这里是内部类B");        
                                     System.out.println("

调用i"+i);
                                     System.out.println("

常量"+y);
                            }                          
                   }
                   new B().bs();
         }
}

---------------------------------------------------------

-------------|-------------------------------------------

---------------------------|
---------------------------------------------------------

-------------|-------------------------------------------

---------------------------|
---------------------------------------------------------

-------------|-------------------------------------------

---------------------------|

二、异常(try\catch\fainlly\throw\throws)
i、 异常的含义和分类
  a)含义:异常是对问题的描述,将问题进行问题的封装
  b)分类:java.lang.Object-----Throwable(java中所有错误和

异常的超类)-----Error(无法通过代码来处理的错误)        
                                            

|---------------Exception(可处理的异常,并能恢复运行)
     |---RuntimeException(运行时异常)---可以不捕获也可以

不处理
     |----CheckedException(已检查时异常)----必须捕获或处

理不然编译失败---IOException\SQLException
 标签(Marker)接口:既无字段又无方法---

Cloneable/Serializable/EventListener

 Error----如:JVM硬件错误----OutOfMemoryError—内存不足、

不断的创建实例、StackOverflowError---递归导致的堆异常
 
 2、异常分类(Throwable)
  1、编译时被检测的异常
     throws 需要处理
  2、编译时不被检测的异常---运行时异常(RuntimeException

或其子类)
    函数内throw,函数外不需要声明,--------无法处理,需要

修改代码

ii、 异常处理
a)RuntimeEception及其子类异常,不需要程序员处理,其后语句

不编译
b)非运行时异常必须处理
c)Exeception中有一个特殊的子类异常RuntimeException,如果

在方法内抛出该异常,方法上可以不用声明,编译可以通过;如果

在方法上声明了该异常,调用者可以不用处理,编译可以通过。

之所以不在函数声明,是因为不希望让使用者处理,当异常发生

时,希望程序停止,程序员修正程序代码

异常的捕获和处理

第一种格式:
try{
         //可能抛出异常的语句
}catch(异常类型 e){
         //处理语句1
} catch(异常类型 e){
         //处理语句2
}finally{
         //一定执行的语句
}

finally只要用于异常处理,修饰异常块,无论异常是否处理都会

执行
finally在return、throw前输出,不管return是在try还是catch


finally定义一定执行的代码,通常用于关闭资源------如:数据

库关闭连接

finally块在以下情况将不会被执行:
(1)finally块中发生了异常;
(2)程序所在线程死亡;
(3)在前面的代码中用了System.exit(0);
(4)关闭CPU。

第二种格式:
try{

}finally{

}

第三种格式:
try{

}catch(){

}

 
iii.在多个catch时只执行一个,自上而下遇到的第一个异常所对

应的catch,如果没有对应的catch,则先执
行finally后在抛出,没有finally则直接抛出,定义多个catch可

精确地定位异常。如果为子类的异常定
义了特殊的catch块,而父类的异常则放在另外一个catch块中,

此时,必须满足以下规则:子类异常的处
理块必须在父类异常处理块的前面,否则会发生编译错误。所以

,越特殊的异常越在前面处理,越普遍的
异常越在后面处理。这类似于制订防火墙的规则次序:较特殊的

规则在前,较普通的规则在后。

throws--------声明方法抛出异常
1、说明:当不知道在当前代码中如何处理的时候,可以选择用

throws将异常交给上层调用者处理
2、基本格式:
类型 方法名(形参列表)throws 异常列表(逗号隔开){
          //代码
}

例:
//手工抛出异常实例
public class JavaThrow1{
         public static void main(String[] args){
                   System.out.print(" Now");
                   try{
                            System.out.print(" is");
                            throw new

NullPointerException();//直接抛出异常转到catch进行处理
                            //System.out.println("This

will not excute!");//有throw这句执行不到
                   }catch (NullPointerException e){
                            System.out.print(" the");
                   }
                   System.out.print(" time.\n");
         }
}

//自动抛异常
public class ExTest {
public static void main(String[] args){
String s=null;
try{
System.out.println("0");
int i=s.length();//自动抛异常--空指针异常
System.out.println("2");
}finally{
System.out.println("1");
}
}
}

例:--------throws
public class ExceptionTest4{
public static void p() throws ArithmeticException{
//间接抛出异常,自己并未处理,让方法的调用者来处理
int i;
i=4/0;//可能发生异常
System.out.println("8");
}
  public static void main(String[] args){    
try{
try{
                p();//方法的直接调用调用者捕获异常处理
}catch(ArithmeticException e){
System.out.println("Divider is zero !");
}
}catch(RuntimeException  e){
              System.out.println("4");
}
  }
}

v.java异常处理机制

答:程序出现想数组角标越界,空指针等错误时,JAVA就会用异

常Throwable
来描述这些错误,Throwable继承了Object类,同时实现了

Serializable接口,
根据出现的问题是否可以通过程序来解决。把Throwable分为

Error错误和Exception异常,Exception根据编译时是否会被检
测分为运行时异常RuntimeException和已检测异常

CheckedException。异常的处理方
式有两种,在发生异常的地方直接使用catch处理,或者将异常抛

出给调用者,让调用者来处理。
 
 1、检查性异常------程序正确,但因为外在的环境条件不满足

引发。例如:用
户错误及I/O问题----程序试图打开一个并不存在的远程Socket端

口。这不是程序
本身的逻辑错误,而很可能是远程机器名字错误(用户拼写错误)

。对商用软件系统,
程序开发者必须考虑并处理这个问题。JAVA编译器强制要求处理

这类异常,如果不
捕获这类异常,程序将不能被编译。
  2、运行期异常------这意味着程序存在bug,如数组越界,0

被除,入参不满足规
范.....这类异常需要更改程序来避免,JAVA编译器强制要求处理

这类异常。
  3、错误------一般很少见,也很难通过程序解决。它可能源

于程序的bug,但一般
更可能源于环境问题,如内存耗尽。错误在程序中无须处理,而

有运行环境处理。


三、 自定义异常
当jdk内置异常类型不能满足系统需求时,我们需要自定义异常,

如:
public class MyExceptionTest {
         public static void main(String[] args) {
                  MyExceptionTest mt = new

MyExceptionTest();
                  mt.manager();
         }

         public void registe(int num) throws MyException{
                  if(num<0){
                           throw new MyException("人数为

负数",3);
                  }
                  System.out.println(" 登记人数

为:"+num);
         }

         public void manager(){
                  try{
                           registe(-100);
                  }catch (MyException e){
                           System.out.println("登记类型出

错:"+e.getId());
                           e.printStackTrace();
                  }       
                  System.out.println(" 操作结束!");
         }
}
class MyException extends Exception{
         private int id;
         public MyException(){}
         public MyException(String message,int id){
                  super(message);//调用父类的getMessage()
                  //父类中已经定义了getMessage()可以直接

使用-----------该方法为Exception继承Throwable的
                  this.id=id;
         }
         public int getId(){
                  return id;
         }
}

自定义异常类必须要继承Exception/RuntimeException,如果该异

常的发生无法再继续进行运算,就让它继承RuntimeException
继承的原因是为了让该类自定义类具备可抛型,让该类具备操作

异常的共性方法
自定义异常:按照JAVA的OO思想,将程序中出现的特有问题进行

封装

四、常见异常
IOException--------------------输入输出异常
ClassNotFoundException-------找不到类异常
NumberFormatException---------字符串到数字格式的异常
FileNotfoundException-----------文件找不到异常
NoSuchMethodException---------------请求方法异常

运行时异常:RuntimeException
SecurityException-----------试图违反安全性异常
NullPointerException----没有实例化却调用其属性和方

法--------------空指针异常
ArrayIndexOfBoundsException---------数组越界异常
StringIndexOfBoundsException---------字符串越界异常
ArithmeticException--------------算数异常/除数为零异常
NullPointerException-------试图查找null异常


Main方法通常情况下不能把异常抛给JVM

Super a = new subclass();//向上转型----
---overload看左边,override看右边
-----------------------------------多态针对的是方法
 

异常的好处:1、将问题进行封装
            2、将正常流程代码和问题代码进行分离,方便阅读

处理原则:
1、处理方式有:try或者throws
2、调用到抛出异常的功能时,抛出几个处理几个(一个try对应

多个catch)
3、多个catch,父类的catch放到最后
4、Catch内,需要定义针对性的处理方式,不要简单的定义

printStackTrace输出语句,也不要不写
5、当铺获到的异常,本功能处理不了时,可以继续在catch中抛



6、  例:
try{
throw new AException();
}catch(AException e){
throw e;
}

7、如果异常在内部被处理(catch),外部则不需要抛出

基本格式:catch用来处理异常,如果该异常为检测时异常时,必

须要处理或者抛出
异常继承时,子类只能抛出父类的异常或者该异常的子类/子集异

常,也可以不抛出异常

异常的注意事项
1、在子父类覆盖时,
a)子类抛出的异常必须是父类异常的子类或子集
b)如果父类或接口没有异常抛出时,子类覆盖出现异常,只能try

不能抛
c)如果父类中是RuntimeException时,子类可以不用抛出异常,

反之,子类为RuntimeException异常,父类为其异常的子类或自

己都可以编译通过

1、throw 与throws
throw 后跟异常对象(只能有一个),throws后跟异常类(多个

时用逗号隔开);
位置:throw用在方法体中,代表手工抛异常,throws用在方法声

明上,代表该方法可能发生异常

2、RuntimeException和CheckedException的区别
前者可以不在方法上声明也可以不处理,后者必须要处理或者抛



---------------------------------------------------------

-------------|-------------------------------------------

---------------------------|
---------------------------------------------------------

-------------|-------------------------------------------

---------------------------|
---------------------------------------------------------

-------------|-------------------------------------------

---------------------------|
                                                          

                                                          

                                                          

                                                          

                                                          

                                                          

                                                         
三、集合(collection、set、list、map)

一、定义:
集合是Java里面最常用的,也是最重要的一部分。能够用好集合

和理解好集合对于做Java程序的开发拥有无比的好处。
容器:用来存储数据,不同的容器集合以不同的格式保存对象,

它能够自动的改变这个容器的所能存放的数据数量的大小。这一

点上,如果使用数组来存储的话,就显得十分的笨拙。
对于对象集合,必须执行的操作主要以下三种:
?       添加新的对象
?       删除对象
?       查找对象
Java容器类类库的用途是“保存对象”,并将其划分为两个不同

的概念:
1)  Collection 。 一组对立的元素,通常这些元素都服从某种

规则。List必须保持元素特定的顺序,而Set 不能有重复元素。
2)  Map 。 一组 成对的“键值对”对象。

? Collection – 对象之间没有指定的顺序,允许重复元素。
? Set –  对象之间没有指定的顺序,不允许重复元素
? List–  对象之间有指定的顺序,允许重复元素,并引入位置下

标。
? Map –  接口用于保存关键字(Key)和数值(Value)的集合

,集合中的每个对象加入时都提供数值和关键字。Map 接口既不

继承 Set 也不继承 Collection。
List、Set、Map共同的实现基础是Object数组


Collection
1.2.1常用方法
Collection 接口用于表示任何对象或元素组。想要尽可能以常规

方式处理一组元素时,就使用这一接口。Collection 在前面的大

图也可以看出,它是List和Set 的父类。并且它本身也是一个接

口。它定义了作为集合所应该拥有的一些方法。如下:
注意:
集合必须只有对象,集合中的元素不能是基本数据类型。
Collection接口支持如添加和除去等基本操作。设法除去一个元

素时,如果这个元素存在,除去的仅仅是集合中此元素的一个实

例。
?     boolean add(Object element)
?     boolean remove(Object element)
Collection 接口还支持查询操作:
?     int size()
?     boolean isEmpty()
?     boolean contains(Object element)
?     Iterator iterator()
组操作 :Collection 接口支持的其它操作,要么是作用于元素

组的任务,要么是同时作用于整个集合的任务。
?     boolean containsAll(Collection collection)
?     boolean addAll(Collection collection)
?     void clear()
?     void removeAll(Collection collection)
?     void retainAll(Collection collection)
containsAll() 方法允许您查找当前集合是否包含了另一个集合

的所有元素,即另一个集合是否是当前集合的子集。其余方法是

可选的,因为特定的集合可能不支持集合更改。 addAll() 方法

确保另一个集合中的所有元素都被添加到当前的集合中,通常称

为并。 clear() 方法从当前集合中除去所有元素。 removeAll()

方法类似于 clear() ,但只除去了元素的一个子集。

retainAll() 方法类似于 removeAll() 方法,不过可能感到它所

做的与前面正好相反:它从当前集合中除去不属于另一个集合的

元素,即交。
 
集合类的基本方法的使用:
import java.util.*;
public class CollectionToArray {
public static void main(String[] args) {
Collection collection1=new ArrayList();//创建一个集合对象
collection1.add("000");//添加对象到Collection集合中
collection1.add("111");
collection1.add("222");
System.out.println("集合collection1的大

小:"+collection1.size());
System.out.println("集合collection1的内

容:"+collection1);
collection1.remove("000");//从集合collection1中移除掉

"000" 这个对象
System.out.println("集合collection1移除 000 后的内

容:"+collection1);
System.out.println("集合collection1中是否包含000

:"+collection1.contains("000"));
System.out.println("集合collection1中是否包含111

:"+collection1.contains("111"));
Collection collection2=new ArrayList();
collection2.addAll(collection1);//将collection1 集合中的

元素全部都加到collection2中
System.out.println("集合collection2的内

容:"+collection2);
collection2.clear();//清空集合 collection1 中的元素
System.out.println("集合collection2是否为空

:"+collection2.isEmpty());
//将集合collection1转化为数组
Object s[]= collection1.toArray();
for(int i=0;i System.out.println(s[i]);
}
}
}
运行结果为:
集合collection1的大小:3
集合collection1的内容:[000, 111, 222]
集合collection1移除 000 后的内容:[111, 222]
集合collection1中是否包含000 :false
集合collection1中是否包含111 :true
集合collection2的内容:[111, 222]
集合collection2是否为空 :true
111
222
这里需要注意的是,Collection 它仅仅只是一个接口,而真正使

用的时候,却是创建该接口的一个实现类。作为集合的接口,它

定义了所有属于集合的类所都应该具有的一些方法。
而ArrayList (列表)类是集合类的一种实现方式。
 
Collection的实现基础是数组,所以有转换为Object数组的方法


?     Object[] toArray()
?     Object[] toArray(Object[] a)
其中第二个方法Object[] toArray(Object[] a) 的参数 a 应该

是集合中所有存放的对象的类的父类

1.2.2  迭代器(Iterator)
迭代器(Iterator)本身就是一个对象,它的工作就是遍历并选

择集合序列中的对象,而客户端的程序员不必知道或关心该序列

底层的结构。此外,迭代器通常被称为“轻量级”对象,创建它

的代价小。但是,它也有一些限制,例如,某些迭代器只能单向

移动。
Collection 接口的 iterator() 方法返回一个 Iterator。

Iterator 和Enumeration 接口类似。使用 Iterator 接口方法,

可以从头至尾遍历集合,并安全的从底层 Collection 中除去元

素。
迭代器的使用:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
 
public class IteratorDemo {
public static void main(String[] args) {
Collection collection = new ArrayList();
collection.add("s1");
collection.add("s2");
collection.add("s3");
Iterator iterator = collection.iterator();//得到一个迭代


while (iterator.hasNext()) {//遍历
Object element = iterator.next();
System.out.println("iterator = " + element);
}
if(collection.isEmpty())
System.out.println("collection is Empty!");
else
System.out.println("collection is not Empty!

size="+collection.size());
Iterator iterator2 = collection.iterator();
while (iterator2.hasNext()) {//移除元素
Object element = iterator2.next();
System.out.println("remove: "+element);
iterator2.remove();
}
Iterator iterator3 = collection.iterator();
if (!iterator3.hasNext()) {//察看是否还有元素
System.out.println("还有元素");
}
if(collection.isEmpty())
System.out.println("collection is Empty!");
//使用collection.isEmpty()方法来判断
}
}
程序的运行结果为:
iterator = s1
iterator = s2
iterator = s3
collection is not Empty! size=3
remove: s1
remove: s2
remove: s3
还有元素
collection is Empty!
可以看到,Java的Collection的Iterator 能够用来,:
1)使用方法 iterator() 要求容器返回一个Iterator .第一次调

用Iterator 的next() 方法时,它返回集合序列的第一个元素。
2)使用next() 获得集合序列的中的下一个元素。
3)使用hasNext()检查序列中是否元素。
4)使用remove()将迭代器新返回的元素删除。
需要注意的是:方法删除由next方法返回的最后一个元素,在每

次调用next时,remove方法只能被调用一次 。

1.3 List
1.3.1概述
Collection接口实际上并没有直接的实现类。而List是容器的一

种,表示列表的意思。当我们不知道存储的数据有多少的情况,
我们就可以使用List 来完成存储数据的工作。例如保存一个应用

系统当前的在线用户的信息。List的最大的特点就是能够自动
的根据插入的数据量来动态改变容器的大小。

1.3.2  常用方法
List 就是列表的意思,它是Collection 的一种,即继承了

Collection 接口,又定义一个允许重复项的有序集合。该接口不


能够对列表的一部分进行处理,还添加了面向位置的操作。List

是按对象的进入顺序进行保存对象,而不做排序或编辑操作。它
除了拥有Collection接口的所有的方法外还拥有一些其他的方法

。面向位置的操作包括插入某个元素或 Collection 的功能,还
包括获取、除去或更改元素的功能。在 List 中搜索元素可以从

列表的头部或尾部开始,如果找到元素,还将报告元素所在的位

置。

1、 void add(int index, Object element):添加对象element

到位置index上
2、 boolean addAll(int index, Collection collection):在

index位置后添加容器collection中所有的元素
3、 Object get(int index) :取出下标为index的位置的元素
4、 int indexOf(Object element) :查找对象element 在List

中第一次出现的位置
5、 int lastIndexOf(Object element) :查找对象element 在

List中最后出现的位置
6、 Object remove(int index) :删除index位置上的元素
7、 Object set(int index, Object element) :将index位置上

的对象替换为element 并返回老的元素。

List(提供基于索引的对成员的随机访问)------ArrayList-----

提供快速的基于索引的成员访问,对尾部成员的增加和删除支持

较好
  成员可为任意Object子类的对象
----------LinkedList-----对列表中任何位置的成员的增加和删

除支持较好,但对基于索引的成员访问支持性能较差
  成员可为任意Object子类的对象
         
在“集合框架”中有两种常规的 List 实现:ArrayList 和

LinkedList。使用两种 List 实现的哪一种取决于您特定的需要

。如果要
支持随机访问,而不必在除尾部的任何位置插入或除去元素,那

么,ArrayList 提供了可选的集合。但如果,您要频繁的从列表

的中间
位置添加和除去元素,而只要顺序的访问列表元素,那么,

LinkedList 实现更好。

LinkedList 来实现一个简单的队列的例子:
import java.util.*;
 
public class ListExample {
  public static void main(String args[]) {
    LinkedList queue = new LinkedList();
    queue.addFirst("Bernadine");
    queue.addFirst("Elizabeth");
    queue.addFirst("Gene");
    queue.addFirst("Elizabeth");
    queue.addFirst("Clara");
    System.out.println(queue);
    queue.removeLast();
    queue.removeLast();
    System.out.println(queue);
  }
}
运行程序产生了以下输出。请注意,与 Set 不同的是 List 允许

重复。
[Clara, Elizabeth, Gene, Elizabeth, Bernadine]
[Clara, Elizabeth, Gene]
该的程序演示了具体 List 类的使用。第一部分,创建一个由

ArrayList 支持的 List。填充完列表以后,特定条目就得到了。

示例
的 LinkedList 部分把 LinkedList 当作一个队列,从队列头部

添加东西,从尾部除去。

List 接口不但以位置友好的方式遍历整个列表,还能处理集合的

子集:
ListIterator listIterator() :返回一个ListIterator 跌代器

,默认开始位置为0
ListIterator listIterator(int startIndex) :返回一个

ListIterator 跌代器,开始位置为startIndex
List subList(int fromIndex, int toIndex) :返回一个子列表

List ,元素存放为从 fromIndex 到toIndex之前的一个元素。
处理 subList() 时,位于 fromIndex 的元素在子列表中,而位

于 toIndex 的元素则不是,提醒这一点很重要。

for-loop :
for (int i=fromIndex; i   // process element at position i
}

对子列表的更改(如 add()、remove() 和 set() 调用)对底层

List 也有影响。


我们看一个List的例子:
import java.util.*;
 
public class ListIteratorTest {
public static void main(String[] args) {
List list = new ArrayList();
list.add("aaa");
list.add("bbb");
list.add("ccc");
list.add("ddd");
System.out.println("下标0开始:"+list.listIterator

(0).next());//next()
System.out.println("下标1开始:"+list.listIterator

(1).next());
System.out.println("子List 1-3:"+list.subList(1,3));//子

列表
ListIterator it = list.listIterator();//默认从下标0开始
//隐式光标属性add操作 ,插入到当前的下标的前面
it.add("sss");
while(it.hasNext()){
System.out.println("next Index="+it.nextIndex

()+",Object="+it.next());
}
//set属性
ListIterator it1 = list.listIterator();
it1.next();
it1.set("ooo");
ListIterator it2 = list.listIterator(list.size());//下标
while(it2.hasPrevious()){
System.out.println("previous Index="+it2.previousIndex

()+",Object="+it2.previous());
}
}
}
程序的执行结果为:
下标0开始:aaa
下标1开始:bbb
子List 1-3:[bbb, ccc]
next Index=1,Object=aaa
next Index=2,Object=bbb
next Index=3,Object=ccc
next Index=4,Object=ddd
previous Index=4,Object=ddd
previous Index=3,Object=ccc
previous Index=2,Object=bbb
previous Index=1,Object=aaa
previous Index=0,Object=ooo
我们还需要稍微再解释一下 add() 操作。添加一个元素会导致新

元素立刻被添加到隐式光标的前面。因此,添加元素后调用
previous() 会返回新元素,而调用 next() 则不起作用,返回添

加操作之前的下一个元素。下标的显示方式,如下图所示:

1.3.3实现原理
ArrayList中主要包含2个属性:
private transient Object elementData[];
private int size;
其中数组::elementData[] 是列表的实现核心属性:数组。 我

们使用该数组来进行存放集合中的数据。而我们的初始化参数就
是该数组构建时候的长度,即该数组的length属性就是

initialCapacity 参数。

Keys:transient 表示被修饰的属性不是对象持久状态的一部分

,不会自动的序列化。

如果要判断一个类的一个实例对象是否等于另外一个对象,那么

我们就需要自己覆写Object类的public boolean equals(Object

obj)
 方法。如果不覆写该方法的话,那么就会调用Object的equals()

方法来进行判断。这就相当于比较两个对象的内存应用地址是否

相等了。
在集合框架中,不仅仅是List,所有的集合类,如果需要判断里

面是否存放了的某个对象,都是调用该对象的equals()方法来进

行处理的。

集合的个数用size();数组用length;String用length();

Collection extends Iterable

方法:
增          add();addAll()---------boolean
删          remove();removeAll();------------boolean
                 clear()-------void
查          Iterator()--------Iterator
改          toArray()-----Object   数组
元素数      size()--------------int

List  extends Collection----------有序的Collection,

可重复

新增方法:
add(int index, E element)//在指定位置添加---------添加顺

序要是连续的
get(int index)//返回指定位置
listIterator(int index)//从指定位置开始迭代

AbstractList extends AbstractCollection implements

List

Set
无序的不可重复的Collection

Map
键K不可以重复,值V可以重复

ArrayList------------在查询时快,增删改时慢

例:
import java.util.*;
//注解
//@SuperessWarnings("unchecked")---------

public class Demo{
public static void main(String[] args) {
List alist = new ArrayList();//List是接口

,不能被实例化

//增加
alist.add("123");
alist.add(new StringBuffer("1s1"));
alist.add(3.4f);
alist.add(3.01d);
alist.add(1,222);//[123, 222, 323]

alist.add("123");//[123, 222, 323, 123]----------可重复
System.out.println(alist);//相当于toString()
System.out.println("长度为:"+alist.size());
System.out.println("------------------------------");
//删除
alist.remove(2);//角标
System.out.println(alist);
//alist.clear();
alist.remove("123");//移除的是第一次出现的
System.out.println(alist);
System.out.println(alist.isEmpty());
System.out.println("------------------------------");
//遍历
//第一种:
for(int i=0;i Object e = alist.get(i);
if(e instanceof String){//Object inteanceof 类型----判断

类型是否是Object的实例
System.out.println(((String)e).length());
}else if(e instanceof Double){
System.out.println(((Double)e).intValue());
}
}

//第二种:
for(Object e:alist){
System.out.println(e);
}
System.out.println("------------------------------");
//List alist1 = new ArrayList();
int size = alist.size();
System.out.println(" size="+size);
boolean flag = alist.isEmpty();//判断是否为空
System.out.println(" flag="+flag);
System.out.println("------------------------------");
//第三种:Iterable-----迭代器输出
//Iterable Iteratoriterator();
Iterator it = alist.iterator();//Iterator与

Iterable无关,是两个接口
while(it.hasNext()){
Object i = it.next();
System.out.println(i);
}
//System.out.println(alist.iterator());
System.out.println("--------------------------------");
//第一种:
for(int i=0;i

System.out.print(alist.get(i)+",");//按照下标获取
}
System.out.println(" ");
System.out.println("--------------------------------");
//第四种:
for(Iterator it2 = alist.iterator();it2.hasNext();){
System.out.println(it2.next());
}
//转换
//alist.toArray();
//System.out.println(alist);

}
}


LinkedList-----------增删改快,查询慢
例:
import java.util.*;
public class  Demo1{
public static void main(String[] args) {
Queue link = new LinkedList();
//Queue是单端队列----------单链表
link.add(21);
link.offer(111);//队尾添加========>add
link.poll();//队头删除
System.out.println(link.remove());
link.poll();//为空时返回null==========>remove
System.out.println(link.poll());
link.peek();//访问=========>get
//link.remove();为空时异常
System.out.println(link.size());
System.out.println

("-------------------------------------");

Deque dl = new LinkedList();
//Deque是双端队列--------双向链表
---------------------------------------------------------

----------------------
第一个元素(头部)             最后一个元素(尾部)

               抛出异常     特殊值          抛出异常      

 特殊值

插入 addFirst(e)   offerFirst(e)   addLast(e)     

offerLast(e)
移除 removeFirst() pollFirst()     removeLast()   

pollLast()
检查 getFirst()    peekFirst()     getLast()      

peekLast()
---------------------------------------------------------

----------------------
//add、offer默认在尾部增加
//remove、poll默认从第一个开始删除

dl.add(123);//默认在尾部增加
dl.addFirst("sss");
dl.offerFirst(231);
dl.addLast(2212);
dl.offerLast(654);
System.out.println(dl);

System.out.println("-------------------1

---------------");
//dl.removeFirst();
//System.out.println(dl);
//System.out.println("------------------2

----------------");
dl.pollLast();
System.out.println(dl);
System.out.println("-----------------3

-----------------");

        System.out.println(dl.getFirst());

System.out.println("-----------------4

-----------------");
dl.peek();
System.out.println(dl);
}
}


注意:所有的集合框架都位于java.util包中,使用前必须导入该

包中的类
熟悉并记忆以下接口之间的关系和相关方法
Iterable--------->接口(java.lang)
        常见方法1:Iterator iterator()
 Iterator--------->接口
        常见方法1:boolean hasNext()
        常见方法2:E   next()
 Collection------->Iterable-------------->接口
         常见方法1:int size()
         常见方法2:boolean isEmpty()
 常见方法3:void clear()
         常见方法4:boolean  add(E e)
 常见方法5:remove()
 List(线性表)----->Collection-------

>Iterable-------------->接口
         常见方法1:add(int index,E e)
 常见方法2:remove(int index,E e)
   常见方法3:E get(int index)
 Queue(队列)----->Collection-------

>Iterable-------------->接口
         常见方法1:offer(E e)  
 常见方法2:poll()
   常见方法3:E peek()
 Deque(双端队列)----->Queue----->Collection-------

>Iterable-------------->接口
         常见方法1:offerFirst(E e)和offerLast(E e)
 常见方法2:pollFirst()和pollLast
   常见方法3:E peekFirst()和peekLast
ArrayList-->AbstractList-->List--->Collection---

>Iterator--------->类
LinkedList--->AbstractList-->List--->Collection---

>Iterator--------->类
                    --->Deque---->Queue----->
Vector--->AbstractList-->List--->Collection---

>Iterator--------->类
Stack-->Vector--->AbstractList-->List--->Collection---

>Iterator--------->类
         常见方法1:E pop()
 常见方法2:E push(E e)
 常见方法3:E peek()
   常见方法4:boolean empty()
stack-----------后进先出---一端


无序的不可重复的(判断重复的标准是hashCode()+equals()),

如果重复定义则会覆盖
LinkedSet---------------重复时保留第一个
TreeSet-------------(String)按照ASCll码进行排序

加载因子:加载因子 是哈希表在其容量自动增加之前可以达到多

满的一种尺度。当哈希
表中的条目数超出了加载因子与当前容量的乘积时,通过调用

rehash 方法将容量翻倍。
通常,默认加载因子 (.75) 在时间和空间成本上寻 求一种折衷

。加载因子过高虽然减少
了空间开销,但同时也增加了查询成本(在大多数 Hashtable类

的操作中,包括 get 和
put 操作,都反映了这一点)。在设置初始容量时应该考虑到映

射中所需的条目数及其加
载因子,以便最大限度地降低 rehash 操作次数。如果初始容量

大于最大条目数除以加载
因子,则不会发生 rehash 操作

List默认容量10,HashSet默认容量16,加载因子0.75;

HashMap 的实例有两个参数影响其性能:初始容量 和加载因子。

容量是哈希表中桶的数量,
初始容量只是哈希表在创建时的容量。加载因子 是哈希表在其容

量自动增加之前可以达到
多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容

量的乘积时,则要对该哈希
表进行 rehash 操作(即重建内部数据结构),从而哈希表将具

有大约两倍的桶数。

在比较时可以自定义一个比较方式,此类必须要继承

Comparable接口,并实现compareTo( T t){ ----重写

toString()输出
   
 return -1|0|1;      //  <|=|>
}

import java.util.*;
public class HashSetTest{
public static void main(String[] args) {
/*Set set1 = new LinkedHashSet();
set1.add("sds");
set1.add("2sa");
set1.add("213");
set1.add("213");
System.out.println(set1);//无序
System.out.println

("--------------------------------------");
Set set2 = new HashSet();
set2.add("sds");
set2.add("213");
set2.add("2sa");
set2.add("213");
System.out.println(set2);//按插入顺序输出
System.out.println

("--------------------------------------");

Set set3 = new TreeSet();
set3.add("sds");
set3.add("213");
set3.add("2sa");
set3.add("213");
System.out.println(set3); //排序
System.out.println

("--------------------------------------");
*/
Set set=new TreeSet();
Cat c1=new Cat(2,"red");
Cat c2=new Cat(1,"black");
Cat c3=new Cat(3,"white");
set.add(c1);
set.add(c2);
set.add(c3);
System.out.println(set.toString());
}
}

class Cat implements Comparable{
private int age;
private String color;
public Cat(int age,String color){
this.age=age;
this.color=color;
}
public String toString(){
return "{age="+age+" , color="+color+"}";
}
    public int compareTo(Cat o){
  if(this.age>o.age){
            return 1;
  }else{
    return -1;
  }
   }
}
//---------- java ----------
//[{age=1 , color=black}, {age=2 , color=red}, {age=3 ,

color=white}]

LinkedHashSet--->HashSet----->AbstractSet----->Set---

>Collection------>Iterable
                                TreeSet------

>AbstractSet----->Set--->Collection------>Iterable
                                TreeSet------

>SortedSet------>Set---->Collection------>Iterable



Map

 泛型擦除----------类型擦除
     类型擦除指的是通过类型参数合并,将泛型类型实例关联到

同一份字节码上。编译器只为泛型类型生成一份字
节码,并将其实例关联到这份字节码上。类型擦除的关键在于从

泛型类型中清除类型参数的相关信息,并且再
必要的时候添加类型检查和类型转换的方法。
     类型擦除可以简单的理解为将泛型java代码转换为普通java

代码,只不过编译器更直接点,将泛型java
代码直接转换成普通java字节码。
     
   类型擦除的主要过程如下:
     1.将所有的泛型参数用其最左边界(最顶级的父类型)类型

替换。
     2.移除所有的类型参数,如:
interface Comparable {
  public int compareTo( A that);
}
final class NumericValue implements Comparable

{
  priva te byte value;  
  public  NumericValue (byte value) { this.value = value;

}  
  public  byte getValue() { return value; }  
  public  int compareTo( NumericValue t hat) { return

this.value - that.value; }
}
-----------------
class Collections {  
  public static
>A max(Collection

xs) {
    Iterator
xi = xs.iterator();
    A w = xi.next();
    while (xi.hasNext()) {
      A x = xi.next();
      if (w.compareTo(x) < 0) w = x;
    }
    return w;
  }
}
final class Test {
  public static void main (String[ ] args) {
    LinkedList numberList = new LinkedList

();
    numberList .add(new NumericValue((byte)0));  
    numberList .add(new NumericValue((byte)1));  
    NumericValue y = Collections.max( numberList );  
  }
}
经过类型擦除后的类型为
 interface Comparable {
  public int compareTo( Object that);
}
final class NumericValue implements Comparable {
  priva te byte value;  
  public  NumericValue (byte value) { this.value = value;

}  
  public  byte getValue() { return value; }  
  public  int compareTo( NumericValue t hat)   { return

this.value - that.value; }
  public  int compareTo(Object that) { return

this.compareTo((NumericValue)that);  }
}
-------------
class Collections {  
  public static Comparable max(Collection xs) {
    Iterator xi = xs.iterator();
    Comparable w = (Comparable) xi.next();
    while (xi.hasNext()) {
      Comparable x = (Comparable) xi.next();
      if (w.compareTo(x) < 0) w = x;
    }
    return w;
  }
}
final class Test {
  public static void main (String[ ] args) {
    LinkedList numberList = new LinkedList();
    numberList .add(new NumericValue((byte)0));  ,
    numberList .add(new NumericValue((byte)1));  
    NumericValue y = (NumericValue) Collections.max(

numberList );  
  }
}
第一个泛型类Comparable
擦除后 A被替换为最左边界Object

。Comparable的类
型参数NumericValue被擦除掉,但是这直 接导致NumericValue没

有实现接口Comparable的compareTo(Object that)
方法,于是编译器充当好人,添加了一个桥接方法。
第二个示例中限定了类型参数的边界

Comparable
>A,A必须为Comparable的子类
,按照类型擦除的过程,先讲所有的类型参数 ti换为最左边界

Comparable
,然后去掉参数类型A,
得到最终的擦除后结果。



Collection 和 Collections的区别。

Collection是个java.util下的接口,它是各种集合结构的父接口

。继承与他的接口主要有Set 和List.
Collections是个java.util下的专用静态类,它包含有各种有关

集合操作的静态方法。提供一系列静态
方法实现对各种集合的搜索、排序、线程安全化等操作。

Array与Arrays的区别。

1.数组类Array,是Java中最基本的一个存储结构。提供了动态

创建和访问 Java 数组的方法。其中的
元素的类型必须相同。效率高,但容量固定且无法动态改变。 它

无法判断其中实际存有多少元素,
length只是告诉我们array的容量。
2、Arrays类,此静态类专门用来操作array ,提供搜索、排序、

复制等静态方法。equals():比较两个
array是否相等。array拥有相同元素个数,且所有对应元素两两

相等。 sort():用来对array进行排序。
 binarySearch():在排好序的array中寻找元素。

collections
例:
import java.util.*;
public class CollectionsDemo {
public static void main(String[] args) {
List sl = new ArrayList();
sl.add("jhn");
sl.add("ncgcxs");
sl.add("rgd");
sl.add("ceaz");
sl.add("vfe");
sl.add("byt");
sl.add("fe");
Collections.sort(sl);
System.out.println(sl);
//Collections.binarySearch(1);
//Collections.copy(sl);
System.out.println(Collections.max(sl));//max
System.out.println(Collections.min(sl));//min
Collections.reverse(sl);//反转
System.out.println(sl);
Collections.shuffle(sl);//打散
System.out.println(sl);
}


HashMap遍历的两种方式

第一种:
Map map = new HashMap();
Iterator iter = map.entrySet().iterator();
while (iter.hasNext()) {
    Map.Entry entry = (Map.Entry) iter.next();
    Object key = entry.getKey();
    Object val = entry.getValue();
}
效率高,以后一定要使用此种方式!
第二种:
Map map = new HashMap();
Iterator iter = map.keySet().iterator();
while (iter.hasNext()) {
    Object key = iter.next();
    Object val = map.get(key);
}
效率低,以后尽量少使用!

HashMap 与 TreeMap的区别
    集合框架”提供两种常规的Map实现:HashMap和TreeMap

(TreeMap实现SortedMap接口)。在Map
中插入、删除和定位元素,HashMap 是最好的选择。但如果您要

按自然顺序或自定义顺序遍历键,那
么TreeMap会更好。使用HashMap要求添加的键类明确定义了

hashCode()和equals()的实现。这个TreeMap
没有调优选项,因为该树总处于平衡状态。

TreeMap
(http://www.cnblogs.com/hzmark/archive/2013/01/02/TreeMa

p-Base.html)
Java 集合系列目录(Category)
(http://www.cnblogs.com/skywang12345/p/3323085.html)

---------------------------------------------------------

-------------|-------------------------------------------

---------------------------|
---------------------------------------------------------

-------------|-------------------------------------------

---------------------------|
---------------------------------------------------------

-------------|-------------------------------------------

---------------------------|
                                                          

                                                          

                              

四、I/O流、File

File--------java.io.File--------文件和目录路径名的抽象表

示形式

常用方法:
createNewFile(" ")---------创建文件
delete(" ")
exists()-----------测试是否存在
getName()---------获得文件名

例:
String path = File.separator;//与系统有关的默认名称分隔符
File f = new File("c:"+path+"c.txt");
ystem.out.println(f.createNewFile());



例:import java.io.*;
public class FileDemo {
public static void main(String[] args) throws

IOException{
/*
File f = new File("c:\\Users\\Rainlate\\Desktop\

\123.txt");//注意\的转义字符
//构建实例不代表创建文件
boolean b =f.createNewFile();//创建文件
f.mkdirs();//创建前不必有父目录
//f.createTempFile(sd,jsp);//使用给定前缀和后缀生成其名称

创建空文件
//f.createTempFile(23,txt, null);//使用给定前缀和后缀生成

其名称
//boolean d1 = f.delete();//删除此抽象路径名表示的文件或

目录。如果此路径名表示一个目录,则该目录必须为空才能删除
System.out.println(f.exists());//是否存在文件
System.out.println(f.getName());//123.txt
String path = File.separator;
File f = new File("c:"+path+"c.txt");
System.out.println(f.createNewFile());
String a = File.separator;
String path="c:"+a+"Users"+a+"Rainlate"+a+"Desktop"+a

+"1";
File f = new File(path);
File[] files = new listFiles(f);
for(String file:files){
System.out.println(file);
}
*/
File x= new File("c:\\Users\\Rainlate\\Desktop\\1");
show(x);
}

public static void show(File f){//递归输出源目录下的所有

文件
if(f.isDirectory()){//判断是否为目录
File[] files =f.listFiles();
for(int i=0;i show(files[i]);
}
}else{
System.out.println(f.getPath());
}
}
}


IO流:
第一,确定方向-----------输入输出是以程序为中心
第二,确定是字节还是字符【若是字符型文本使用字符流,其他

使用字节流】
第三,确定是否需要缓冲【autoFlush、Flush】----------缓冲

流是用空间换时间
第四,所有操作必须关闭【在finally关闭】

例1;
import java.io.*;
public class  FileInputStreamDemo{//文本复制
public static void main(String[] args) {
String a = File.separator;//与系统有关的默认名称分隔符
FileInputStream fin = null;
//FileOutputStream fo = null;
BufferedOutputStream fo = null;
try{
fin = new FileInputStream("C:"+a+"Users"+a+"Rainlate"+a

+"Desktop"+a+"123.docx");
byte[] b = new byte[512];//存储读取数据的缓冲区
long start = System.currentTimeMillis();
int size = fin.read(b,0,b.length);
//fo = new FileOutputStream("C:"+a+"Users"+a

+"Rainlate"+a+"Desktop"+a+"12.java");
fo = new BufferedOutputStream (new FileOutputStream

("C:"+a+"Users"+a+"Rainlate"+a+"Desktop"+a+"12.docx"));
while(size != -1){
fo.write(b,0,size);//文件的实际大小
fo.flush();
size = fin.read(b,0,b.length);
}
long late = System.currentTimeMillis();
System.out.println(late-start);
}catch (FileNotFoundException e){
System.out.println(e.getMessage());
}catch(IOException e){
System.out.println(e.getMessage());
}finally{
try{
fin.close();//关闭输入流
        fo.close();//关闭输出流
}catch (IOException e){
System.exit(1);//异常退出
}
}
}
}

例2:
import java.io.*;
public class ObjectSerializable {
public static void main(String[] args) {
Person p = new Person(32,"huhu");
String a = File.separator;
ObjectOutputStream ou =null;//序列化
ObjectInputStream oin = null;//反序列化
try{
ou = new ObjectOutputStream(new FileOutputStream("C:"+a

+"Users"+a+"Rainlate"+a+"Desktop"+a+"1.txt"));
ou.writeObject(p);//对象序列化
ou.flush();

//反序列化
oin = new ObjectInputStream(new FileInputStream("C:"+a

+"Users"+a+"Rainlate"+a+"Desktop"+a+"1.txt"));
Object obj = oin.readObject();
Person as = (Person)obj;
System.out.println(as);
out.flush();
}catch (FileNotFoundException e){
System.out.println(e.getMessage());
}catch(IOException e){
System.out.println(e.getMessage());
}catch(ClassNotFoundException e){
System.out.println(e.getMessage());
}finally{
try{
out.close();
}catch (IOException e){
System.exit(1);
}
}
}
}

class Person implements Serializable {
private int age;
private String name;
public Person(int age,String name){
this.age=age;
this.name=name;
}
public String toString(){
return "name="+this.name+",age="+this.age;
}
}


序列化的版本号(serialVersionUID=1L)?
作用:就是确保了不同版本之间的兼容性,不仅能够向前兼容,

还能够向后兼容,即在版本升级时反序列化仍保持对象的唯一性


它有两种生成方式:       
       一个是默认的1L,比如:private static final long

serialVersionUID = 1L;
       一个是根据类名、接口名、成员方法及属性等来生成一个

64位的哈希字段,比如:  private static final long

serialVersionUID = xxxxL


类图结构
  ┌BufferedReader
  ├InputStream──FileReader
  ├StringReader
┌Reader─┤
│   ├PipedReader
│   ├ByteArrayReader
│   └FileReader──PushbackReader
字符流─┤
│   ┌BufferedWriter
│   ├OutputStreamWriter──FileWriter
│   ├PrinterWriter
└Writer─┼StringWriter
  ├PipedWriter
  ├CharArrayWriter
  └FileWriter


┌FileInputStream
│ ┌BufferedInputStream
├FilterInputStream ──┼DataInputStream
│ └PushbackInputStream
┌InputStream ─┼ObjectInputStream
│ ├PipedInputStream
│ ├SequenceInputStream
│ ├StringBufferInputStream
│ └ByteArrayInoutStream
字节流─┤

│  ┌FileOutputStream
│  │   ┌BufferedOutputStream
│  ├FilterOutputStream ──┼DataOutputStream
└OutputStream ─┤   └PrintStream
 ├ObjectOutputStream
 ├PipedOutputStream



IO流------

(http://developer.51cto.com/art/201309/410913.htm)

---------------------------------------------------------

-------------|-------------------------------------------

---------------------------|
---------------------------------------------------------

-------------|-------------------------------------------

---------------------------|
---------------------------------------------------------

-------------|-------------------------------------------

---------------------------|
                                                          

                                                          

                              

五、html

  定义文档类型。
定义 HTML 文档。
定义文档的主体。

to

定义 HTML 标题。

定义段落。

定义简单的折行。


定义水平线。
定义注释。

定义粗体文本。
不赞成使用。定义文本的字体、尺寸和颜色
定义斜体文本。
定义强调文本。
定义大号文本。
定义语气更为强烈的强调文本。
定义小号文本。
定义上标文本。
定义下标文本。
定义文本的方向。
不赞成使用。定义下划线文本。

 定义预格式文本 
  
定义计算机代码文本。
定义打字机文本。
定义键盘文本。
定义文本的变量部分。
定义定义项目。
定义计算机代码样本。
不赞成使用。定义预格式文本。   <br> <br> <acronym> 定义只取首字母的缩写。 <br> <abbr> 定义缩写。 <br> <address> 定义文档作者或拥有者的联系信息。 <br> <blockquote> 定义块引用。 <br> <center> 不赞成使用。定义居中文本。 <br> <q> 定义短的引用。 <br> <cite> 定义引用(citation)。 <br> <ins> 定义被插入文本。 <br> <del> 定义被删除文本。 <br> <s> 不赞成使用。定义加删除线的文本。 <br> <strike> 不赞成使用。定义加删除线的文本。 <br> <br> <a> 定义锚。 <br> <link> 定义文档与外部资源的关系。 <br> <br> <frame> 定义框架集的窗口或框架。 <br> <frameset> 定义框架集。 <br> <noframes> 定义针对不支持框架的用户的替代内容。 <br> <iframe> 定义内联框架。 <br> <br> <form> 定义供用户输入的 HTML 表单。 <br> <input> 定义输入控件。 <br> <textarea> 定义多行的文本输入控件。 <br> <button> 定义按钮。 <br> <select> 定义选择列表(下拉列表)。 <br> <optgroup> 定义选择列表中相关选项的组合。 <br> <option> 定义选择列表中的选项。 <br> <label> 定义 input 元素的标注。 <br> <fieldset> 定义围绕表单中元素的边框。 <br> <legend> 定义 fieldset 元素的标题。 <br> <isindex> 不赞成使用。定义与文档相关的可搜索索引。 <br> <br> <ul> 定义无序列表。 <br> <ol> 定义有序列表。 <br> <li> 定义列表的项目。 <br> <dir> 不赞成使用。定义目录列表。 <br> <dl> 定义定义列表。 <br> <dt> 定义定义列表中的项目。 <br> <dd> 定义定义列表中项目的描述。 <br> <menu> 不赞成使用。定义菜单列表。 <br> <br> <img> 定义图像。 <br> <map> 定义图像映射。 <br> <area> 定义图像地图内部的区域。 <br> <br> <table> 定义表格 <br> <caption> 定义表格标题。 <br> <th> 定义表格中的表头单元格。 <br> <tr> 定义表格中的行。 <br> <td> 定义表格中的单元。 <br> <thead> 定义表格中的表头内容。 <br> <tbody> 定义表格中的主体内容。 <br> <tfoot> 定义表格中的表注内容(脚注)。 <br> <col> 定义表格中一个或多个列的属性值。 <br> <colgroup> 定义表格中供格式化的列组。 <br> <br> <style> 定义文档的样式信息。 <br> <div> 定义文档中的节。 <br> <span> 定义文档中的节。 <br> <br> <head> 定义关于文档的信息。 <br> <title> 定义文档的标题。 <br> <meta> 定义关于 HTML 文档的元信息。 <br> <base> 定义页面中所有链接的默认地址或默认目标。 <br> <basefont> 不赞成使用。定义页面中文本的默认字体、颜色或尺 <br> <br> 寸。 <br> <br> <script> 定义客户端脚本。 <br> <noscript> 定义针对不支持客户端脚本的用户的替代内容。 <br> <applet> 不赞成使用。定义嵌入的 applet。 <br> <object> 定义嵌入的对象。 <br> <param> 定义对象的参数。 <br> <br> <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br>                                                            <br> <br>                                                            <br> <br>                                <br> 六、CSS <br> <br> CSS 背景属性(Background) <br> 属性 描述 CSS <br> background 在一个声明中设置所有的背景属性。 1 <br> background-attachment 设置背景图像是否固定或者随着页面的 <br> <br> 其余部分滚动。 1 <br> background-color 设置元素的背景颜色。 1 <br> background-image 设置元素的背景图像。 1 <br> background-position 设置背景图像的开始位置。 1 <br> background-repeat 设置是否及如何重复背景图像。 1 <br> <br> CSS 边框属性(Border 和 Outline) <br> 属性 描述 CSS <br> border 在一个声明中设置所有的边框属性。 1 <br> border-bottom 在一个声明中设置所有的下边框属性。 1 <br> border-bottom-color 设置下边框的颜色。 2 <br> border-bottom-style 设置下边框的样式。 2 <br> border-bottom-width 设置下边框的宽度。 1 <br> border-color 设置四条边框的颜色。 1 <br> border-left 在一个声明中设置所有的左边框属性。 1 <br> border-left-color 设置左边框的颜色。 2 <br> border-left-style 设置左边框的样式。 2 <br> border-left-width 设置左边框的宽度。 1 <br> border-right 在一个声明中设置所有的右边框属性。 1 <br> border-right-color 设置右边框的颜色。 2 <br> border-right-style 设置右边框的样式。 2 <br> border-right-width 设置右边框的宽度。 1 <br> border-style 设置四条边框的样式。 1 <br> border-top 在一个声明中设置所有的上边框属性。 1 <br> border-top-color 设置上边框的颜色。 2 <br> border-top-style 设置上边框的样式。 2 <br> border-top-width 设置上边框的宽度。 1 <br> border-width 设置四条边框的宽度。 1 <br> outline 在一个声明中设置所有的轮廓属性。 2 <br> outline-color 设置轮廓的颜色。 2 <br> outline-style 设置轮廓的样式。 2 <br> outline-width 设置轮廓的宽度。 2 <br> <br> CSS 文本属性(Text) <br> 属性 描述 CSS <br> color 设置文本的颜色。 1 <br> direction 规定文本的方向 / 书写方向。 2 <br> letter-spacing 设置字符间距。 1 <br> line-height 设置行高。 1 <br> text-align 规定文本的水平对齐方式。 1 <br> text-decoration 规定添加到文本的装饰效果。 1 <br> text-indent 规定文本块首行的缩进。 1 <br> text-shadow 规定添加到文本的阴影效果。 2 <br> text-transform 控制文本的大小写。 1 <br> unicode-bidi 设置文本方向。 2 <br> white-space 规定如何处理元素中的空白。 1 <br> word-spacing 设置单词间距。 1 <br> <br> CSS 字体属性(Font) <br> 属性 描述 CSS <br> font 在一个声明中设置所有字体属性。 1 <br> font-family 规定文本的字体系列。 1 <br> font-size 规定文本的字体尺寸。 1 <br> font-size-adjust 为元素规定 aspect 值。 2 <br> font-stretch 收缩或拉伸当前的字体系列。 2 <br> font-style 规定文本的字体样式。 1 <br> font-variant 规定是否以小型大写字母的字体显示文本。 1 <br> font-weight 规定字体的粗细。 1 <br> <br> CSS 外边距属性(Margin) <br> 属性 描述 CSS <br> margin 在一个声明中设置所有外边距属性。 1 <br> margin-bottom 设置元素的下外边距。 1 <br> margin-left 设置元素的左外边距。 1 <br> margin-right 设置元素的右外边距。 1 <br> margin-top 设置元素的上外边距。 1 <br> <br> CSS 内边距属性(Padding) <br> 属性 描述 CSS <br> padding 在一个声明中设置所有内边距属性。 1 <br> padding-bottom 设置元素的下内边距。 1 <br> padding-left 设置元素的左内边距。 1 <br> padding-right 设置元素的右内边距。 1 <br> padding-top 设置元素的上内边距。 1 <br> <br> CSS 列表属性(List) <br> 属性 描述 CSS <br> list-style 在一个声明中设置所有的列表属性。 1 <br> list-style-image 将图象设置为列表项标记。 1 <br> list-style-position 设置列表项标记的放置位置。 1 <br> list-style-type 设置列表项标记的类型。 1 <br> marker-offset   2 <br> <br> 内容生成(Generated Content) <br> 属性 描述 CSS <br> content 与 :before 以及 :after 伪元素配合使用,来插入生成 <br> <br> 内容。 2 <br> counter-increment 递增或递减一个或多个计数器。 2 <br> counter-reset 创建或重置一个或多个计数器。 2 <br> quotes 设置嵌套引用的引号类型。 2 <br> CSS 尺寸属性(Dimension) <br> <br> 属性 描述 CSS <br> height 设置元素高度。 1 <br> max-height 设置元素的最大高度。 2 <br> max-width 设置元素的最大宽度。 2 <br> min-height 设置元素的最小高度。 2 <br> min-width 设置元素的最小宽度。 2 <br> width 设置元素的宽度。 1 <br> <br> CSS 定位属性(Positioning) <br> 属性 描述 CSS <br> bottom 设置定位元素下外边距边界与其包含块下边界之间的偏移 <br> <br> 。 2 <br> clear 规定元素的哪一侧不允许其他浮动元素。 1 <br> clip 剪裁绝对定位元素。 2 <br> cursor 规定要显示的光标的类型(形状)。 2 <br> display 规定元素应该生成的框的类型。 1 <br> float 规定框是否应该浮动。 1 <br> left 设置定位元素左外边距边界与其包含块左边界之间的偏移。 <br> <br> 2 <br> overflow 规定当内容溢出元素框时发生的事情。 2 <br> position 规定元素的定位类型。 2 <br> right 设置定位元素右外边距边界与其包含块右边界之间的偏移 <br> <br> 。 2 <br> top 设置定位元素的上外边距边界与其包含块上边界之间的偏移 <br> <br> 。 2 <br> vertical-align 设置元素的垂直对齐方式。 1 <br> visibility 规定元素是否可见。 2 <br> z-index 设置元素的堆叠顺序。 2 <br> <br> CSS 打印属性(Print) <br> 属性 描述 CSS <br> orphans 设置当元素内部发生分页时必须在页面底部保留的最少 <br> <br> 行数。 2 <br> page-break-after 设置元素后的分页行为。 2 <br> page-break-before 设置元素前的分页行为。 2 <br> page-break-inside 设置元素内部的分页行为。 2 <br> widows 设置当元素内部发生分页时必须在页面顶部保留的最少行 <br> <br> 数。 2 <br> <br> CSS 表格属性(Table) <br> 属性 描述 CSS <br> border-collapse 规定是否合并表格边框。 2 <br> border-spacing 规定相邻单元格边框之间的距离。 2 <br> caption-side 规定表格标题的位置。 2 <br> empty-cells 规定是否显示表格中的空单元格上的边框和背景。 <br> <br> 2 <br> table-layout 设置用于表格的布局算法。 2 <br> <br> CSS 伪类(Pseudo-classes) <br> 属性 描述 CSS <br> :active 向被激活的元素添加样式。 1 <br> :focus 向拥有键盘输入焦点的元素添加样式。 2 <br> :hover 当鼠标悬浮在元素上方时,向元素添加样式。 1 <br> :link 向未被访问的链接添加样式。 1 <br> :visited 向已被访问的链接添加样式。 1 <br> :first-child 向元素的第一个子元素添加样式。 2 <br> :lang 向带有指定 lang 属性的元素添加样式。 2 <br> <br> CSS 伪元素(Pseudo elements) <br> 属性 描述 CSS <br> :first-letter 向文本的第一个字母添加特殊样式。 1 <br> :first-line 向文本的首行添加特殊样式。 1 <br> :before 在元素之前添加内容。 2 <br> :after 在元素之后添加内容。 2 <br> <br> <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br>                                                            <br> <br>                                                            <br> <br>                                <br> <br> JDK1.5新特性: <br> <br> 七、枚举 <br> 枚举是一个类类型,是JDK1.5的新特性 <br> <br> 枚举的关键字是enum <br> <br> Java中所有的枚举类都是java.lang.Enum的子类 <br> <br> 注意:枚举类中可以包含成员有【字段(常量)、方法(构造方 <br> <br> 法、普通方法)】 <br> <br> 枚举中不能有number;不能赋值------------类 <br> <br>  只有顺序可以比较----------- <br> <br> 语法: <br> <br> enum 枚举名{ <br> <br>          枚举体 <br> <br> } <br> <br> 例: <br> <br> enum Direction{//枚举体 <br> <br>          EAST,SOUTH,WEST,NORTH//后面可以有分号也可以没有 <br> <br> } <br> <br> 调用:枚举名.成员 <br> <br> 枚举名 name =枚举名.成员; <br> <br> Direction dir = Direction.EAST; <br> <br>   <br> <br> Enum的方法使用: <br> <br> Javap---------------查看字节码文件 <br> <br> <br> 代码: <br> <br> enum Direction{ <br> <br> EAST('e'),SOUTH('s'),NORTH('n'),WEST('w'); <br> <br>     protected char a; <br> <br> private Direction(char a){ <br> <br> this.a = a; <br> <br> } <br> <br> public String toString(){ <br> <br> return a+""; <br> <br> } <br> <br> } <br> <br> 字节码: <br> <br> <br> ---------- javap ---------- <br> <br> Compiled from "Direction.java" <br> <br> final class Direction extends java.lang.Enum<Direction> <br> <br> {//不能被实例化 <br> <br>   public static final Direction EAST; <br> <br>   public static final Direction SOUTH; <br> <br>   public static final Direction NORTH; <br> <br>   public static final Direction WEST; <br> <br>   protected char a;//默认是private,但可以使用4P <br> <br>   public static Direction[] values();//默认方法,用来遍历 <br> <br> 打印枚举成员 <br> <br>   public static Direction valueOf(java.lang.String); <br> <br>   public java.lang.String toString(); <br> <br>   static {};//静态初始化块 <br> <br> } <br> <br> 由上面可以知道枚举继承java.lang.Enum类,参数的默认修饰符 <br> <br> public static final,在枚举中可以使用4p <br> <br> <br> <br> public enum A{BLUE,RED,BLACK};//声明并定义一个枚举,初始 <br> <br> 化为。。。 <br> <br> 在一个类中定义一个enum成员,enum默认是静态的------------- <br> <br> 相当于类变量 <br> <br> <br> <br> 枚举的用法 <br> <br> 一、常量-----------枚举出来之前都是通过接口 <br> <br> 在JDK1.5 之前,我们定义常量都是: public static fianl,现 <br> <br> 在可以把相关的常量分组到一个枚举类型里,例: <br> <br> public enum Color { <br> <br>   RED, GREEN, BLANK, YELLOW <br> <br> } <br> <br> 二、Switch <br> <br> JDK1.5之后的switch语句支持Byte,short,int,char,enum类型 <br> <br> ,使用枚举,能让我们的代码可读性更强,JDK1.7之后开始支持 <br> <br> String类型,例: <br> <br> enum Signal { <br> <br>          GREEN, YELLOW, RED <br> <br> } <br> <br> public class TrafficLight { <br> <br>          Signal color = Signal.RED; <br> <br>          public void change() { <br> <br>                    switch (color) { <br> <br>                    case RED: <br> <br>                             color = Signal.GREEN; <br> <br>                             break; <br> <br>                    case YELLOW: <br> <br>                             color = Signal.RED; <br> <br>                             break; <br> <br>                    case GREEN: <br> <br>                             color = Signal.YELLOW; <br> <br>                             break; <br> <br>                    } <br> <br>          } <br> <br> } <br> <br> 三、向枚举中添加新方法 <br> <br> 要自定义方法,必须在enum实例序列的最后添加一个分号。而且 <br> <br> Java 要求必须先定义 enum实例,例: <br> <br> public enum Color { <br> <br>          RED("红色", 1), GREEN("绿色", 2), BLANK("白色", <br> <br> 3), YELLO("黄色", 4); <br> <br>          // 成员变量 <br> <br>          private String name; <br> <br>          private int index; <br> <br>          // 构造方法 <br> <br>          private Color(String name, int index) { <br> <br>                    this.name = name; <br> <br>                    this.index = index; <br> <br>          } <br> <br>          // 普通方法 <br> <br>          public static String getName(int index) { <br> <br>                    for (Color c : Color.values()) { <br> <br>                             if (c.getIndex() == index) { <br> <br>                                      return c.name; <br> <br>                             } <br> <br>                    } <br> <br>                    return null; <br> <br>          } <br> <br>          // get set 方法 <br> <br>          public String getName() { <br> <br>                    return name; <br> <br>          } <br> <br>          public void setName(String name) { <br> <br>                    this.name = name; <br> <br>          } <br> <br>          public int getIndex() { <br> <br>                    return index; <br> <br>          } <br> <br>          public void setIndex(int index) { <br> <br>                    this.index = index; <br> <br>          } <br> <br> } <br> <br> 四、覆盖枚举的方法 <br> <br> 例如覆盖toString() <br> <br> public enum Color { <br> <br>          RED("红色", 1), GREEN("绿色", 2), BLANK("白色", <br> <br> 3), YELLO("黄色", 4); <br> <br>          // 成员变量 <br> <br>          private String name; <br> <br>          private int index; <br> <br>          // 构造方法 <br> <br>          private Color(String name, int index) { <br> <br>                    this.name = name; <br> <br>                    this.index = index; <br> <br>          } <br> <br>          //覆盖方法 <br> <br>          @Override <br> <br>          public String toString() { <br> <br>                    return this.index+"_"+this.name; <br> <br>          } <br> <br> } <br> <br> 五、实现接口------所有的枚举都继承自java.lang.Enum类。由 <br> <br> 于Java 不支持多继承,所以枚举对象不能再继承其他类,例: <br> <br> public interface Behaviour { <br> <br>          void print(); <br> <br>          String getInfo(); <br> <br> } <br> <br> public enum Color implements Behaviour{ <br> <br>          RED("红色", 1), GREEN("绿色", 2), BLANK("白色", <br> <br> 3), YELLO("黄色", 4); <br> <br>          // 成员变量 <br> <br>          private String name; <br> <br>          private int index; <br> <br>          // 构造方法 <br> <br>          private Color(String name, int index) { <br> <br>                    this.name = name; <br> <br>                    this.index = index; <br> <br>          } <br> <br> //接口方法 <br> <br>          @Override <br> <br>          public String getInfo() { <br> <br>                    return this.name; <br> <br>          } <br> <br>          //接口方法 <br> <br>          @Override <br> <br>          public void print() { <br> <br>                    System.out.println(this.index <br> <br> +":"+this.name); <br> <br>          } <br> <br> } <br> <br> 六、使用接口组织枚举 <br> <br> public interface Food { <br> <br>          enum Coffee implements Food{ <br> <br>                     <br> <br> BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO <br> <br>          } <br> <br>          enum Dessert implements Food{ <br> <br>                    FRUIT, CAKE, GELATO <br> <br>          } <br> <br> } <br> <br> 七、枚举集合 <br> <br> java.util.EnumSet和java.util.EnumMap是两个枚举集合。 <br> <br> EnumSet保证集合中的元素不重复;EnumMap中的key是enum类型, <br> <br> 而value则可以是任意类型。 <br> <br> <br> <br> 枚举和普通类的区别与联系; <br> <br> 1、枚举与类都可以实现多接口;访问控制符都可以使用(4p), <br> <br> 但枚举中默认的是private,类中默认的是package; <br> <br> 2、枚举直接继承java.lang.Enum类,普通类是继承 <br> <br> java.lang.Object;其中java.long.Enum类实现了 <br> <br> java.long.Serializable和java.long.Comparable两个接口。 <br> <br> 3、使用enum定义、非抽象的枚举默认修饰符为public final,因 <br> <br> 此枚举不能派生子类。 <br> 4、枚举的构造器只能使用private访问控制符,如果省略了枚举 <br> <br> 的访问修饰符其默认为private修饰;因为枚举的字段不能初始化 <br> <br> ,对象类型的必须调用构造方法,所有有多少个成员构造方法就 <br> <br> 会运行多少次; <br> 5、枚举的所有实例必须在枚举的第一行显示列出,否则这个枚举 <br> <br> 永远都不能生产实例,列出这些实例时系统会自动添加public <br> <br> static final修饰,无需程序员显式添加 <br> <br> 6、所有的枚举类都提供了一个values方法,该方法可以很方便的 <br> <br> 遍历所有的枚举值 <br> <br> 7、关键字:枚举是enum,类是class <br> <br> 8、枚举是类类型,类是引用类型 <br> <br> <br> instanceof关键字: <br> public class FX { <br> public static void main(String[] args) { <br> boolean b = ("1" instanceof String);//判断某个对象是不是 <br> <br> 某个类的实例    Result = Object instanceof <br> <br> Class/interface <br> //Result:布尔类型。 <br>    //Object:必选项。任意对象表达式。 <br> //Class:必选项。任意已定义的对象类。 <br> System.out.println(b); <br> } <br> } <br> <br> <br> 注解---JDK1.5的新特性 <br> 使用位置:类上、方法上、语句上 <br> <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br> <br> <br> 八、协变与泛型 <br> 协变-------可以用在数组、重写,不可以用在枚举中 <br> <br> 可变参数: <br> <br> int… a-------------代表一个没有长度限制的数组---------- <br> <br> JDK1.5之后有的 <br> <br> 输入的必须是数组 <br> <br> Java1.5增加了新特性:可变参数:适用于参数个数不确定,类型 <br> <br> 确定的情况,java把可变参数当做数组处理。注意:可变参数必 <br> <br> 须位于最后一项。只支持有一个可变参数。因为参数个数不定, <br> <br> 所以当其后边还有相同类型参数时,java无法区分传入的参数属 <br> <br> 于前一个可变参数还是后边的参数,所以只能让可变参数位于最 <br> <br> 后一项。 <br> <br> 可变参数的特点: <br> <br> (1)、只能出现在参数列表的最后; <br> <br> (2)、... 位于变量类型和变量名之间,前后有无空格都可以; <br> <br> (3)、调用可变参数的方法时,编译器为该可变参数隐含创建一 <br> <br> 个数组,在方法体中以数组的形式访问可变参数。例: <br> <br> public class Varable { <br>      public static void main(String [] args){ <br>          System.out.println(add(2,3)); <br>          System.out.println(add(2,3,5)); <br>      } <br>      public static int add(int x,int ...args){ <br>          int sum=x; <br>          for(int i=0;i<args.length;i++){ <br>              sum+=args[i]; <br>          } <br>          return sum; <br>      } <br> } <br> <br>  协变的作用范围 <br> <br> 1、数组:如果 A 是 B 的超类,则 A[] 也是 B[] 的超类,所有 <br> <br> 需要 A[] 的地方都可以用 B[] 代替,例: <br> <br> public class Test2 { <br> <br>     public static void main(String[] args){ <br> <br>         Integer[] ints=new Integer[1]; <br> <br>         ints[0]=99; <br> <br>         show(ints); <br> <br>     } <br> <br>     static void show(Number[] ns){ <br> <br>         System.out.println(Arrays.toString(ns)); <br> <br>     } <br> <br> } <br> <br>   <br> <br> 2、重写 <br> <br> public class Test2 { <br> <br>     public static void main(String[] args){ <br> <br>         P p=new C(); <br> <br>         System.out.println(p.get()); <br> <br>     } <br> <br> } <br> <br> class P{ <br> <br>     public Number get(){ <br> <br>         return new Integer(0); <br> <br>     } <br> <br> } <br> <br> class C extends P{ <br> <br>     public Integer get(){ <br> <br>         return new Integer(1); <br> <br>     } <br> <br> } <br> <br> 3、泛型不能协变:如果 A 是 B 的超类,则 List<A> 和 <br> <br> List<B> 无关,需要 List<A> 的地方不可以用 List<B> 代替, <br> <br> 例: <br> <br> public class Test2 { <br> <br>     public static void main(String[] args) { <br> <br>         List<Integer> ints = new ArrayList<Integer>(); <br> <br>         //incompatible type--类型不兼容 <br> <br>         show(ints); <br> <br>     } <br> <br>   <br> <br>     static void show(List<Number> ns) { <br> <br>         System.out.println(ns); <br> <br>     } <br> <br> } <br> <br> <br> 泛型(Generic)的本质是类型参数化 <br> <br> -------------是JDK1.5提供的新技术,它的本质是类型参数化, <br> <br> 类似C++中的模板,它根据应用主要分为泛型方法,泛型接口,泛 <br> <br> 型类,协变不适用于泛型 <br> <br>   <br> <br> 泛型-------------泛型类class Demo<T>{},泛型接口interface <br> <br> Inter<T>{},泛型方法public<T> T show(T a) {} <br> <br> 泛型的好处是在编译的时候检查类型安全,并且所有的强制转换 <br> <br> 都是自动和隐式的,提高代码的重用率 <br> <br>   <br> <br> 例1: <br> <br> public class  GenericDemo{ <br> <br>        public static void main(String[] args) { <br> <br>               C c1 = new C(new A("aaa")); <br> <br>               C c2 = new C(new B(3.4));//包装成double--- <br> <br> 自动装箱 <br> <br>               Object obj = c1.getObj(); <br> <br>               A obj = (A)(c1.getObj());//强制转换 <br> <br>               System.out.println(obj); <br> <br>        } <br> <br> } <br> <br> class A{ <br> <br>        private String x; <br> <br>        public A(String x){ <br> <br>               this.x=x; <br> <br>        } <br> <br>        public String getX(){ <br> <br>               return x; <br> <br>        } <br> <br> } <br> <br> class B{ <br> <br>        private Double d; <br> <br>        public B(Double d){ <br> <br>               this.d=d ; <br> <br>        } <br> <br>        public Double getD(){ <br> <br>               return d; <br> <br>        } <br> <br> } <br> <br> class C{ <br> <br>        private Object obj; <br> <br>        public C(Object obj){ <br> <br>               this.obj=obj ; <br> <br>        } <br> <br>        public Object  getObj(){ <br> <br>               return obj; <br> <br>        } <br> <br> } <br> <br>   <br> <br> 泛型的使用: <br> <br> 一、泛型类: <br> <br> public class Demo1 { <br> <br>        public static void main(String[] args) { <br> <br>               Generic<String> c = new Generic<String> <br> <br> ("asad"); <br> <br>               System.out.println(c.getA()); <br> <br>   <br> <br>               //Generic<int> c1 = new Generic<int>(12);必 <br> <br> 须要是包装类 <br> <br>        } <br> <br> } <br> <br> class Generic<T>{//泛型类 <br> <br>        private T a; <br> <br>        public Generic(T a){ <br> <br>               this.a = a; <br> <br>        } <br> <br>        public T getA(){ <br> <br>               return a; <br> <br>        } <br> <br> } <br> <br>   <br> <br> 二、泛型方法 <br> <br>        public static <T> T getX(T t){//泛型方 <br> <br> 法----------<  >--表声明 <br> <br>               return t; <br> <br>        } <br> <br>        <br> <br> public static <T,K> T getX(K t){//泛型方法 <br> <br>               return t; <br> <br>        } <br> <br>   <br> <br> 三、泛型接口 <br> <br> public class GenericDemo3{ <br> <br> public static void main(String[] args) { <br> <br> D<int[][]> d = new D<int[][]>(); <br> <br> d.show(new int[][]{{1,4},{2,3}}); <br> <br> } <br> <br> } <br> <br> interface IA<T>{ <br> <br> void show(T t); <br> <br> } <br> <br> <br> <br> class D<T> implements IA<T>{ <br> <br> public void show(T t){ <br> <br> System.out.println(t.getClass().getName()); <br> <br> } <br> <br> } <br> <br>   <br> <br>   <br> <br> 有界类型: <br> <br> 上界:extends 默认上界为Object <br> <br> Class G <T extends Number,K extends Object,H super <br> <br> Integer>{} <br> <br> 下界:super----------只有通配符有下限 <br> <br> extends关键字声明了类型的上界,表示参数化的类型可能是所指 <br> <br> 定的类型,或者是此类型的子类 <br> <br> super关键字声明了类型的下界,表示参数化的类型可能是所指定 <br> <br> 的类型,或者是此类型的父类型,直至Object <br> <br>   <br> <br> 规则和限制 <br> <br> 1、泛型的类型参数只能是类类型(包括自定义类),不能是简单 <br> <br> 类型。 <br> <br> 2、同一种泛型可以对应多个版本(因为参数类型是不确定的), <br> <br> 不同版本的泛型类实例是不兼容的。 <br> <br> 3、泛型的类型参数可以有多个。<T,K> <br> <br> 4、泛型的参数类型可以使用extends关键字,例如<T extends <br> <br> superclass>。习惯上称为“有界类型”。 <br> <br> 5、泛型的参数类型还可以是通配符类型。例如Class<?> <br> <br> classType = Class.forName("java.lang.String") <br> <br> 6、如果只指定了<?>,而没有extends,则默认是允许Object及其 <br> <br> 下的任何Java类了。也就是任意类。 <br> <br> 7、通配符泛型不但可以向下限制,如<? extends Collection>, <br> <br> 还可以向上限制,如<? super Double>,表示类型只能接受 <br> <br> Double及其上层父类类型,如Number、Object类型的实例。 <br> <br> 8、泛型类定义可以有多个泛型参数,中间用逗号隔开,还可以定 <br> <br> 义泛型接口,泛型方法。这些都与泛型类中泛型的使用规则类似 <br> <br> 。 <br> <br> 一个普通static方法,无法访问泛型类的类型参数,所以,若普 <br> <br> 通static方法需要使用泛型参数,必须使其成为泛型方法。 <br> <br>   <br> <br>   <br> <br> java 泛型详解 <br> <br> 普通泛型 <br> <br> Java代码 <br> <br> 1.  class Point<T>{       // 此处可以随便写标识符号   <br> <br> 2.      private T var ; // var的类型由T指定,即:由外部指 <br> <br> 定   <br> <br> 3.      public T getVar(){  // 返回值的类型由外部决定   <br> <br> 4.          return var ;   <br> <br> 5.      }   <br> <br> 6.      public void setVar(T var){  // 设置的类型也由外部 <br> <br> 决定   <br> <br> 7.          this.var = var ;   <br> <br> 8.      }   <br> <br> 9.  }   <br> <br> 10. public class GenericsDemo06{   <br> <br> 11.     public static void main(String[] args){ <br> <br> 12.         Point<String> p = new Point<String>() ; // 里 <br> <br> 面的var类型为String类型  --------指定数据类型—必须是引用 <br> <br> 数据类型 <br> <br> 13.         p.setVar("it") ;        // 设置字符串   <br> <br> 14.         System.out.println(p.getVar().length()) ;    <br> <br> // 取得字符串的长度   <br> <br> 15.     }   <br> <br> 16. } <br> <br> 17. //2 <br> <br> 18. <br> <br> --------------------------------------------------------- <br> <br> -   <br> <br> 19. class Notepad<K,V>{       // 此处指定了两个泛型类 <br> <br> 型-----再类上进行声明泛型类型   <br> <br> 20.     private K key ;     // 此变量的类型由外部决定   <br> <br> 21.     private V value ;   // 此变量的类型由外部决定   <br> <br> 22.     public K getKey(){   <br> <br> 23.         return this.key ;   <br> <br> 24.     }   <br> <br> 25.     public V getValue(){   <br> <br> 26.         return this.value ;   <br> <br> 27.     }   <br> <br> 28.     public void setKey(K key){   <br> <br> 29.         this.key = key ;   <br> <br> 30.     }   <br> <br> 31.     public void setValue(V value){   <br> <br> 32.         this.value = value ;   <br> <br> 33.     }   <br> <br> 34. }   <br> <br> 35. public class GenericsDemo09{   <br> <br> 36.     public static void main(String args[]){   <br> <br> 37.         Notepad<String,Integer> t = null ;        // <br> <br> 定义两个泛型类型的对象   <br> <br> 38.         t = new Notepad<String,Integer>() ;       // <br> <br> 里面的key为String,value为Integer   <br> <br> 39.         t.setKey("汤姆") ;        // 设置第一个内容   <br> <br> 40.         t.setValue(20) ;            // 设置第二个内容 <br> <br>   <br> <br> 41.         System.out.print("姓名;" + t.getKey()) ;      <br> <br>  // 取得信息   <br> <br> 42.         System.out.print(",年龄;" + t.getValue()) ; <br> <br>       // 取得信息   <br> <br> 43.       }   <br> <br> 44. }  //汤姆 <br> <br> 45.       20 <br> <br>  通配符 <br> <br> Java代码 <br> <br> 1.  class Info<T>{   <br> <br> 2.      private T var ;     // 定义泛型变量   <br> <br> 3.      public void setVar(T var){   <br> <br> 4.          this.var = var ;   <br> <br> 5.      }   <br> <br> 6.      public T getVar(){   <br> <br> 7.          return this.var ;   <br> <br> 8.      }   <br> <br> 9.      public String toString(){   // 直接打印   <br> <br> 10.         return this.var.toString() ;   <br> <br> 11.     }   <br> <br> 12. } <br> <br> 13. public class GenericsDemo14{   <br> <br> 14.     public static void main(String args[]){   <br> <br> 15.         Info<String> i = new Info<String>() ;        <br> <br> // 使用String为泛型类型   <br> <br> 16.         i.setVar("it") ;                             <br> <br> // 设置内容   <br> <br> 17.         fun(i) ;   <br> <br> 18.     }   <br> <br> 19.     public static void fun(Info<?> temp){     // 可以 <br> <br> 接收任意的泛型对象   <br> <br> 20.         System.out.println("内容:" + temp) ;   <br> <br> 21.     }   <br> <br> 22. }//  内容:it <br> <br>  受限泛型 <br> <br> Java代码 <br> <br> 1.  class Info<T>{   <br> <br> 2.      private T var ;     // 定义泛型变量   <br> <br> 3.      public void setVar(T var){   <br> <br> 4.          this.var = var ;   <br> <br> 5.      }   <br> <br> 6.      public T getVar(){   <br> <br> 7.          return this.var ;   <br> <br> 8.      }   <br> <br> 9.      public String toString(){   // 直接打印   <br> <br> 10.         return this.var.toString() ;   <br> <br> 11.     }   <br> <br> 12. }   <br> <br> 13. public class GenericsDemo17{   <br> <br> 14.     public static void main(String args[]){   <br> <br> 15.         Info<Integer> i1 = new Info<Integer>() ;   // <br> <br> 声明Integer的泛型对象   <br> <br> 16.         Info<Float> i2 = new Info<Float>() ;          <br> <br> // 声明Float的泛型对象   <br> <br> 17.         i1.setVar(30) ;                               <br> <br> // 设置整数,自动装箱   <br> <br> 18.         i2.setVar(30.1f) ;                            <br> <br> // 设置小数,自动装箱   <br> <br> 19.         fun(i1) ;   <br> <br> 20.         fun(i2) ;   <br> <br> 21.     }   <br> <br> 22.     public static void fun(Info<? extends Number> <br> <br> temp){ // 只能接收Number及其Number的子类   <br> <br> 23.         System.out.print(temp + "、") ;   <br> <br> 24.     }   <br> <br> 25. }//  30、30.1、 <br> <br> 26. <br> <br> --------------------------------------------------------- <br> <br> -   <br> <br> 27. class Info<T>{   <br> <br> 28.     private T var ;     // 定义泛型变量   <br> <br> 29.     public void setVar(T var){   <br> <br> 30.         this.var = var ;   <br> <br> 31.     }   <br> <br> 32.     public T getVar(){   <br> <br> 33.         return this.var ;   <br> <br> 34.     }   <br> <br> 35.     public String toString(){   // 直接打印   <br> <br> 36.         return this.var.toString() ;   <br> <br> 37.     }   <br> <br> 38. }   <br> <br> 39. public class GenericsDemo21{   <br> <br> 40.     public static void main(String args[]){   <br> <br> 41.         Info<String> i1 = new Info<String>() ;       <br> <br> // 声明String的泛型对象   <br> <br> 42.         Info<Object> i2 = new Info<Object>() ;       <br> <br> // 声明Object的泛型对象   <br> <br> 43.         i1.setVar("hello") ;   <br> <br> 44.         i2.setVar(new Object()) ;   <br> <br> 45.         fun(i1) ;   <br> <br> 46.         fun(i2) ;   <br> <br> 47.     }   <br> <br> 48.     public static void fun(Info<? super String> <br> <br> temp){   // 只能接收String或Object类型的泛型  ----上限为 <br> <br> String <br> <br> 49.         System.out.print(temp + "、") ;   <br> <br> 50.     }   <br> <br> 51. }//  hello、java.lang.Object@1ffc686、 <br> <br>  泛型无法向上转型 <br> <br> Java代码 <br> <br> 1.  class Info<T>{   <br> <br> 2.      private T var ;     // 定义泛型变量   <br> <br> 3.      public void setVar(T var){   <br> <br> 4.          this.var = var ;   <br> <br> 5.      }   <br> <br> 6.      public T getVar(){   <br> <br> 7.          return this.var ;   <br> <br> 8.      }   <br> <br> 9.      public String toString(){   // 直接打印   <br> <br> 10.         return this.var.toString() ;   <br> <br> 11.     }   <br> <br> 12. }   <br> <br> 13. public class GenericsDemo23{   <br> <br> 14.     public static void main(String args[]){   <br> <br> 15.         Info<String> i1 = new Info<String>() ;       <br> <br> // 泛型类型为String   <br> <br> 16.         Info<Object> i2 = null ;   <br> <br> 17.         i2 = i1 ;                           //这句会 <br> <br> 出错 incompatible types   <br> <br> 18.     }   <br> <br> 19. }//  编译失败 <br> <br>  泛型接口 <br> <br> Java代码 <br> <br> 1.  interface Info<T>{        // 在接口上定义泛型   <br> <br> 2.      public T getVar() ; // 定义抽象方法,抽象方法的返 <br> <br> 回值就是泛型类型   <br> <br> 3.  }   <br> <br> 4.  class InfoImpl<T> implements Info<T>{   // 定义泛型接 <br> <br> 口的子类   <br> <br> 5.      private T var ;             // 定义属性   <br> <br> 6.      public InfoImpl(T var){     // 通过构造方法设置属 <br> <br> 性内容   <br> <br> 7.          this.setVar(var) ;     <br> <br> 8.      }   <br> <br> 9.      public void setVar(T var){   <br> <br> 10.         this.var = var ;   <br> <br> 11.     }   <br> <br> 12.     public T getVar(){   <br> <br> 13.         return this.var ;   <br> <br> 14.     }   <br> <br> 15. }   <br> <br> 16. public class GenericsDemo24{   <br> <br> 17.     public static void main(String arsg[]){   <br> <br> 18.         Info<String> i = null;        // 声明接口对象 <br> <br>   <br> <br> 19.         i = new InfoImpl<String>("汤姆") ;  // 通过子 <br> <br> 类实例化对象   <br> <br> 20.         System.out.println("内容:" + i.getVar()) ;   <br> <br> 21.     }   <br> <br> 22. }//  内容:汤姆 <br> <br>  泛型方法 <br> <br> Java代码 <br> <br> 1.  class Demo{   <br> <br> 2.      public <T> T fun(T t){            // 可以接收任意 <br> <br> 类型的数据   <br> <br> 3.          return t ;                  // 直接把参数返回 <br> <br>   <br> <br> 4.      }   <br> <br> 5.  }   <br> <br> 6.  public class GenericsDemo26{   <br> <br> 7.      public static void main(String args[]){   <br> <br> 8.          Demo d = new Demo() ;   // 实例化Demo对象   <br> <br> 9.          String str = d.fun("汤姆") ; //   传递字符串   <br> <br> 10.         int i = d.fun(30) ;     // 传递数字,自动装箱 <br> <br>   <br> <br> 11.         System.out.println(str) ;   // 输出内容   <br> <br> 12.         System.out.println(i) ;     // 输出内容   <br> <br> 13.     }   <br> <br> 14. }//  汤姆  30 <br> <br>  通过泛型方法返回泛型类型实例 <br> <br> Java代码 <br> <br> 1.  class Info<T extends Number>{ // 指定上限,只能是数字 <br> <br> 类型   <br> <br> 2.      private T var ;     // 此类型由外部决定   <br> <br> 3.      public T getVar(){   <br> <br> 4.          return this.var ;      <br> <br> 5.      }   <br> <br> 6.      public void setVar(T var){   <br> <br> 7.          this.var = var ;   <br> <br> 8.      }   <br> <br> 9.      public String toString(){       // 覆写Object类中 <br> <br> 的toString()方法   <br> <br> 10.         return this.var.toString() ;       <br> <br> 11.     }   <br> <br> 12. }   <br> <br> 13. public class GenericsDemo27{   <br> <br> 14.     public static void main(String args[]){   <br> <br> 15.         Info<Integer> i = fun(30) ;   <br> <br> 16.         System.out.println(i.getVar()) ;   <br> <br> 17.     }   <br> <br> 18.     public static <T extends Number> Info<T> fun(T <br> <br> param){//方法中传入或返回的泛型类型由调用方法时所设置的参 <br> <br> 数类型决定   <br> <br> 19.         Info<T> temp = new Info<T>() ;      // 根据传 <br> <br> 入的数据类型实例化Info   <br> <br> 20.         temp.setVar(param) ;     // 将传递的内容设置 <br> <br> 到Info对象的var属性之中   <br> <br> 21.         return temp ;   // 返回实例化对象   <br> <br> 22.     }   <br> <br> 23. }//  30 <br> <br>  使用泛型统一传入的参数类型 <br> <br> Java代码 <br> <br> 1.  class Info<T>{    // 指定上限,只能是数字类型   <br> <br> 2.      private T var ;     // 此类型由外部决定   <br> <br> 3.      public T getVar(){   <br> <br> 4.          return this.var ;      <br> <br> 5.      }   <br> <br> 6.      public void setVar(T var){   <br> <br> 7.          this.var = var ;   <br> <br> 8.      }   <br> <br> 9.      public String toString(){       // 覆写Object类中 <br> <br> 的toString()方法   <br> <br> 10.         return this.var.toString() ;       <br> <br> 11.     }   <br> <br> 12. } <br> <br> 13. public class GenericsDemo28{   <br> <br> 14.     public static void main(String args[]){   <br> <br> 15.         Info<String> i1 = new Info<String>() ;   <br> <br> 16.         Info<String> i2 = new Info<String>() ;   <br> <br> 17.         i1.setVar("HELLO") ;        // 设置内容   <br> <br> 18.         i2.setVar("汤姆") ;       // 设置内容   <br> <br> 19.         add(i1,i2) ;   <br> <br> 20.     }   <br> <br> 21.     public static <T> void add(Info<T> i1,Info<T> <br> <br> i2){   <br> <br> 22.         System.out.println(i1.getVar() + " " + <br> <br> i2.getVar()) ;   <br> <br> 23.     }   <br> <br> 24. }// HELLO 汤姆 <br> <br>  泛型数组 <br> <br> Java代码 <br> <br> 1.  public class GenericsDemo30{   <br> <br> 2.      public static void main(String args[]){   <br> <br> 3.          Integer i[] = fun1(1,2,3,4,5,6) ;   // 返回泛 <br> <br> 型数组   <br> <br> 4.          fun2(i) ;   <br> <br> 5.      }   <br> <br> 6.      public static <T> T[] fun1(T...arg){  // 接收可变 <br> <br> 参数   <br> <br> 7.          return arg ;            // 返回泛型数组   <br> <br> 8.      }   <br> <br> 9.      public static <T> void fun2(T param[]){   // 输出 <br> <br>   <br> <br> 10.         System.out.print("接收泛型数组:") ;   <br> <br> 11.         for(T t:param){   <br> <br> 12.             System.out.print(t + "、") ;   <br> <br> 13.         }   <br> <br> 14.     }   <br> <br> 15. }//  接收泛型数组:1、2、3、4、5、6、 <br> <br>  泛型的嵌套设置 <br> <br> Java代码 <br> <br> 1.  class Info<T,V>{      // 接收两个泛型类型   <br> <br> 2.      private T var ;   <br> <br> 3.      private V value ;   <br> <br> 4.      public Info(T var,V value){   <br> <br> 5.          this.setVar(var) ;   <br> <br> 6.          this.setValue(value) ;   <br> <br> 7.      }   <br> <br> 8.      public void setVar(T var){   <br> <br> 9.          this.var = var ;   <br> <br> 10.     }   <br> <br> 11.     public void setValue(V value){   <br> <br> 12.         this.value = value ;   <br> <br> 13.     }   <br> <br> 14.     public T getVar(){   <br> <br> 15.         return this.var ;   <br> <br> 16.     }   <br> <br> 17.     public V getValue(){   <br> <br> 18.         return this.value ;   <br> <br> 19.     }   <br> <br> 20. }   <br> <br> 21. class Demo<S>{   <br> <br> 22.     private S info ;   <br> <br> 23.     public Demo(S info){   <br> <br> 24.         this.setInfo(info) ;   <br> <br> 25.     }   <br> <br> 26.     public void setInfo(S info){   <br> <br> 27.         this.info = info ;   <br> <br> 28.     }   <br> <br> 29.     public S getInfo(){   <br> <br> 30.         return this.info ;   <br> <br> 31.     }   <br> <br> 32. } <br> <br> 33. public class GenericsDemo31{   <br> <br> 34.     public static void main(String args[]){   <br> <br> 35.         Demo<Info<String,Integer>> d = null ;  // 将 <br> <br> Info作为Demo的泛型类型   <br> <br> 36.         Info<String,Integer> i = null ;   // Info指定 <br> <br> 两个泛型类型   <br> <br> 37.         i = new Info<String,Integer>("汤姆",30) ;     <br> <br> // 实例化Info对象   <br> <br> 38.         d = new Demo<Info<String,Integer>>(i);//在 <br> <br> Demo类中设置Info类的对象   <br> <br> 39.         System.out.println("内容一:" + d.getInfo <br> <br> ().getVar()) ;   <br> <br> 40.         System.out.println("内容二:" + d.getInfo <br> <br> ().getValue()) ;   <br> <br> 41.     }   <br> <br> 42. } // 内容一:汤姆 内容二:30 <br> <br>   泛型方法不一定要通过参数来确定泛型准确类型,可以只通过 <br> <br> 返回值,比如: <br> <br>  public static <E> ArrayList<E> newArrayList() { <br>          return new ArrayList<E>(); <br>  } <br> <br>  public List<PrepaidHistory> queryHistories(Long <br> <br> skyid,PrepaidHistoryType type, Date from, Date end) {  <br> <br>          return Lists.newArrayList(); <br> <br> } <br> <br>  这样Lists.newArrayList(); <br> 智能的知道返回类型为PrepaidHistory <br> 一、内部类(局部内部类、成员内部类、匿名内部类) <br> <br> 1、定义:内部类就是在类的内部定义一个类,它的分类有成员内 <br> <br> 部类、局部内部类、匿名内部类, <br> 它可以定义在类中方法外,也可以定义在类中方法内,内部类的 <br> <br> 好处是可以访问外部类的私有成员,但外部类无法访问内部类的 <br> <br> 私有成员 <br> 通过使用内部类可以确保程序的结构清晰和代码精炼 <br> <br> 编译后的内部类名称:InnerTest$A.class <br> <br> 2、分类:成员内部类(静态成员内部类)、局部内部类、匿名内 <br> <br> 部类 <br> a、成员内部类(非静态内部类):与外部类的属性和方法并列, <br> <br> 成员内部类可以看作是外部类的实例变量 <br> 在内部类中访问实例变量:this.字段; <br> 在内部类中访问外部类的实例变量:外部类名.this.字段 <br> 成员内部类中不能有静态字段或方法(final修饰的常量除外), <br> <br> 因为Static在加载时就创建,此时内部类可能还没被实例化 <br> 在外部类的外部实例化对象: <br> Foo foo = new Foo(); <br> Koo koo = foo.new Koo(); <br> Foo.Koo koo = new Foo().new Koo(); <br> <br> b、静态内部类 <br> 静态内部类可以直接访问外部类的静态成员,不能访问外部类的 <br> <br> 实例成员,但可以通过外部类的实例(new 对象)来访问 <br> 静态内部类里面可以定义静态成员(其他内部类不可以) <br> 静态内部类不可以使用private修饰 <br> 静态内部类的对象可以直接生成 <br> Foo.Koo koo = new Foo().new Koo(); <br> c、局部内部类 <br> 在方法中定义的内部类称为局部内部类,类似局部变量,不可以 <br> <br> 加修饰符public、protected、private,其范围为定义它的代码 <br> <br> 块 <br> 可以访问外部类的所有成员,还可以访问所在方法中的final修饰 <br> <br> 的参数和变量,但不能访问方法体中的局部变量 <br> d、匿名内部类 <br> 匿名内部类没有类名,它必须继承一个类或者实现一个接口,并 <br> <br> 且不能显示的extends或implements关键字 <br> 匿名内部类不能有构造方法,因为它没有类名。可以通过new<父 <br> <br> 类名>的方法创建实例对象,匿名类的创建与定义同时进行 <br> 匿名内部类只能一次性的创建其对象 <br> 匿名内部类既可以在方法体中,也可以在参数列表中 <br> 注意:匿名内部类一定是在new的后面隐含实现一个接口或继承一 <br> <br> 个类,匿名内部类不是抽象类 <br>       匿名内部类必须实现他的父类抽象接口或接口里的所有的 <br> <br> 抽象方法 <br> new 父类的构造器(实参列表)|实现接口(){ <br> //类体 <br> } <br> new Object(){ <br> } <br> <br> 3、内部类的访问规则:内部类可以直接访问外部类中的成员,包 <br> <br> 括私有 <br>                     最近的外部类要访问内部类必须建立内部 <br> <br> 类对象new Inner().fumction()来访问内部类中的成员 <br>                如: Outer.Inner in = new Outer().new <br> <br> Inner(); <br>                     in.function(); <br> <br> 4、使用:当描述事物时,事物的内部还有事物,该事物用内部类 <br> <br> 来描述,因为内部事物在使用外部事物的内容。 <br> 内部类定义在局部时,不能使用成员修饰符、static修饰,使用 <br> <br> 时需要new— <br> 可以直接访问外部类中的成员,但不可访问它所在的局部中的变 <br> <br> 量,只能访问被final修饰的局部变量 <br> <br> 5、代码分析:例1:----分类 <br> public class Demo2 { <br> class B{//成员内部类------Demo2$B.class <br> } <br> static class A{//静态成员内部类------Demo2$A.class <br> } <br> void show(){ <br> class C{//局部内部类-------Demo2$1C.class <br> } <br> } <br> public static void main(String[] args) { <br> class C{//局部内部类----Demo2$2C.class <br> } <br> System.out.println(); <br> } <br> } <br> <br> <br> <br> 例2:-----匿名内部类 <br> <br> 1、  匿名内部类其实就是内部类的简写格式 <br> 2、  定义前题必须继承一个类或实现一个接口 <br> 3、  匿名内部类的格式: new 父类或接口(){定义子类的内容} <br> 4、  匿名内部类定义的方法最好不要超过三个 <br> <br> public class Test{ <br>        public static void main(String[] agrs){ <br>               Test t=new Test();   //new了 一个Test对象 <br>               t.te(new A(){                //调用实例方法 <br> <br> 并且声明一个匿名内部类类作为一个参数传入 <br>                             public void as(){ <br>                                    System.out.println("我 <br> <br> 是实现了接口A的匿名类"); <br>                             } <br>                      } <br>               ); <br>       }          <br>       void te(A a){    //实例方法 <br>               a.as(); <br>       } <br> } <br> interface A{    //声明了一个接口类 <br>        void as();    //抽象方法 <br> } <br> <br>   <br> <br> 例3: <br> class A{ <br>        void as(){ <br>               System.out.println("我是内部类A"); <br>        } <br> } <br> class B{ <br>        void bs(){ <br>               System.out.println("我是内部类B"); <br>        } <br> } <br> public class MultipleExtends { <br>        private class C extends A{} <br>        private class D extends B{} <br>        public static void main(String[] args) { <br>               MultipleExtends m=new MultipleExtends(); // <br> <br> 声明一个外部类的对象 <br>               MultipleExtends.C c=m.new C(); //让外部类对 <br> <br> 象持有一个 <br>               MultipleExtends.D d=m.new D();//内部类对象 <br> <br> 的引用 <br>               c.as();                                      <br> <br>                                                            <br> <br>                             <br>               d.bs();                                      <br> <br>                                                            <br> <br>                             <br>        } <br> } <br> <br> <br> 例4:-----内部类是可以被私有的 <br> public class MemberClass { <br>    private int i=10;  //定义一个私有字段 <br>     private static int j=20;       <br>     public static void main(String[] args) { <br> MemberClass mc=new MemberClass();//new 一个外部类的对象 <br> A a=mc.new A();//A a=new MemberClass().new A();//new 一个 <br> <br> 内部类的对象 <br> a.as();//调用内部类的实例方法 <br>     } <br> private class A{ <br> //static int j=6; <br> //int i=5;              //定义一个内部类的实例字段     <br> void as(){     //定义一个内部类的实例方法 <br> System.out.println("这里是内部类A");    <br> System.out.println("调用外部类私有实例字段i:"+i); <br> System.out.print("调用外部类私有静态字段j:"+j); <br> } <br> } <br> } <br> <br> //---------- java ---------- <br> //这里是内部类A <br> //调用外部类私有实例字段i:10 <br> //调用外部类私有静态字段j:20 <br> <br> <br> <br> <br> 例5:----静态内部类 <br> public class StaticClass {          <br>        private static int i=10; //定义一个私有静态字段 <br>        //private int j=7; <br>        public static void main(String[] args) { <br>               StaticClass sc=new StaticClass();//new 一个 <br> <br> 外部类的对象 <br>               A a=new StaticClass.A(); //new 一个静态内部 <br> <br> 类 <br>               a.as();            //调用静态内部类的实例方 <br> <br> 法 <br>               A.at        //调用静态内部类的静态方法 <br>        } <br>        static class A{        <br>               int i=5; <br>               static at(){   //定义静态内部类的静态方法 <br>                      System.out.println("这里是静态内部类 <br> <br> 的静态方法"); <br>               } <br>               void as(){                 //定义静态内部类 <br> <br> 的实例方法 <br>                      System.out.println("这里是内部类A"); <br>                      System.out.print("调用外部类私有静态 <br> <br> 字段i:"+i); <br>               } <br>        } <br> } <br> <br>   <br> 例6:------局部内部类 <br> public class InteriorClass { <br>          private int i=5; <br>          public static void main(String[] args) { <br>                    InteriorClass ic=new InteriorClass();   <br> <br>  //new 一个对象 <br>                    ic.as();             //调用实例方法 <br>                    //      B b=ic.new B(); <br>          } <br>          void as(){ <br>                    final int y=5;        //常量        <br>                    int u=1;            //局部变量 <br>                    class B{ <br>                             void bs(){ <br>                                      System.out.println(" <br> <br> 这里是内部类B");         <br>                                      System.out.println(" <br> <br> 调用i"+i); <br>                                      System.out.println(" <br> <br> 常量"+y); <br>                             }                           <br>                    } <br>                    new B().bs(); <br>          } <br> } <br> <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br> <br> 二、异常(try\catch\fainlly\throw\throws) <br> i、 异常的含义和分类 <br>   a)含义:异常是对问题的描述,将问题进行问题的封装 <br>   b)分类:java.lang.Object-----Throwable(java中所有错误和 <br> <br> 异常的超类)-----Error(无法通过代码来处理的错误)         <br>                                              <br> <br> |---------------Exception(可处理的异常,并能恢复运行) <br>      |---RuntimeException(运行时异常)---可以不捕获也可以 <br> <br> 不处理 <br>      |----CheckedException(已检查时异常)----必须捕获或处 <br> <br> 理不然编译失败---IOException\SQLException <br>  标签(Marker)接口:既无字段又无方法--- <br> <br> Cloneable/Serializable/EventListener <br> <br>  Error----如:JVM硬件错误----OutOfMemoryError—内存不足、 <br> <br> 不断的创建实例、StackOverflowError---递归导致的堆异常 <br>   <br>  2、异常分类(Throwable) <br>   1、编译时被检测的异常 <br>      throws 需要处理 <br>   2、编译时不被检测的异常---运行时异常(RuntimeException <br> <br> 或其子类) <br>     函数内throw,函数外不需要声明,--------无法处理,需要 <br> <br> 修改代码 <br> <br> ii、 异常处理 <br> a)RuntimeEception及其子类异常,不需要程序员处理,其后语句 <br> <br> 不编译 <br> b)非运行时异常必须处理 <br> c)Exeception中有一个特殊的子类异常RuntimeException,如果 <br> <br> 在方法内抛出该异常,方法上可以不用声明,编译可以通过;如果 <br> <br> 在方法上声明了该异常,调用者可以不用处理,编译可以通过。 <br> <br> 之所以不在函数声明,是因为不希望让使用者处理,当异常发生 <br> <br> 时,希望程序停止,程序员修正程序代码 <br> <br> 异常的捕获和处理 <br> <br> 第一种格式: <br> try{ <br>          //可能抛出异常的语句 <br> }catch(异常类型 e){ <br>          //处理语句1 <br> } catch(异常类型 e){ <br>          //处理语句2 <br> }finally{ <br>          //一定执行的语句 <br> } <br> <br> finally只要用于异常处理,修饰异常块,无论异常是否处理都会 <br> <br> 执行 <br> finally在return、throw前输出,不管return是在try还是catch <br> <br> 中 <br> finally定义一定执行的代码,通常用于关闭资源------如:数据 <br> <br> 库关闭连接 <br> <br> finally块在以下情况将不会被执行: <br> (1)finally块中发生了异常; <br> (2)程序所在线程死亡; <br> (3)在前面的代码中用了System.exit(0); <br> (4)关闭CPU。 <br> <br> 第二种格式: <br> try{ <br> <br> }finally{ <br> <br> } <br> <br> 第三种格式: <br> try{ <br> <br> }catch(){ <br> <br> } <br> <br>   <br> iii.在多个catch时只执行一个,自上而下遇到的第一个异常所对 <br> <br> 应的catch,如果没有对应的catch,则先执 <br> 行finally后在抛出,没有finally则直接抛出,定义多个catch可 <br> <br> 精确地定位异常。如果为子类的异常定 <br> 义了特殊的catch块,而父类的异常则放在另外一个catch块中, <br> <br> 此时,必须满足以下规则:子类异常的处 <br> 理块必须在父类异常处理块的前面,否则会发生编译错误。所以 <br> <br> ,越特殊的异常越在前面处理,越普遍的 <br> 异常越在后面处理。这类似于制订防火墙的规则次序:较特殊的 <br> <br> 规则在前,较普通的规则在后。 <br> <br> throws--------声明方法抛出异常 <br> 1、说明:当不知道在当前代码中如何处理的时候,可以选择用 <br> <br> throws将异常交给上层调用者处理 <br> 2、基本格式: <br> 类型 方法名(形参列表)throws 异常列表(逗号隔开){ <br>           //代码 <br> } <br> <br> 例: <br> //手工抛出异常实例 <br> public class JavaThrow1{ <br>          public static void main(String[] args){ <br>                    System.out.print(" Now"); <br>                    try{ <br>                             System.out.print(" is"); <br>                             throw new <br> <br> NullPointerException();//直接抛出异常转到catch进行处理 <br>                             //System.out.println("This <br> <br> will not excute!");//有throw这句执行不到 <br>                    }catch (NullPointerException e){ <br>                             System.out.print(" the"); <br>                    } <br>                    System.out.print(" time.\n"); <br>          } <br> } <br> <br> //自动抛异常 <br> public class ExTest { <br> public static void main(String[] args){ <br> String s=null; <br> try{ <br> System.out.println("0"); <br> int i=s.length();//自动抛异常--空指针异常 <br> System.out.println("2"); <br> }finally{ <br> System.out.println("1"); <br> } <br> } <br> } <br> <br> 例:--------throws <br> public class ExceptionTest4{ <br> public static void p() throws ArithmeticException{ <br> //间接抛出异常,自己并未处理,让方法的调用者来处理 <br> int i; <br> i=4/0;//可能发生异常 <br> System.out.println("8"); <br> } <br>   public static void main(String[] args){     <br> try{ <br> try{ <br>                 p();//方法的直接调用调用者捕获异常处理 <br> }catch(ArithmeticException e){ <br> System.out.println("Divider is zero !"); <br> } <br> }catch(RuntimeException  e){ <br>               System.out.println("4"); <br> } <br>   } <br> } <br> <br> v.java异常处理机制 <br> <br> 答:程序出现想数组角标越界,空指针等错误时,JAVA就会用异 <br> <br> 常Throwable <br> 来描述这些错误,Throwable继承了Object类,同时实现了 <br> <br> Serializable接口, <br> 根据出现的问题是否可以通过程序来解决。把Throwable分为 <br> <br> Error错误和Exception异常,Exception根据编译时是否会被检 <br> 测分为运行时异常RuntimeException和已检测异常 <br> <br> CheckedException。异常的处理方 <br> 式有两种,在发生异常的地方直接使用catch处理,或者将异常抛 <br> <br> 出给调用者,让调用者来处理。 <br>   <br>  1、检查性异常------程序正确,但因为外在的环境条件不满足 <br> <br> 引发。例如:用 <br> 户错误及I/O问题----程序试图打开一个并不存在的远程Socket端 <br> <br> 口。这不是程序 <br> 本身的逻辑错误,而很可能是远程机器名字错误(用户拼写错误) <br> <br> 。对商用软件系统, <br> 程序开发者必须考虑并处理这个问题。JAVA编译器强制要求处理 <br> <br> 这类异常,如果不 <br> 捕获这类异常,程序将不能被编译。 <br>   2、运行期异常------这意味着程序存在bug,如数组越界,0 <br> <br> 被除,入参不满足规 <br> 范.....这类异常需要更改程序来避免,JAVA编译器强制要求处理 <br> <br> 这类异常。 <br>   3、错误------一般很少见,也很难通过程序解决。它可能源 <br> <br> 于程序的bug,但一般 <br> 更可能源于环境问题,如内存耗尽。错误在程序中无须处理,而 <br> <br> 有运行环境处理。 <br> <br> <br> 三、 自定义异常 <br> 当jdk内置异常类型不能满足系统需求时,我们需要自定义异常, <br> <br> 如: <br> public class MyExceptionTest { <br>          public static void main(String[] args) { <br>                   MyExceptionTest mt = new <br> <br> MyExceptionTest(); <br>                   mt.manager(); <br>          } <br> <br>          public void registe(int num) throws MyException{ <br>                   if(num<0){ <br>                            throw new MyException("人数为 <br> <br> 负数",3); <br>                   } <br>                   System.out.println(" 登记人数 <br> <br> 为:"+num); <br>          } <br> <br>          public void manager(){ <br>                   try{ <br>                            registe(-100); <br>                   }catch (MyException e){ <br>                            System.out.println("登记类型出 <br> <br> 错:"+e.getId()); <br>                            e.printStackTrace(); <br>                   }        <br>                   System.out.println(" 操作结束!"); <br>          } <br> } <br> class MyException extends Exception{ <br>          private int id; <br>          public MyException(){} <br>          public MyException(String message,int id){ <br>                   super(message);//调用父类的getMessage() <br>                   //父类中已经定义了getMessage()可以直接 <br> <br> 使用-----------该方法为Exception继承Throwable的 <br>                   this.id=id; <br>          } <br>          public int getId(){ <br>                   return id; <br>          } <br> } <br> <br> 自定义异常类必须要继承Exception/RuntimeException,如果该异 <br> <br> 常的发生无法再继续进行运算,就让它继承RuntimeException <br> 继承的原因是为了让该类自定义类具备可抛型,让该类具备操作 <br> <br> 异常的共性方法 <br> 自定义异常:按照JAVA的OO思想,将程序中出现的特有问题进行 <br> <br> 封装 <br> <br> 四、常见异常 <br> IOException--------------------输入输出异常 <br> ClassNotFoundException-------找不到类异常 <br> NumberFormatException---------字符串到数字格式的异常 <br> FileNotfoundException-----------文件找不到异常 <br> NoSuchMethodException---------------请求方法异常 <br> <br> 运行时异常:RuntimeException <br> SecurityException-----------试图违反安全性异常 <br> NullPointerException----没有实例化却调用其属性和方 <br> <br> 法--------------空指针异常 <br> ArrayIndexOfBoundsException---------数组越界异常 <br> StringIndexOfBoundsException---------字符串越界异常 <br> ArithmeticException--------------算数异常/除数为零异常 <br> NullPointerException-------试图查找null异常 <br> <br> <br> Main方法通常情况下不能把异常抛给JVM <br> <br> Super a = new subclass();//向上转型---- <br> ---overload看左边,override看右边 <br> -----------------------------------多态针对的是方法 <br>   <br> <br> 异常的好处:1、将问题进行封装 <br>             2、将正常流程代码和问题代码进行分离,方便阅读 <br> <br> 处理原则: <br> 1、处理方式有:try或者throws <br> 2、调用到抛出异常的功能时,抛出几个处理几个(一个try对应 <br> <br> 多个catch) <br> 3、多个catch,父类的catch放到最后 <br> 4、Catch内,需要定义针对性的处理方式,不要简单的定义 <br> <br> printStackTrace输出语句,也不要不写 <br> 5、当铺获到的异常,本功能处理不了时,可以继续在catch中抛 <br> <br> 出 <br> <br> 6、  例: <br> try{ <br> throw new AException(); <br> }catch(AException e){ <br> throw e; <br> } <br> <br> 7、如果异常在内部被处理(catch),外部则不需要抛出 <br> <br> 基本格式:catch用来处理异常,如果该异常为检测时异常时,必 <br> <br> 须要处理或者抛出 <br> 异常继承时,子类只能抛出父类的异常或者该异常的子类/子集异 <br> <br> 常,也可以不抛出异常 <br> <br> 异常的注意事项 <br> 1、在子父类覆盖时, <br> a)子类抛出的异常必须是父类异常的子类或子集 <br> b)如果父类或接口没有异常抛出时,子类覆盖出现异常,只能try <br> <br> 不能抛 <br> c)如果父类中是RuntimeException时,子类可以不用抛出异常, <br> <br> 反之,子类为RuntimeException异常,父类为其异常的子类或自 <br> <br> 己都可以编译通过 <br> <br> 1、throw 与throws <br> throw 后跟异常对象(只能有一个),throws后跟异常类(多个 <br> <br> 时用逗号隔开); <br> 位置:throw用在方法体中,代表手工抛异常,throws用在方法声 <br> <br> 明上,代表该方法可能发生异常 <br> <br> 2、RuntimeException和CheckedException的区别 <br> 前者可以不在方法上声明也可以不处理,后者必须要处理或者抛 <br> <br> 出 <br> <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br>                                                            <br> <br>                                                            <br> <br>                                                            <br> <br>                                                            <br> <br>                                                            <br> <br>                                                            <br> <br>                                                           <br> 三、集合(collection、set、list、map) <br> <br> 一、定义: <br> 集合是Java里面最常用的,也是最重要的一部分。能够用好集合 <br> <br> 和理解好集合对于做Java程序的开发拥有无比的好处。 <br> 容器:用来存储数据,不同的容器集合以不同的格式保存对象, <br> <br> 它能够自动的改变这个容器的所能存放的数据数量的大小。这一 <br> <br> 点上,如果使用数组来存储的话,就显得十分的笨拙。 <br> 对于对象集合,必须执行的操作主要以下三种: <br> ?       添加新的对象 <br> ?       删除对象 <br> ?       查找对象 <br> Java容器类类库的用途是“保存对象”,并将其划分为两个不同 <br> <br> 的概念: <br> 1)  Collection 。 一组对立的元素,通常这些元素都服从某种 <br> <br> 规则。List必须保持元素特定的顺序,而Set 不能有重复元素。 <br> 2)  Map 。 一组 成对的“键值对”对象。 <br> <br> ? Collection – 对象之间没有指定的顺序,允许重复元素。 <br> ? Set –  对象之间没有指定的顺序,不允许重复元素 <br> ? List–  对象之间有指定的顺序,允许重复元素,并引入位置下 <br> <br> 标。 <br> ? Map –  接口用于保存关键字(Key)和数值(Value)的集合 <br> <br> ,集合中的每个对象加入时都提供数值和关键字。Map 接口既不 <br> <br> 继承 Set 也不继承 Collection。 <br> List、Set、Map共同的实现基础是Object数组 <br> <br> <br> Collection <br> 1.2.1常用方法 <br> Collection 接口用于表示任何对象或元素组。想要尽可能以常规 <br> <br> 方式处理一组元素时,就使用这一接口。Collection 在前面的大 <br> <br> 图也可以看出,它是List和Set 的父类。并且它本身也是一个接 <br> <br> 口。它定义了作为集合所应该拥有的一些方法。如下: <br> 注意: <br> 集合必须只有对象,集合中的元素不能是基本数据类型。 <br> Collection接口支持如添加和除去等基本操作。设法除去一个元 <br> <br> 素时,如果这个元素存在,除去的仅仅是集合中此元素的一个实 <br> <br> 例。 <br> ?     boolean add(Object element) <br> ?     boolean remove(Object element) <br> Collection 接口还支持查询操作: <br> ?     int size() <br> ?     boolean isEmpty() <br> ?     boolean contains(Object element) <br> ?     Iterator iterator() <br> 组操作 :Collection 接口支持的其它操作,要么是作用于元素 <br> <br> 组的任务,要么是同时作用于整个集合的任务。 <br> ?     boolean containsAll(Collection collection) <br> ?     boolean addAll(Collection collection) <br> ?     void clear() <br> ?     void removeAll(Collection collection) <br> ?     void retainAll(Collection collection) <br> containsAll() 方法允许您查找当前集合是否包含了另一个集合 <br> <br> 的所有元素,即另一个集合是否是当前集合的子集。其余方法是 <br> <br> 可选的,因为特定的集合可能不支持集合更改。 addAll() 方法 <br> <br> 确保另一个集合中的所有元素都被添加到当前的集合中,通常称 <br> <br> 为并。 clear() 方法从当前集合中除去所有元素。 removeAll() <br> <br> 方法类似于 clear() ,但只除去了元素的一个子集。 <br> <br> retainAll() 方法类似于 removeAll() 方法,不过可能感到它所 <br> <br> 做的与前面正好相反:它从当前集合中除去不属于另一个集合的 <br> <br> 元素,即交。 <br>   <br> 集合类的基本方法的使用: <br> import java.util.*; <br> public class CollectionToArray { <br> public static void main(String[] args) { <br> Collection collection1=new ArrayList();//创建一个集合对象 <br> collection1.add("000");//添加对象到Collection集合中 <br> collection1.add("111"); <br> collection1.add("222"); <br> System.out.println("集合collection1的大 <br> <br> 小:"+collection1.size()); <br> System.out.println("集合collection1的内 <br> <br> 容:"+collection1); <br> collection1.remove("000");//从集合collection1中移除掉 <br> <br> "000" 这个对象 <br> System.out.println("集合collection1移除 000 后的内 <br> <br> 容:"+collection1); <br> System.out.println("集合collection1中是否包含000 <br> <br> :"+collection1.contains("000")); <br> System.out.println("集合collection1中是否包含111 <br> <br> :"+collection1.contains("111")); <br> Collection collection2=new ArrayList(); <br> collection2.addAll(collection1);//将collection1 集合中的 <br> <br> 元素全部都加到collection2中 <br> System.out.println("集合collection2的内 <br> <br> 容:"+collection2); <br> collection2.clear();//清空集合 collection1 中的元素 <br> System.out.println("集合collection2是否为空 <br> <br> :"+collection2.isEmpty()); <br> //将集合collection1转化为数组 <br> Object s[]= collection1.toArray(); <br> for(int i=0;i<s.length;i++){ <br> System.out.println(s[i]); <br> } <br> } <br> } <br> 运行结果为: <br> 集合collection1的大小:3 <br> 集合collection1的内容:[000, 111, 222] <br> 集合collection1移除 000 后的内容:[111, 222] <br> 集合collection1中是否包含000 :false <br> 集合collection1中是否包含111 :true <br> 集合collection2的内容:[111, 222] <br> 集合collection2是否为空 :true <br> 111 <br> 222 <br> 这里需要注意的是,Collection 它仅仅只是一个接口,而真正使 <br> <br> 用的时候,却是创建该接口的一个实现类。作为集合的接口,它 <br> <br> 定义了所有属于集合的类所都应该具有的一些方法。 <br> 而ArrayList (列表)类是集合类的一种实现方式。 <br>   <br> Collection的实现基础是数组,所以有转换为Object数组的方法 <br> <br> : <br> ?     Object[] toArray() <br> ?     Object[] toArray(Object[] a) <br> 其中第二个方法Object[] toArray(Object[] a) 的参数 a 应该 <br> <br> 是集合中所有存放的对象的类的父类 <br> <br> 1.2.2  迭代器(Iterator) <br> 迭代器(Iterator)本身就是一个对象,它的工作就是遍历并选 <br> <br> 择集合序列中的对象,而客户端的程序员不必知道或关心该序列 <br> <br> 底层的结构。此外,迭代器通常被称为“轻量级”对象,创建它 <br> <br> 的代价小。但是,它也有一些限制,例如,某些迭代器只能单向 <br> <br> 移动。 <br> Collection 接口的 iterator() 方法返回一个 Iterator。 <br> <br> Iterator 和Enumeration 接口类似。使用 Iterator 接口方法, <br> <br> 可以从头至尾遍历集合,并安全的从底层 Collection 中除去元 <br> <br> 素。 <br> 迭代器的使用: <br> import java.util.ArrayList; <br> import java.util.Collection; <br> import java.util.Iterator; <br>   <br> public class IteratorDemo { <br> public static void main(String[] args) { <br> Collection collection = new ArrayList(); <br> collection.add("s1"); <br> collection.add("s2"); <br> collection.add("s3"); <br> Iterator iterator = collection.iterator();//得到一个迭代 <br> <br> 器 <br> while (iterator.hasNext()) {//遍历 <br> Object element = iterator.next(); <br> System.out.println("iterator = " + element); <br> } <br> if(collection.isEmpty()) <br> System.out.println("collection is Empty!"); <br> else <br> System.out.println("collection is not Empty! <br> <br> size="+collection.size()); <br> Iterator iterator2 = collection.iterator(); <br> while (iterator2.hasNext()) {//移除元素 <br> Object element = iterator2.next(); <br> System.out.println("remove: "+element); <br> iterator2.remove(); <br> } <br> Iterator iterator3 = collection.iterator(); <br> if (!iterator3.hasNext()) {//察看是否还有元素 <br> System.out.println("还有元素"); <br> } <br> if(collection.isEmpty()) <br> System.out.println("collection is Empty!"); <br> //使用collection.isEmpty()方法来判断 <br> } <br> } <br> 程序的运行结果为: <br> iterator = s1 <br> iterator = s2 <br> iterator = s3 <br> collection is not Empty! size=3 <br> remove: s1 <br> remove: s2 <br> remove: s3 <br> 还有元素 <br> collection is Empty! <br> 可以看到,Java的Collection的Iterator 能够用来,: <br> 1)使用方法 iterator() 要求容器返回一个Iterator .第一次调 <br> <br> 用Iterator 的next() 方法时,它返回集合序列的第一个元素。 <br> 2)使用next() 获得集合序列的中的下一个元素。 <br> 3)使用hasNext()检查序列中是否元素。 <br> 4)使用remove()将迭代器新返回的元素删除。 <br> 需要注意的是:方法删除由next方法返回的最后一个元素,在每 <br> <br> 次调用next时,remove方法只能被调用一次 。 <br> <br> 1.3 List <br> 1.3.1概述 <br> Collection接口实际上并没有直接的实现类。而List是容器的一 <br> <br> 种,表示列表的意思。当我们不知道存储的数据有多少的情况, <br> 我们就可以使用List 来完成存储数据的工作。例如保存一个应用 <br> <br> 系统当前的在线用户的信息。List的最大的特点就是能够自动 <br> 的根据插入的数据量来动态改变容器的大小。 <br> <br> 1.3.2  常用方法 <br> List 就是列表的意思,它是Collection 的一种,即继承了 <br> <br> Collection 接口,又定义一个允许重复项的有序集合。该接口不 <br> <br> 但 <br> 能够对列表的一部分进行处理,还添加了面向位置的操作。List <br> <br> 是按对象的进入顺序进行保存对象,而不做排序或编辑操作。它 <br> 除了拥有Collection接口的所有的方法外还拥有一些其他的方法 <br> <br> 。面向位置的操作包括插入某个元素或 Collection 的功能,还 <br> 包括获取、除去或更改元素的功能。在 List 中搜索元素可以从 <br> <br> 列表的头部或尾部开始,如果找到元素,还将报告元素所在的位 <br> <br> 置。 <br> <br> 1、 void add(int index, Object element):添加对象element <br> <br> 到位置index上 <br> 2、 boolean addAll(int index, Collection collection):在 <br> <br> index位置后添加容器collection中所有的元素 <br> 3、 Object get(int index) :取出下标为index的位置的元素 <br> 4、 int indexOf(Object element) :查找对象element 在List <br> <br> 中第一次出现的位置 <br> 5、 int lastIndexOf(Object element) :查找对象element 在 <br> <br> List中最后出现的位置 <br> 6、 Object remove(int index) :删除index位置上的元素 <br> 7、 Object set(int index, Object element) :将index位置上 <br> <br> 的对象替换为element 并返回老的元素。 <br> <br> List(提供基于索引的对成员的随机访问)------ArrayList----- <br> <br> 提供快速的基于索引的成员访问,对尾部成员的增加和删除支持 <br> <br> 较好 <br>   成员可为任意Object子类的对象 <br> ----------LinkedList-----对列表中任何位置的成员的增加和删 <br> <br> 除支持较好,但对基于索引的成员访问支持性能较差 <br>   成员可为任意Object子类的对象 <br>           <br> 在“集合框架”中有两种常规的 List 实现:ArrayList 和 <br> <br> LinkedList。使用两种 List 实现的哪一种取决于您特定的需要 <br> <br> 。如果要 <br> 支持随机访问,而不必在除尾部的任何位置插入或除去元素,那 <br> <br> 么,ArrayList 提供了可选的集合。但如果,您要频繁的从列表 <br> <br> 的中间 <br> 位置添加和除去元素,而只要顺序的访问列表元素,那么, <br> <br> LinkedList 实现更好。 <br> <br> LinkedList 来实现一个简单的队列的例子: <br> import java.util.*; <br>   <br> public class ListExample { <br>   public static void main(String args[]) { <br>     LinkedList queue = new LinkedList(); <br>     queue.addFirst("Bernadine"); <br>     queue.addFirst("Elizabeth"); <br>     queue.addFirst("Gene"); <br>     queue.addFirst("Elizabeth"); <br>     queue.addFirst("Clara"); <br>     System.out.println(queue); <br>     queue.removeLast(); <br>     queue.removeLast(); <br>     System.out.println(queue); <br>   } <br> } <br> 运行程序产生了以下输出。请注意,与 Set 不同的是 List 允许 <br> <br> 重复。 <br> [Clara, Elizabeth, Gene, Elizabeth, Bernadine] <br> [Clara, Elizabeth, Gene] <br> 该的程序演示了具体 List 类的使用。第一部分,创建一个由 <br> <br> ArrayList 支持的 List。填充完列表以后,特定条目就得到了。 <br> <br> 示例 <br> 的 LinkedList 部分把 LinkedList 当作一个队列,从队列头部 <br> <br> 添加东西,从尾部除去。 <br> <br> List 接口不但以位置友好的方式遍历整个列表,还能处理集合的 <br> <br> 子集: <br> ListIterator listIterator() :返回一个ListIterator 跌代器 <br> <br> ,默认开始位置为0 <br> ListIterator listIterator(int startIndex) :返回一个 <br> <br> ListIterator 跌代器,开始位置为startIndex <br> List subList(int fromIndex, int toIndex) :返回一个子列表 <br> <br> List ,元素存放为从 fromIndex 到toIndex之前的一个元素。 <br> 处理 subList() 时,位于 fromIndex 的元素在子列表中,而位 <br> <br> 于 toIndex 的元素则不是,提醒这一点很重要。 <br> <br> for-loop : <br> for (int i=fromIndex; i<toIndex; i++) { <br>   // process element at position i <br> } <br> <br> 对子列表的更改(如 add()、remove() 和 set() 调用)对底层 <br> <br> List 也有影响。 <br> <br> <br> 我们看一个List的例子: <br> import java.util.*; <br>   <br> public class ListIteratorTest { <br> public static void main(String[] args) { <br> List list = new ArrayList(); <br> list.add("aaa"); <br> list.add("bbb"); <br> list.add("ccc"); <br> list.add("ddd"); <br> System.out.println("下标0开始:"+list.listIterator <br> <br> (0).next());//next() <br> System.out.println("下标1开始:"+list.listIterator <br> <br> (1).next()); <br> System.out.println("子List 1-3:"+list.subList(1,3));//子 <br> <br> 列表 <br> ListIterator it = list.listIterator();//默认从下标0开始 <br> //隐式光标属性add操作 ,插入到当前的下标的前面 <br> it.add("sss"); <br> while(it.hasNext()){ <br> System.out.println("next Index="+it.nextIndex <br> <br> ()+",Object="+it.next()); <br> } <br> //set属性 <br> ListIterator it1 = list.listIterator(); <br> it1.next(); <br> it1.set("ooo"); <br> ListIterator it2 = list.listIterator(list.size());//下标 <br> while(it2.hasPrevious()){ <br> System.out.println("previous Index="+it2.previousIndex <br> <br> ()+",Object="+it2.previous()); <br> } <br> } <br> } <br> 程序的执行结果为: <br> 下标0开始:aaa <br> 下标1开始:bbb <br> 子List 1-3:[bbb, ccc] <br> next Index=1,Object=aaa <br> next Index=2,Object=bbb <br> next Index=3,Object=ccc <br> next Index=4,Object=ddd <br> previous Index=4,Object=ddd <br> previous Index=3,Object=ccc <br> previous Index=2,Object=bbb <br> previous Index=1,Object=aaa <br> previous Index=0,Object=ooo <br> 我们还需要稍微再解释一下 add() 操作。添加一个元素会导致新 <br> <br> 元素立刻被添加到隐式光标的前面。因此,添加元素后调用 <br> previous() 会返回新元素,而调用 next() 则不起作用,返回添 <br> <br> 加操作之前的下一个元素。下标的显示方式,如下图所示: <br> <br> 1.3.3实现原理 <br> ArrayList中主要包含2个属性: <br> private transient Object elementData[]; <br> private int size; <br> 其中数组::elementData[] 是列表的实现核心属性:数组。 我 <br> <br> 们使用该数组来进行存放集合中的数据。而我们的初始化参数就 <br> 是该数组构建时候的长度,即该数组的length属性就是 <br> <br> initialCapacity 参数。 <br> <br> Keys:transient 表示被修饰的属性不是对象持久状态的一部分 <br> <br> ,不会自动的序列化。 <br> <br> 如果要判断一个类的一个实例对象是否等于另外一个对象,那么 <br> <br> 我们就需要自己覆写Object类的public boolean equals(Object <br> <br> obj) <br>  方法。如果不覆写该方法的话,那么就会调用Object的equals() <br> <br> 方法来进行判断。这就相当于比较两个对象的内存应用地址是否 <br> <br> 相等了。 <br> 在集合框架中,不仅仅是List,所有的集合类,如果需要判断里 <br> <br> 面是否存放了的某个对象,都是调用该对象的equals()方法来进 <br> <br> 行处理的。 <br> <br> 集合的个数用size();数组用length;String用length(); <br> <br> Collection<E> extends Iterable <br> <br> 方法: <br> 增          add();addAll()---------boolean <br> 删          remove();removeAll();------------boolean <br>                  clear()-------void <br> 查          Iterator<E>()--------Iterator <br> 改          toArray()-----Object   数组 <br> 元素数      size()--------------int <br> <br> List<E>  extends Collection<E>----------有序的Collection, <br> <br> 可重复 <br> <br> 新增方法: <br> add(int index, E element)//在指定位置添加---------添加顺 <br> <br> 序要是连续的 <br> get(int index)//返回指定位置 <br> listIterator(int index)//从指定位置开始迭代 <br> <br> AbstractList<E> extends AbstractCollection<E> implements <br> <br> List<E> <br> <br> Set<E> <br> 无序的不可重复的Collection <br> <br> Map<K,V> <br> 键K不可以重复,值V可以重复 <br> <br> ArrayList------------在查询时快,增删改时慢 <br> <br> 例: <br> import java.util.*; <br> //注解 <br> //@SuperessWarnings("unchecked")--------- <br> <br> public class Demo{ <br> public static void main(String[] args) { <br> List<Object> alist = new ArrayList<Object>();//List是接口 <br> <br> ,不能被实例化 <br> <br> //增加 <br> alist.add("123"); <br> alist.add(new StringBuffer("1s1")); <br> alist.add(3.4f); <br> alist.add(3.01d); <br> alist.add(1,222);//[123, 222, 323] <br> <br> alist.add("123");//[123, 222, 323, 123]----------可重复 <br> System.out.println(alist);//相当于toString() <br> System.out.println("长度为:"+alist.size()); <br> System.out.println("------------------------------"); <br> //删除 <br> alist.remove(2);//角标 <br> System.out.println(alist); <br> //alist.clear(); <br> alist.remove("123");//移除的是第一次出现的 <br> System.out.println(alist); <br> System.out.println(alist.isEmpty()); <br> System.out.println("------------------------------"); <br> //遍历 <br> //第一种: <br> for(int i=0;i<alist.size();i++){ <br> Object e = alist.get(i); <br> if(e instanceof String){//Object inteanceof 类型----判断 <br> <br> 类型是否是Object的实例 <br> System.out.println(((String)e).length()); <br> }else if(e instanceof Double){ <br> System.out.println(((Double)e).intValue()); <br> } <br> } <br> <br> //第二种: <br> for(Object e:alist){ <br> System.out.println(e); <br> } <br> System.out.println("------------------------------"); <br> //List<Integer> alist1 = new ArrayList<Integer>(); <br> int size = alist.size(); <br> System.out.println(" size="+size); <br> boolean flag = alist.isEmpty();//判断是否为空 <br> System.out.println(" flag="+flag); <br> System.out.println("------------------------------"); <br> //第三种:Iterable-----迭代器输出 <br> //Iterable Iterator<T>iterator(); <br> Iterator<Object> it = alist.iterator();//Iterator与 <br> <br> Iterable无关,是两个接口 <br> while(it.hasNext()){ <br> Object i = it.next(); <br> System.out.println(i); <br> } <br> //System.out.println(alist.iterator()); <br> System.out.println("--------------------------------"); <br> //第一种: <br> for(int i=0;i<alist.size();i++){//注意:size()是动态变化 <br> <br> 的 <br> System.out.print(alist.get(i)+",");//按照下标获取 <br> } <br> System.out.println(" "); <br> System.out.println("--------------------------------"); <br> //第四种: <br> for(Iterator it2 = alist.iterator();it2.hasNext();){ <br> System.out.println(it2.next()); <br> } <br> //转换 <br> //alist.toArray(); <br> //System.out.println(alist); <br> <br> } <br> } <br> <br> <br> LinkedList-----------增删改快,查询慢 <br> 例: <br> import java.util.*; <br> public class  Demo1{ <br> public static void main(String[] args) { <br> Queue<Integer> link = new LinkedList<Integer>(); <br> //Queue是单端队列----------单链表 <br> link.add(21); <br> link.offer(111);//队尾添加========>add <br> link.poll();//队头删除 <br> System.out.println(link.remove()); <br> link.poll();//为空时返回null==========>remove <br> System.out.println(link.poll()); <br> link.peek();//访问=========>get <br> //link.remove();为空时异常 <br> System.out.println(link.size()); <br> System.out.println <br> <br> ("-------------------------------------"); <br> <br> Deque<Object> dl = new LinkedList<Object>(); <br> //Deque是双端队列--------双向链表 <br> --------------------------------------------------------- <br> <br> ---------------------- <br> 第一个元素(头部)             最后一个元素(尾部) <br> <br>                抛出异常     特殊值          抛出异常       <br> <br>  特殊值 <br> <br> 插入 addFirst(e)   offerFirst(e)   addLast(e)      <br> <br> offerLast(e) <br> 移除 removeFirst() pollFirst()     removeLast()    <br> <br> pollLast() <br> 检查 getFirst()    peekFirst()     getLast()       <br> <br> peekLast() <br> --------------------------------------------------------- <br> <br> ---------------------- <br> //add、offer默认在尾部增加 <br> //remove、poll默认从第一个开始删除 <br> <br> dl.add(123);//默认在尾部增加 <br> dl.addFirst("sss"); <br> dl.offerFirst(231); <br> dl.addLast(2212); <br> dl.offerLast(654); <br> System.out.println(dl); <br> <br> System.out.println("-------------------1 <br> <br> ---------------"); <br> //dl.removeFirst(); <br> //System.out.println(dl); <br> //System.out.println("------------------2 <br> <br> ----------------"); <br> dl.pollLast(); <br> System.out.println(dl); <br> System.out.println("-----------------3 <br> <br> -----------------"); <br> <br>         System.out.println(dl.getFirst()); <br> <br> System.out.println("-----------------4 <br> <br> -----------------"); <br> dl.peek(); <br> System.out.println(dl); <br> } <br> } <br> <br> <br> 注意:所有的集合框架都位于java.util包中,使用前必须导入该 <br> <br> 包中的类 <br> 熟悉并记忆以下接口之间的关系和相关方法 <br> Iterable--------->接口(java.lang) <br>         常见方法1:Iterator<T> iterator() <br>  Iterator--------->接口 <br>         常见方法1:boolean hasNext() <br>         常见方法2:E   next() <br>  Collection------->Iterable-------------->接口 <br>          常见方法1:int size() <br>          常见方法2:boolean isEmpty() <br>  常见方法3:void clear() <br>          常见方法4:boolean  add(E e) <br>  常见方法5:remove() <br>  List(线性表)----->Collection------- <br> <br> >Iterable-------------->接口 <br>          常见方法1:add(int index,E e) <br>  常见方法2:remove(int index,E e) <br>    常见方法3:E get(int index) <br>  Queue(队列)----->Collection------- <br> <br> >Iterable-------------->接口 <br>          常见方法1:offer(E e)   <br>  常见方法2:poll() <br>    常见方法3:E peek() <br>  Deque(双端队列)----->Queue----->Collection------- <br> <br> >Iterable-------------->接口 <br>          常见方法1:offerFirst(E e)和offerLast(E e) <br>  常见方法2:pollFirst()和pollLast <br>    常见方法3:E peekFirst()和peekLast <br> ArrayList-->AbstractList-->List--->Collection--- <br> <br> >Iterator--------->类 <br> LinkedList--->AbstractList-->List--->Collection--- <br> <br> >Iterator--------->类 <br>                     --->Deque---->Queue-----> <br> Vector--->AbstractList-->List--->Collection--- <br> <br> >Iterator--------->类 <br> Stack-->Vector--->AbstractList-->List--->Collection--- <br> <br> >Iterator--------->类 <br>          常见方法1:E pop() <br>  常见方法2:E push(E e) <br>  常见方法3:E peek() <br>    常见方法4:boolean empty() <br> stack-----------后进先出---一端 <br> <br> <br> 无序的不可重复的(判断重复的标准是hashCode()+equals()), <br> <br> 如果重复定义则会覆盖 <br> LinkedSet---------------重复时保留第一个 <br> TreeSet-------------(String)按照ASCll码进行排序 <br> <br> 加载因子:加载因子 是哈希表在其容量自动增加之前可以达到多 <br> <br> 满的一种尺度。当哈希 <br> 表中的条目数超出了加载因子与当前容量的乘积时,通过调用 <br> <br> rehash 方法将容量翻倍。 <br> 通常,默认加载因子 (.75) 在时间和空间成本上寻 求一种折衷 <br> <br> 。加载因子过高虽然减少 <br> 了空间开销,但同时也增加了查询成本(在大多数 Hashtable类 <br> <br> 的操作中,包括 get 和 <br> put 操作,都反映了这一点)。在设置初始容量时应该考虑到映 <br> <br> 射中所需的条目数及其加 <br> 载因子,以便最大限度地降低 rehash 操作次数。如果初始容量 <br> <br> 大于最大条目数除以加载 <br> 因子,则不会发生 rehash 操作 <br> <br> List默认容量10,HashSet默认容量16,加载因子0.75; <br> <br> HashMap 的实例有两个参数影响其性能:初始容量 和加载因子。 <br> <br> 容量是哈希表中桶的数量, <br> 初始容量只是哈希表在创建时的容量。加载因子 是哈希表在其容 <br> <br> 量自动增加之前可以达到 <br> 多满的一种尺度。当哈希表中的条目数超出了加载因子与当前容 <br> <br> 量的乘积时,则要对该哈希 <br> 表进行 rehash 操作(即重建内部数据结构),从而哈希表将具 <br> <br> 有大约两倍的桶数。 <br> <br> 在比较时可以自定义一个比较方式,此类必须要继承 <br> <br> Comparable<T>接口,并实现compareTo( T t){ ----重写 <br> <br> toString()输出 <br>     <br>  return -1|0|1;      //  <|=|> <br> } <br> <br> import java.util.*; <br> public class HashSetTest{ <br> public static void main(String[] args) { <br> /*Set<String> set1 = new LinkedHashSet<String>(); <br> set1.add("sds"); <br> set1.add("2sa"); <br> set1.add("213"); <br> set1.add("213"); <br> System.out.println(set1);//无序 <br> System.out.println <br> <br> ("--------------------------------------"); <br> Set<String> set2 = new HashSet<String>(); <br> set2.add("sds"); <br> set2.add("213"); <br> set2.add("2sa"); <br> set2.add("213"); <br> System.out.println(set2);//按插入顺序输出 <br> System.out.println <br> <br> ("--------------------------------------"); <br> <br> Set<String> set3 = new TreeSet<String>(); <br> set3.add("sds"); <br> set3.add("213"); <br> set3.add("2sa"); <br> set3.add("213"); <br> System.out.println(set3); //排序 <br> System.out.println <br> <br> ("--------------------------------------"); <br> */ <br> Set<Cat> set=new TreeSet<Cat>(); <br> Cat c1=new Cat(2,"red"); <br> Cat c2=new Cat(1,"black"); <br> Cat c3=new Cat(3,"white"); <br> set.add(c1); <br> set.add(c2); <br> set.add(c3); <br> System.out.println(set.toString()); <br> } <br> } <br> <br> class Cat implements Comparable<Cat>{ <br> private int age; <br> private String color; <br> public Cat(int age,String color){ <br> this.age=age; <br> this.color=color; <br> } <br> public String toString(){ <br> return "{age="+age+" , color="+color+"}"; <br> } <br>     public int compareTo(Cat o){ <br>   if(this.age>o.age){ <br>             return 1; <br>   }else{ <br>     return -1; <br>   } <br>    } <br> } <br> //---------- java ---------- <br> //[{age=1 , color=black}, {age=2 , color=red}, {age=3 , <br> <br> color=white}] <br> <br> LinkedHashSet--->HashSet----->AbstractSet----->Set--- <br> <br> >Collection------>Iterable <br>                                 TreeSet------ <br> <br> >AbstractSet----->Set--->Collection------>Iterable <br>                                 TreeSet------ <br> <br> >SortedSet------>Set---->Collection------>Iterable <br> <br> <br> <br> Map <br> <br>  泛型擦除----------类型擦除 <br>      类型擦除指的是通过类型参数合并,将泛型类型实例关联到 <br> <br> 同一份字节码上。编译器只为泛型类型生成一份字 <br> 节码,并将其实例关联到这份字节码上。类型擦除的关键在于从 <br> <br> 泛型类型中清除类型参数的相关信息,并且再 <br> 必要的时候添加类型检查和类型转换的方法。 <br>      类型擦除可以简单的理解为将泛型java代码转换为普通java <br> <br> 代码,只不过编译器更直接点,将泛型java <br> 代码直接转换成普通java字节码。 <br>       <br>    类型擦除的主要过程如下: <br>      1.将所有的泛型参数用其最左边界(最顶级的父类型)类型 <br> <br> 替换。 <br>      2.移除所有的类型参数,如: <br> interface Comparable <A> { <br>   public int compareTo( A that); <br> } <br> final class NumericValue implements Comparable <br> <br> <NumericValue> { <br>   priva te byte value;   <br>   public  NumericValue (byte value) { this.value = value; <br> <br> }   <br>   public  byte getValue() { return value; }   <br>   public  int compareTo( NumericValue t hat) { return <br> <br> this.value - that.value; } <br> } <br> ----------------- <br> class Collections {   <br>   public static <A extends Comparable<A>>A max(Collection <br> <br> <A> xs) { <br>     Iterator <A> xi = xs.iterator(); <br>     A w = xi.next(); <br>     while (xi.hasNext()) { <br>       A x = xi.next(); <br>       if (w.compareTo(x) < 0) w = x; <br>     } <br>     return w; <br>   } <br> } <br> final class Test { <br>   public static void main (String[ ] args) { <br>     LinkedList <NumericValue> numberList = new LinkedList <br> <br> <NumericValue> (); <br>     numberList .add(new NumericValue((byte)0));   <br>     numberList .add(new NumericValue((byte)1));   <br>     NumericValue y = Collections.max( numberList );   <br>   } <br> } <br> 经过类型擦除后的类型为 <br>  interface Comparable { <br>   public int compareTo( Object that); <br> } <br> final class NumericValue implements Comparable { <br>   priva te byte value;   <br>   public  NumericValue (byte value) { this.value = value; <br> <br> }   <br>   public  byte getValue() { return value; }   <br>   public  int compareTo( NumericValue t hat)   { return <br> <br> this.value - that.value; } <br>   public  int compareTo(Object that) { return <br> <br> this.compareTo((NumericValue)that);  } <br> } <br> ------------- <br> class Collections {   <br>   public static Comparable max(Collection xs) { <br>     Iterator xi = xs.iterator(); <br>     Comparable w = (Comparable) xi.next(); <br>     while (xi.hasNext()) { <br>       Comparable x = (Comparable) xi.next(); <br>       if (w.compareTo(x) < 0) w = x; <br>     } <br>     return w; <br>   } <br> } <br> final class Test { <br>   public static void main (String[ ] args) { <br>     LinkedList numberList = new LinkedList(); <br>     numberList .add(new NumericValue((byte)0));  , <br>     numberList .add(new NumericValue((byte)1));   <br>     NumericValue y = (NumericValue) Collections.max( <br> <br> numberList );   <br>   } <br> } <br> 第一个泛型类Comparable <A>擦除后 A被替换为最左边界Object <br> <br> 。Comparable<NumericValue>的类 <br> 型参数NumericValue被擦除掉,但是这直 接导致NumericValue没 <br> <br> 有实现接口Comparable的compareTo(Object that) <br> 方法,于是编译器充当好人,添加了一个桥接方法。 <br> 第二个示例中限定了类型参数的边界<A extends <br> <br> Comparable<A>>A,A必须为Comparable<A>的子类 <br> ,按照类型擦除的过程,先讲所有的类型参数 ti换为最左边界 <br> <br> Comparable<A>,然后去掉参数类型A, <br> 得到最终的擦除后结果。 <br> <br> <br> <br> Collection 和 Collections的区别。 <br> <br> Collection是个java.util下的接口,它是各种集合结构的父接口 <br> <br> 。继承与他的接口主要有Set 和List. <br> Collections是个java.util下的专用静态类,它包含有各种有关 <br> <br> 集合操作的静态方法。提供一系列静态 <br> 方法实现对各种集合的搜索、排序、线程安全化等操作。 <br> <br> Array与Arrays的区别。 <br> <br> 1.数组类Array,是Java中最基本的一个存储结构。提供了动态 <br> <br> 创建和访问 Java 数组的方法。其中的 <br> 元素的类型必须相同。效率高,但容量固定且无法动态改变。 它 <br> <br> 无法判断其中实际存有多少元素, <br> length只是告诉我们array的容量。 <br> 2、Arrays类,此静态类专门用来操作array ,提供搜索、排序、 <br> <br> 复制等静态方法。equals():比较两个 <br> array是否相等。array拥有相同元素个数,且所有对应元素两两 <br> <br> 相等。 sort():用来对array进行排序。 <br>  binarySearch():在排好序的array中寻找元素。 <br> <br> collections <br> 例: <br> import java.util.*; <br> public class CollectionsDemo { <br> public static void main(String[] args) { <br> List<String> sl = new ArrayList<String>(); <br> sl.add("jhn"); <br> sl.add("ncgcxs"); <br> sl.add("rgd"); <br> sl.add("ceaz"); <br> sl.add("vfe"); <br> sl.add("byt"); <br> sl.add("fe"); <br> Collections.sort(sl); <br> System.out.println(sl); <br> //Collections.binarySearch(1); <br> //Collections.copy(sl); <br> System.out.println(Collections.max(sl));//max <br> System.out.println(Collections.min(sl));//min <br> Collections.reverse(sl);//反转 <br> System.out.println(sl); <br> Collections.shuffle(sl);//打散 <br> System.out.println(sl); <br> } <br> <br> <br> HashMap遍历的两种方式 <br> <br> 第一种: <br> Map map = new HashMap(); <br> Iterator iter = map.entrySet().iterator(); <br> while (iter.hasNext()) { <br>     Map.Entry entry = (Map.Entry) iter.next(); <br>     Object key = entry.getKey(); <br>     Object val = entry.getValue(); <br> } <br> 效率高,以后一定要使用此种方式! <br> 第二种: <br> Map map = new HashMap(); <br> Iterator iter = map.keySet().iterator(); <br> while (iter.hasNext()) { <br>     Object key = iter.next(); <br>     Object val = map.get(key); <br> } <br> 效率低,以后尽量少使用! <br> <br> HashMap 与 TreeMap的区别 <br>     集合框架”提供两种常规的Map实现:HashMap和TreeMap <br> <br> (TreeMap实现SortedMap接口)。在Map <br> 中插入、删除和定位元素,HashMap 是最好的选择。但如果您要 <br> <br> 按自然顺序或自定义顺序遍历键,那 <br> 么TreeMap会更好。使用HashMap要求添加的键类明确定义了 <br> <br> hashCode()和equals()的实现。这个TreeMap <br> 没有调优选项,因为该树总处于平衡状态。 <br> <br> TreeMap <br> (http://www.cnblogs.com/hzmark/archive/2013/01/02/TreeMa <br> <br> p-Base.html) <br> Java 集合系列目录(Category) <br> (http://www.cnblogs.com/skywang12345/p/3323085.html) <br> <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br>                                                            <br> <br>                                                            <br> <br>                                <br> <br> 四、I/O流、File <br> <br> File--------java.io.File--------文件和目录路径名的抽象表 <br> <br> 示形式 <br> <br> 常用方法: <br> createNewFile(" ")---------创建文件 <br> delete(" ") <br> exists()-----------测试是否存在 <br> getName()---------获得文件名 <br> <br> 例: <br> String path = File.separator;//与系统有关的默认名称分隔符 <br> File f = new File("c:"+path+"c.txt"); <br> ystem.out.println(f.createNewFile()); <br> <br> <br> <br> 例:import java.io.*; <br> public class FileDemo { <br> public static void main(String[] args) throws <br> <br> IOException{ <br> /* <br> File f = new File("c:\\Users\\Rainlate\\Desktop\ <br> <br> \123.txt");//注意\的转义字符 <br> //构建实例不代表创建文件 <br> boolean b =f.createNewFile();//创建文件 <br> f.mkdirs();//创建前不必有父目录 <br> //f.createTempFile(sd,jsp);//使用给定前缀和后缀生成其名称 <br> <br> 创建空文件 <br> //f.createTempFile(23,txt, null);//使用给定前缀和后缀生成 <br> <br> 其名称 <br> //boolean d1 = f.delete();//删除此抽象路径名表示的文件或 <br> <br> 目录。如果此路径名表示一个目录,则该目录必须为空才能删除 <br> System.out.println(f.exists());//是否存在文件 <br> System.out.println(f.getName());//123.txt <br> String path = File.separator; <br> File f = new File("c:"+path+"c.txt"); <br> System.out.println(f.createNewFile()); <br> String a = File.separator; <br> String path="c:"+a+"Users"+a+"Rainlate"+a+"Desktop"+a <br> <br> +"1"; <br> File f = new File(path); <br> File[] files = new listFiles(f); <br> for(String file:files){ <br> System.out.println(file); <br> } <br> */ <br> File x= new File("c:\\Users\\Rainlate\\Desktop\\1"); <br> show(x); <br> } <br> <br> public static void show(File f){//递归输出源目录下的所有 <br> <br> 文件 <br> if(f.isDirectory()){//判断是否为目录 <br> File[] files =f.listFiles(); <br> for(int i=0;i<files.length;i++){ <br> show(files[i]); <br> } <br> }else{ <br> System.out.println(f.getPath()); <br> } <br> } <br> } <br> <br> <br> IO流: <br> 第一,确定方向-----------输入输出是以程序为中心 <br> 第二,确定是字节还是字符【若是字符型文本使用字符流,其他 <br> <br> 使用字节流】 <br> 第三,确定是否需要缓冲【autoFlush、Flush】----------缓冲 <br> <br> 流是用空间换时间 <br> 第四,所有操作必须关闭【在finally关闭】 <br> <br> 例1; <br> import java.io.*; <br> public class  FileInputStreamDemo{//文本复制 <br> public static void main(String[] args) { <br> String a = File.separator;//与系统有关的默认名称分隔符 <br> FileInputStream fin = null; <br> //FileOutputStream fo = null; <br> BufferedOutputStream fo = null; <br> try{ <br> fin = new FileInputStream("C:"+a+"Users"+a+"Rainlate"+a <br> <br> +"Desktop"+a+"123.docx"); <br> byte[] b = new byte[512];//存储读取数据的缓冲区 <br> long start = System.currentTimeMillis(); <br> int size = fin.read(b,0,b.length); <br> //fo = new FileOutputStream("C:"+a+"Users"+a <br> <br> +"Rainlate"+a+"Desktop"+a+"12.java"); <br> fo = new BufferedOutputStream (new FileOutputStream <br> <br> ("C:"+a+"Users"+a+"Rainlate"+a+"Desktop"+a+"12.docx")); <br> while(size != -1){ <br> fo.write(b,0,size);//文件的实际大小 <br> fo.flush(); <br> size = fin.read(b,0,b.length); <br> } <br> long late = System.currentTimeMillis(); <br> System.out.println(late-start); <br> }catch (FileNotFoundException e){ <br> System.out.println(e.getMessage()); <br> }catch(IOException e){ <br> System.out.println(e.getMessage()); <br> }finally{ <br> try{ <br> fin.close();//关闭输入流 <br>         fo.close();//关闭输出流 <br> }catch (IOException e){ <br> System.exit(1);//异常退出 <br> } <br> } <br> } <br> } <br> <br> 例2: <br> import java.io.*; <br> public class ObjectSerializable { <br> public static void main(String[] args) { <br> Person p = new Person(32,"huhu"); <br> String a = File.separator; <br> ObjectOutputStream ou =null;//序列化 <br> ObjectInputStream oin = null;//反序列化 <br> try{ <br> ou = new ObjectOutputStream(new FileOutputStream("C:"+a <br> <br> +"Users"+a+"Rainlate"+a+"Desktop"+a+"1.txt")); <br> ou.writeObject(p);//对象序列化 <br> ou.flush(); <br> <br> //反序列化 <br> oin = new ObjectInputStream(new FileInputStream("C:"+a <br> <br> +"Users"+a+"Rainlate"+a+"Desktop"+a+"1.txt")); <br> Object obj = oin.readObject(); <br> Person as = (Person)obj; <br> System.out.println(as); <br> out.flush(); <br> }catch (FileNotFoundException e){ <br> System.out.println(e.getMessage()); <br> }catch(IOException e){ <br> System.out.println(e.getMessage()); <br> }catch(ClassNotFoundException e){ <br> System.out.println(e.getMessage()); <br> }finally{ <br> try{ <br> out.close(); <br> }catch (IOException e){ <br> System.exit(1); <br> } <br> } <br> } <br> } <br> <br> class Person implements Serializable { <br> private int age; <br> private String name; <br> public Person(int age,String name){ <br> this.age=age; <br> this.name=name; <br> } <br> public String toString(){ <br> return "name="+this.name+",age="+this.age; <br> } <br> } <br> <br> <br> 序列化的版本号(serialVersionUID=1L)? <br> 作用:就是确保了不同版本之间的兼容性,不仅能够向前兼容, <br> <br> 还能够向后兼容,即在版本升级时反序列化仍保持对象的唯一性 <br> <br> 。 <br> 它有两种生成方式:        <br>        一个是默认的1L,比如:private static final long <br> <br> serialVersionUID = 1L; <br>        一个是根据类名、接口名、成员方法及属性等来生成一个 <br> <br> 64位的哈希字段,比如:  private static final long <br> <br> serialVersionUID = xxxxL <br> <br> <br> 类图结构 <br>   ┌BufferedReader <br>   ├InputStream──FileReader <br>   ├StringReader <br> ┌Reader─┤ <br> │   ├PipedReader <br> │   ├ByteArrayReader <br> │   └FileReader──PushbackReader <br> 字符流─┤ <br> │   ┌BufferedWriter <br> │   ├OutputStreamWriter──FileWriter <br> │   ├PrinterWriter <br> └Writer─┼StringWriter <br>   ├PipedWriter <br>   ├CharArrayWriter <br>   └FileWriter <br> <br> <br> ┌FileInputStream <br> │ ┌BufferedInputStream <br> ├FilterInputStream ──┼DataInputStream <br> │ └PushbackInputStream <br> ┌InputStream ─┼ObjectInputStream <br> │ ├PipedInputStream <br> │ ├SequenceInputStream <br> │ ├StringBufferInputStream <br> │ └ByteArrayInoutStream <br> 字节流─┤ <br> │ <br> │  ┌FileOutputStream <br> │  │   ┌BufferedOutputStream <br> │  ├FilterOutputStream ──┼DataOutputStream <br> └OutputStream ─┤   └PrintStream <br>  ├ObjectOutputStream <br>  ├PipedOutputStream <br> <br> <br> <br> IO流------ <br> <br> (http://developer.51cto.com/art/201309/410913.htm) <br> <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br>                                                            <br> <br>                                                            <br> <br>                                <br> <br> JDK1.5新特性: <br> <br> 七、枚举 <br> 枚举是一个类类型,是JDK1.5的新特性 <br> <br> 枚举的关键字是enum <br> <br> Java中所有的枚举类都是java.lang.Enum的子类 <br> <br> 注意:枚举类中可以包含成员有【字段(常量)、方法(构造方 <br> <br> 法、普通方法)】 <br> <br> 枚举中不能有number;不能赋值------------类 <br> <br>  只有顺序可以比较----------- <br> <br> 语法: <br> <br> enum 枚举名{ <br> <br>          枚举体 <br> <br> } <br> <br> 例: <br> <br> enum Direction{//枚举体 <br> <br>          EAST,SOUTH,WEST,NORTH//后面可以有分号也可以没有 <br> <br> } <br> <br> 调用:枚举名.成员 <br> <br> 枚举名 name =枚举名.成员; <br> <br> Direction dir = Direction.EAST; <br> <br>   <br> <br> Enum的方法使用: <br> <br> Javap---------------查看字节码文件 <br> <br> <br> 代码: <br> <br> enum Direction{ <br> <br> EAST('e'),SOUTH('s'),NORTH('n'),WEST('w'); <br> <br>     protected char a; <br> <br> private Direction(char a){ <br> <br> this.a = a; <br> <br> } <br> <br> public String toString(){ <br> <br> return a+""; <br> <br> } <br> <br> } <br> <br> 字节码: <br> <br> <br> ---------- javap ---------- <br> <br> Compiled from "Direction.java" <br> <br> final class Direction extends java.lang.Enum<Direction> <br> <br> {//不能被实例化 <br> <br>   public static final Direction EAST; <br> <br>   public static final Direction SOUTH; <br> <br>   public static final Direction NORTH; <br> <br>   public static final Direction WEST; <br> <br>   protected char a;//默认是private,但可以使用4P <br> <br>   public static Direction[] values();//默认方法,用来遍历 <br> <br> 打印枚举成员 <br> <br>   public static Direction valueOf(java.lang.String); <br> <br>   public java.lang.String toString(); <br> <br>   static {};//静态初始化块 <br> <br> } <br> <br> 由上面可以知道枚举继承java.lang.Enum类,参数的默认修饰符 <br> <br> public static final,在枚举中可以使用4p <br> <br> <br> <br> public enum A{BLUE,RED,BLACK};//声明并定义一个枚举,初始 <br> <br> 化为。。。 <br> <br> 在一个类中定义一个enum成员,enum默认是静态的------------- <br> <br> 相当于类变量 <br> <br> <br> <br> 枚举的用法 <br> <br> 一、常量-----------枚举出来之前都是通过接口 <br> <br> 在JDK1.5 之前,我们定义常量都是: public static fianl,现 <br> <br> 在可以把相关的常量分组到一个枚举类型里,例: <br> <br> public enum Color { <br> <br>   RED, GREEN, BLANK, YELLOW <br> <br> } <br> <br> 二、Switch <br> <br> JDK1.5之后的switch语句支持Byte,short,int,char,enum类型 <br> <br> ,使用枚举,能让我们的代码可读性更强,JDK1.7之后开始支持 <br> <br> String类型,例: <br> <br> enum Signal { <br> <br>          GREEN, YELLOW, RED <br> <br> } <br> <br> public class TrafficLight { <br> <br>          Signal color = Signal.RED; <br> <br>          public void change() { <br> <br>                    switch (color) { <br> <br>                    case RED: <br> <br>                             color = Signal.GREEN; <br> <br>                             break; <br> <br>                    case YELLOW: <br> <br>                             color = Signal.RED; <br> <br>                             break; <br> <br>                    case GREEN: <br> <br>                             color = Signal.YELLOW; <br> <br>                             break; <br> <br>                    } <br> <br>          } <br> <br> } <br> <br> 三、向枚举中添加新方法 <br> <br> 要自定义方法,必须在enum实例序列的最后添加一个分号。而且 <br> <br> Java 要求必须先定义 enum实例,例: <br> <br> public enum Color { <br> <br>          RED("红色", 1), GREEN("绿色", 2), BLANK("白色", <br> <br> 3), YELLO("黄色", 4); <br> <br>          // 成员变量 <br> <br>          private String name; <br> <br>          private int index; <br> <br>          // 构造方法 <br> <br>          private Color(String name, int index) { <br> <br>                    this.name = name; <br> <br>                    this.index = index; <br> <br>          } <br> <br>          // 普通方法 <br> <br>          public static String getName(int index) { <br> <br>                    for (Color c : Color.values()) { <br> <br>                             if (c.getIndex() == index) { <br> <br>                                      return c.name; <br> <br>                             } <br> <br>                    } <br> <br>                    return null; <br> <br>          } <br> <br>          // get set 方法 <br> <br>          public String getName() { <br> <br>                    return name; <br> <br>          } <br> <br>          public void setName(String name) { <br> <br>                    this.name = name; <br> <br>          } <br> <br>          public int getIndex() { <br> <br>                    return index; <br> <br>          } <br> <br>          public void setIndex(int index) { <br> <br>                    this.index = index; <br> <br>          } <br> <br> } <br> <br> 四、覆盖枚举的方法 <br> <br> 例如覆盖toString() <br> <br> public enum Color { <br> <br>          RED("红色", 1), GREEN("绿色", 2), BLANK("白色", <br> <br> 3), YELLO("黄色", 4); <br> <br>          // 成员变量 <br> <br>          private String name; <br> <br>          private int index; <br> <br>          // 构造方法 <br> <br>          private Color(String name, int index) { <br> <br>                    this.name = name; <br> <br>                    this.index = index; <br> <br>          } <br> <br>          //覆盖方法 <br> <br>          @Override <br> <br>          public String toString() { <br> <br>                    return this.index+"_"+this.name; <br> <br>          } <br> <br> } <br> <br> 五、实现接口------所有的枚举都继承自java.lang.Enum类。由 <br> <br> 于Java 不支持多继承,所以枚举对象不能再继承其他类,例: <br> <br> public interface Behaviour { <br> <br>          void print(); <br> <br>          String getInfo(); <br> <br> } <br> <br> public enum Color implements Behaviour{ <br> <br>          RED("红色", 1), GREEN("绿色", 2), BLANK("白色", <br> <br> 3), YELLO("黄色", 4); <br> <br>          // 成员变量 <br> <br>          private String name; <br> <br>          private int index; <br> <br>          // 构造方法 <br> <br>          private Color(String name, int index) { <br> <br>                    this.name = name; <br> <br>                    this.index = index; <br> <br>          } <br> <br> //接口方法 <br> <br>          @Override <br> <br>          public String getInfo() { <br> <br>                    return this.name; <br> <br>          } <br> <br>          //接口方法 <br> <br>          @Override <br> <br>          public void print() { <br> <br>                    System.out.println(this.index <br> <br> +":"+this.name); <br> <br>          } <br> <br> } <br> <br> 六、使用接口组织枚举 <br> <br> public interface Food { <br> <br>          enum Coffee implements Food{ <br> <br>                     <br> <br> BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO <br> <br>          } <br> <br>          enum Dessert implements Food{ <br> <br>                    FRUIT, CAKE, GELATO <br> <br>          } <br> <br> } <br> <br> 七、枚举集合 <br> <br> java.util.EnumSet和java.util.EnumMap是两个枚举集合。 <br> <br> EnumSet保证集合中的元素不重复;EnumMap中的key是enum类型, <br> <br> 而value则可以是任意类型。 <br> <br> <br> <br> 枚举和普通类的区别与联系; <br> <br> 1、枚举与类都可以实现多接口;访问控制符都可以使用(4p), <br> <br> 但枚举中默认的是private,类中默认的是package; <br> <br> 2、枚举直接继承java.lang.Enum类,普通类是继承 <br> <br> java.lang.Object;其中java.long.Enum类实现了 <br> <br> java.long.Serializable和java.long.Comparable两个接口。 <br> <br> 3、使用enum定义、非抽象的枚举默认修饰符为public final,因 <br> <br> 此枚举不能派生子类。 <br> 4、枚举的构造器只能使用private访问控制符,如果省略了枚举 <br> <br> 的访问修饰符其默认为private修饰;因为枚举的字段不能初始化 <br> <br> ,对象类型的必须调用构造方法,所有有多少个成员构造方法就 <br> <br> 会运行多少次; <br> 5、枚举的所有实例必须在枚举的第一行显示列出,否则这个枚举 <br> <br> 永远都不能生产实例,列出这些实例时系统会自动添加public <br> <br> static final修饰,无需程序员显式添加 <br> <br> 6、所有的枚举类都提供了一个values方法,该方法可以很方便的 <br> <br> 遍历所有的枚举值 <br> <br> 7、关键字:枚举是enum,类是class <br> <br> 8、枚举是类类型,类是引用类型 <br> <br> <br> instanceof关键字: <br> public class FX { <br> public static void main(String[] args) { <br> boolean b = ("1" instanceof String);//判断某个对象是不是 <br> <br> 某个类的实例    Result = Object instanceof <br> <br> Class/interface <br> //Result:布尔类型。 <br>    //Object:必选项。任意对象表达式。 <br> //Class:必选项。任意已定义的对象类。 <br> System.out.println(b); <br> } <br> } <br> <br> <br> 注解---JDK1.5的新特性 <br> 使用位置:类上、方法上、语句上 <br> <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br> --------------------------------------------------------- <br> <br> -------------|------------------------------------------- <br> <br> ---------------------------| <br> <br> <br> 八、协变与泛型 <br> 协变-------可以用在数组、重写,不可以用在枚举中 <br> <br> 可变参数: <br> <br> int… a-------------代表一个没有长度限制的数组---------- <br> <br> JDK1.5之后有的 <br> <br> 输入的必须是数组 <br> <br> Java1.5增加了新特性:可变参数:适用于参数个数不确定,类型 <br> <br> 确定的情况,java把可变参数当做数组处理。注意:可变参数必 <br> <br> 须位于最后一项。只支持有一个可变参数。因为参数个数不定, <br> <br> 所以当其后边还有相同类型参数时,java无法区分传入的参数属 <br> <br> 于前一个可变参数还是后边的参数,所以只能让可变参数位于最 <br> <br> 后一项。 <br> <br> 可变参数的特点: <br> <br> (1)、只能出现在参数列表的最后; <br> <br> (2)、... 位于变量类型和变量名之间,前后有无空格都可以; <br> <br> (3)、调用可变参数的方法时,编译器为该可变参数隐含创建一 <br> <br> 个数组,在方法体中以数组的形式访问可变参数。例: <br> <br> public class Varable { <br>      public static void main(String [] args){ <br>          System.out.println(add(2,3)); <br>          System.out.println(add(2,3,5)); <br>      } <br>      public static int add(int x,int ...args){ <br>          int sum=x; <br>          for(int i=0;i<args.length;i++){ <br>              sum+=args[i]; <br>          } <br>          return sum; <br>      } <br> } <br> <br>  协变的作用范围 <br> <br> 1、数组:如果 A 是 B 的超类,则 A[] 也是 B[] 的超类,所有 <br> <br> 需要 A[] 的地方都可以用 B[] 代替,例: <br> <br> public class Test2 { <br> <br>     public static void main(String[] args){ <br> <br>         Integer[] ints=new Integer[1]; <br> <br>         ints[0]=99; <br> <br>         show(ints); <br> <br>     } <br> <br>     static void show(Number[] ns){ <br> <br>         System.out.println(Arrays.toString(ns)); <br> <br>     } <br> <br> } <br> <br>   <br> <br> 2、重写 <br> <br> public class Test2 { <br> <br>     public static void main(String[] args){ <br> <br>         P p=new C(); <br> <br>         System.out.println(p.get()); <br> <br>     } <br> <br> } <br> <br> class P{ <br> <br>     public Number get(){ <br> <br>         return new Integer(0); <br> <br>     } <br> <br> } <br> <br> class C extends P{ <br> <br>     public Integer get(){ <br> <br>         return new Integer(1); <br> <br>     } <br> <br> } <br> <br> 3、泛型不能协变:如果 A 是 B 的超类,则 List<A> 和 <br> <br> List<B> 无关,需要 List<A> 的地方不可以用 List<B> 代替, <br> <br> 例: <br> <br> public class Test2 { <br> <br>     public static void main(String[] args) { <br> <br>         List<Integer> ints = new ArrayList<Integer>(); <br> <br>         //incompatible type--类型不兼容 <br> <br>         show(ints); <br> <br>     } <br> <br>   <br> <br>     static void show(List<Number> ns) { <br> <br>         System.out.println(ns); <br> <br>     } <br> <br> } <br> <br> <br> 泛型(Generic)的本质是类型参数化 <br> <br> -------------是JDK1.5提供的新技术,它的本质是类型参数化, <br> <br> 类似C++中的模板,它根据应用主要分为泛型方法,泛型接口,泛 <br> <br> 型类,协变不适用于泛型 <br> <br>   <br> <br> 泛型-------------泛型类class Demo<T>{},泛型接口interface <br> <br> Inter<T>{},泛型方法public<T> T show(T a) {} <br> <br> 泛型的好处是在编译的时候检查类型安全,并且所有的强制转换 <br> <br> 都是自动和隐式的,提高代码的重用率 <br> <br>   <br> <br> 例1: <br> <br> public class  GenericDemo{ <br> <br>        public static void main(String[] args) { <br> <br>               C c1 = new C(new A("aaa")); <br> <br>               C c2 = new C(new B(3.4));//包装成double--- <br> <br> 自动装箱 <br> <br>               Object obj = c1.getObj(); <br> <br>               A obj = (A)(c1.getObj());//强制转换 <br> <br>               System.out.println(obj); <br> <br>        } <br> <br> } <br> <br> class A{ <br> <br>        private String x; <br> <br>        public A(String x){ <br> <br>               this.x=x; <br> <br>        } <br> <br>        public String getX(){ <br> <br>               return x; <br> <br>        } <br> <br> } <br> <br> class B{ <br> <br>        private Double d; <br> <br>        public B(Double d){ <br> <br>               this.d=d ; <br> <br>        } <br> <br>        public Double getD(){ <br> <br>               return d; <br> <br>        } <br> <br> } <br> <br> class C{ <br> <br>        private Object obj; <br> <br>        public C(Object obj){ <br> <br>               this.obj=obj ; <br> <br>        } <br> <br>        public Object  getObj(){ <br> <br>               return obj; <br> <br>        } <br> <br> } <br> <br>   <br> <br> 泛型的使用: <br> <br> 一、泛型类: <br> <br> public class Demo1 { <br> <br>        public static void main(String[] args) { <br> <br>               Generic<String> c = new Generic<String> <br> <br> ("asad"); <br> <br>               System.out.println(c.getA()); <br> <br>   <br> <br>               //Generic<int> c1 = new Generic<int>(12);必 <br> <br> 须要是包装类 <br> <br>        } <br> <br> } <br> <br> class Generic<T>{//泛型类 <br> <br>        private T a; <br> <br>        public Generic(T a){ <br> <br>               this.a = a; <br> <br>        } <br> <br>        public T getA(){ <br> <br>               return a; <br> <br>        } <br> <br> } <br> <br>   <br> <br> 二、泛型方法 <br> <br>        public static <T> T getX(T t){//泛型方 <br> <br> 法----------<  >--表声明 <br> <br>               return t; <br> <br>        } <br> <br>        <br> <br> public static <T,K> T getX(K t){//泛型方法 <br> <br>               return t; <br> <br>        } <br> <br>   <br> <br> 三、泛型接口 <br> <br> public class GenericDemo3{ <br> <br> public static void main(String[] args) { <br> <br> D<int[][]> d = new D<int[][]>(); <br> <br> d.show(new int[][]{{1,4},{2,3}}); <br> <br> } <br> <br> } <br> <br> interface IA<T>{ <br> <br> void show(T t); <br> <br> } <br> <br> <br> <br> class D<T> implements IA<T>{ <br> <br> public void show(T t){ <br> <br> System.out.println(t.getClass().getName()); <br> <br> } <br> <br> } <br> <br>   <br> <br>   <br> <br> 有界类型: <br> <br> 上界:extends 默认上界为Object <br> <br> Class G <T extends Number,K extends Object,H super <br> <br> Integer>{} <br> <br> 下界:super----------只有通配符有下限 <br> <br> extends关键字声明了类型的上界,表示参数化的类型可能是所指 <br> <br> 定的类型,或者是此类型的子类 <br> <br> super关键字声明了类型的下界,表示参数化的类型可能是所指定 <br> <br> 的类型,或者是此类型的父类型,直至Object <br> <br>   <br> <br> 规则和限制 <br> <br> 1、泛型的类型参数只能是类类型(包括自定义类),不能是简单 <br> <br> 类型。 <br> <br> 2、同一种泛型可以对应多个版本(因为参数类型是不确定的), <br> <br> 不同版本的泛型类实例是不兼容的。 <br> <br> 3、泛型的类型参数可以有多个。<T,K> <br> <br> 4、泛型的参数类型可以使用extends关键字,例如<T extends <br> <br> superclass>。习惯上称为“有界类型”。 <br> <br> 5、泛型的参数类型还可以是通配符类型。例如Class<?> <br> <br> classType = Class.forName("java.lang.String") <br> <br> 6、如果只指定了<?>,而没有extends,则默认是允许Object及其 <br> <br> 下的任何Java类了。也就是任意类。 <br> <br> 7、通配符泛型不但可以向下限制,如<? extends Collection>, <br> <br> 还可以向上限制,如<? super Double>,表示类型只能接受 <br> <br> Double及其上层父类类型,如Number、Object类型的实例。 <br> <br> 8、泛型类定义可以有多个泛型参数,中间用逗号隔开,还可以定 <br> <br> 义泛型接口,泛型方法。这些都与泛型类中泛型的使用规则类似 <br> <br> 。 <br> <br> 一个普通static方法,无法访问泛型类的类型参数,所以,若普 <br> <br> 通static方法需要使用泛型参数,必须使其成为泛型方法。 <br> <br>   <br> <br>   <br> <br> java 泛型详解 <br> <br> 普通泛型 <br> <br> Java代码 <br> <br> 1.  class Point<T>{       // 此处可以随便写标识符号   <br> <br> 2.      private T var ; // var的类型由T指定,即:由外部指 <br> <br> 定   <br> <br> 3.      public T getVar(){  // 返回值的类型由外部决定   <br> <br> 4.          return var ;   <br> <br> 5.      }   <br> <br> 6.      public void setVar(T var){  // 设置的类型也由外部 <br> <br> 决定   <br> <br> 7.          this.var = var ;   <br> <br> 8.      }   <br> <br> 9.  }   <br> <br> 10. public class GenericsDemo06{   <br> <br> 11.     public static void main(String[] args){ <br> <br> 12.         Point<String> p = new Point<String>() ; // 里 <br> <br> 面的var类型为String类型  --------指定数据类型—必须是引用 <br> <br> 数据类型 <br> <br> 13.         p.setVar("it") ;        // 设置字符串   <br> <br> 14.         System.out.println(p.getVar().length()) ;    <br> <br> // 取得字符串的长度   <br> <br> 15.     }   <br> <br> 16. } <br> <br> 17. //2 <br> <br> 18. <br> <br> --------------------------------------------------------- <br> <br> -   <br> <br> 19. class Notepad<K,V>{       // 此处指定了两个泛型类 <br> <br> 型-----再类上进行声明泛型类型   <br> <br> 20.     private K key ;     // 此变量的类型由外部决定   <br> <br> 21.     private V value ;   // 此变量的类型由外部决定   <br> <br> 22.     public K getKey(){   <br> <br> 23.         return this.key ;   <br> <br> 24.     }   <br> <br> 25.     public V getValue(){   <br> <br> 26.         return this.value ;   <br> <br> 27.     }   <br> <br> 28.     public void setKey(K key){   <br> <br> 29.         this.key = key ;   <br> <br> 30.     }   <br> <br> 31.     public void setValue(V value){   <br> <br> 32.         this.value = value ;   <br> <br> 33.     }   <br> <br> 34. }   <br> <br> 35. public class GenericsDemo09{   <br> <br> 36.     public static void main(String args[]){   <br> <br> 37.         Notepad<String,Integer> t = null ;        // <br> <br> 定义两个泛型类型的对象   <br> <br> 38.         t = new Notepad<String,Integer>() ;       // <br> <br> 里面的key为String,value为Integer   <br> <br> 39.         t.setKey("汤姆") ;        // 设置第一个内容   <br> <br> 40.         t.setValue(20) ;            // 设置第二个内容 <br> <br>   <br> <br> 41.         System.out.print("姓名;" + t.getKey()) ;      <br> <br>  // 取得信息   <br> <br> 42.         System.out.print(",年龄;" + t.getValue()) ; <br> <br>       // 取得信息   <br> <br> 43.       }   <br> <br> 44. }  //汤姆 <br> <br> 45.       20 <br> <br>  通配符 <br> <br> Java代码 <br> <br> 1.  class Info<T>{   <br> <br> 2.      private T var ;     // 定义泛型变量   <br> <br> 3.      public void setVar(T var){   <br> <br> 4.          this.var = var ;   <br> <br> 5.      }   <br> <br> 6.      public T getVar(){   <br> <br> 7.          return this.var ;   <br> <br> 8.      }   <br> <br> 9.      public String toString(){   // 直接打印   <br> <br> 10.         return this.var.toString() ;   <br> <br> 11.     }   <br> <br> 12. } <br> <br> 13. public class GenericsDemo14{   <br> <br> 14.     public static void main(String args[]){   <br> <br> 15.         Info<String> i = new Info<String>() ;        <br> <br> // 使用String为泛型类型   <br> <br> 16.         i.setVar("it") ;                             <br> <br> // 设置内容   <br> <br> 17.         fun(i) ;   <br> <br> 18.     }   <br> <br> 19.     public static void fun(Info<?> temp){     // 可以 <br> <br> 接收任意的泛型对象   <br> <br> 20.         System.out.println("内容:" + temp) ;   <br> <br> 21.     }   <br> <br> 22. }//  内容:it <br> <br>  受限泛型 <br> <br> Java代码 <br> <br> 1.  class Info<T>{   <br> <br> 2.      private T var ;     // 定义泛型变量   <br> <br> 3.      public void setVar(T var){   <br> <br> 4.          this.var = var ;   <br> <br> 5.      }   <br> <br> 6.      public T getVar(){   <br> <br> 7.          return this.var ;   <br> <br> 8.      }   <br> <br> 9.      public String toString(){   // 直接打印   <br> <br> 10.         return this.var.toString() ;   <br> <br> 11.     }   <br> <br> 12. }   <br> <br> 13. public class GenericsDemo17{   <br> <br> 14.     public static void main(String args[]){   <br> <br> 15.         Info<Integer> i1 = new Info<Integer>() ;   // <br> <br> 声明Integer的泛型对象   <br> <br> 16.         Info<Float> i2 = new Info<Float>() ;          <br> <br> // 声明Float的泛型对象   <br> <br> 17.         i1.setVar(30) ;                               <br> <br> // 设置整数,自动装箱   <br> <br> 18.         i2.setVar(30.1f) ;                            <br> <br> // 设置小数,自动装箱   <br> <br> 19.         fun(i1) ;   <br> <br> 20.         fun(i2) ;   <br> <br> 21.     }   <br> <br> 22.     public static void fun(Info<? extends Number> <br> <br> temp){ // 只能接收Number及其Number的子类   <br> <br> 23.         System.out.print(temp + "、") ;   <br> <br> 24.     }   <br> <br> 25. }//  30、30.1、 <br> <br> 26. <br> <br> --------------------------------------------------------- <br> <br> -   <br> <br> 27. class Info<T>{   <br> <br> 28.     private T var ;     // 定义泛型变量   <br> <br> 29.     public void setVar(T var){   <br> <br> 30.         this.var = var ;   <br> <br> 31.     }   <br> <br> 32.     public T getVar(){   <br> <br> 33.         return this.var ;   <br> <br> 34.     }   <br> <br> 35.     public String toString(){   // 直接打印   <br> <br> 36.         return this.var.toString() ;   <br> <br> 37.     }   <br> <br> 38. }   <br> <br> 39. public class GenericsDemo21{   <br> <br> 40.     public static void main(String args[]){   <br> <br> 41.         Info<String> i1 = new Info<String>() ;       <br> <br> // 声明String的泛型对象   <br> <br> 42.         Info<Object> i2 = new Info<Object>() ;       <br> <br> // 声明Object的泛型对象   <br> <br> 43.         i1.setVar("hello") ;   <br> <br> 44.         i2.setVar(new Object()) ;   <br> <br> 45.         fun(i1) ;   <br> <br> 46.         fun(i2) ;   <br> <br> 47.     }   <br> <br> 48.     public static void fun(Info<? super String> <br> <br> temp){   // 只能接收String或Object类型的泛型  ----上限为 <br> <br> String <br> <br> 49.         System.out.print(temp + "、") ;   <br> <br> 50.     }   <br> <br> 51. }//  hello、java.lang.Object@1ffc686、 <br> <br>  泛型无法向上转型 <br> <br> Java代码 <br> <br> 1.  class Info<T>{   <br> <br> 2.      private T var ;     // 定义泛型变量   <br> <br> 3.      public void setVar(T var){   <br> <br> 4.          this.var = var ;   <br> <br> 5.      }   <br> <br> 6.      public T getVar(){   <br> <br> 7.          return this.var ;   <br> <br> 8.      }   <br> <br> 9.      public String toString(){   // 直接打印   <br> <br> 10.         return this.var.toString() ;   <br> <br> 11.     }   <br> <br> 12. }   <br> <br> 13. public class GenericsDemo23{   <br> <br> 14.     public static void main(String args[]){   <br> <br> 15.         Info<String> i1 = new Info<String>() ;       <br> <br> // 泛型类型为String   <br> <br> 16.         Info<Object> i2 = null ;   <br> <br> 17.         i2 = i1 ;                           //这句会 <br> <br> 出错 incompatible types   <br> <br> 18.     }   <br> <br> 19. }//  编译失败 <br> <br>  泛型接口 <br> <br> Java代码 <br> <br> 1.  interface Info<T>{        // 在接口上定义泛型   <br> <br> 2.      public T getVar() ; // 定义抽象方法,抽象方法的返 <br> <br> 回值就是泛型类型   <br> <br> 3.  }   <br> <br> 4.  class InfoImpl<T> implements Info<T>{   // 定义泛型接 <br> <br> 口的子类   <br> <br> 5.      private T var ;             // 定义属性   <br> <br> 6.      public InfoImpl(T var){     // 通过构造方法设置属 <br> <br> 性内容   <br> <br> 7.          this.setVar(var) ;     <br> <br> 8.      }   <br> <br> 9.      public void setVar(T var){   <br> <br> 10.         this.var = var ;   <br> <br> 11.     }   <br> <br> 12.     public T getVar(){   <br> <br> 13.         return this.var ;   <br> <br> 14.     }   <br> <br> 15. }   <br> <br> 16. public class GenericsDemo24{   <br> <br> 17.     public static void main(String arsg[]){   <br> <br> 18.         Info<String> i = null;        // 声明接口对象 <br> <br>   <br> <br> 19.         i = new InfoImpl<String>("汤姆") ;  // 通过子 <br> <br> 类实例化对象   <br> <br> 20.         System.out.println("内容:" + i.getVar()) ;   <br> <br> 21.     }   <br> <br> 22. }//  内容:汤姆 <br> <br>  泛型方法 <br> <br> Java代码 <br> <br> 1.  class Demo{   <br> <br> 2.      public <T> T fun(T t){            // 可以接收任意 <br> <br> 类型的数据   <br> <br> 3.          return t ;                  // 直接把参数返回 <br> <br>   <br> <br> 4.      }   <br> <br> 5.  }   <br> <br> 6.  public class GenericsDemo26{   <br> <br> 7.      public static void main(String args[]){   <br> <br> 8.          Demo d = new Demo() ;   // 实例化Demo对象   <br> <br> 9.          String str = d.fun("汤姆") ; //   传递字符串   <br> <br> 10.         int i = d.fun(30) ;     // 传递数字,自动装箱 <br> <br>   <br> <br> 11.         System.out.println(str) ;   // 输出内容   <br> <br> 12.         System.out.println(i) ;     // 输出内容   <br> <br> 13.     }   <br> <br> 14. }//  汤姆  30 <br> <br>  通过泛型方法返回泛型类型实例 <br> <br> Java代码 <br> <br> 1.  class Info<T extends Number>{ // 指定上限,只能是数字 <br> <br> 类型   <br> <br> 2.      private T var ;     // 此类型由外部决定   <br> <br> 3.      public T getVar(){   <br> <br> 4.          return this.var ;      <br> <br> 5.      }   <br> <br> 6.      public void setVar(T var){   <br> <br> 7.          this.var = var ;   <br> <br> 8.      }   <br> <br> 9.      public String toString(){       // 覆写Object类中 <br> <br> 的toString()方法   <br> <br> 10.         return this.var.toString() ;       <br> <br> 11.     }   <br> <br> 12. }   <br> <br> 13. public class GenericsDemo27{   <br> <br> 14.     public static void main(String args[]){   <br> <br> 15.         Info<Integer> i = fun(30) ;   <br> <br> 16.         System.out.println(i.getVar()) ;   <br> <br> 17.     }   <br> <br> 18.     public static <T extends Number> Info<T> fun(T <br> <br> param){//方法中传入或返回的泛型类型由调用方法时所设置的参 <br> <br> 数类型决定   <br> <br> 19.         Info<T> temp = new Info<T>() ;      // 根据传 <br> <br> 入的数据类型实例化Info   <br> <br> 20.         temp.setVar(param) ;     // 将传递的内容设置 <br> <br> 到Info对象的var属性之中   <br> <br> 21.         return temp ;   // 返回实例化对象   <br> <br> 22.     }   <br> <br> 23. }//  30 <br> <br>  使用泛型统一传入的参数类型 <br> <br> Java代码 <br> <br> 1.  class Info<T>{    // 指定上限,只能是数字类型   <br> <br> 2.      private T var ;     // 此类型由外部决定   <br> <br> 3.      public T getVar(){   <br> <br> 4.          return this.var ;      <br> <br> 5.      }   <br> <br> 6.      public void setVar(T var){   <br> <br> 7.          this.var = var ;   <br> <br> 8.      }   <br> <br> 9.      public String toString(){       // 覆写Object类中 <br> <br> 的toString()方法   <br> <br> 10.         return this.var.toString() ;       <br> <br> 11.     }   <br> <br> 12. } <br> <br> 13. public class GenericsDemo28{   <br> <br> 14.     public static void main(String args[]){   <br> <br> 15.         Info<String> i1 = new Info<String>() ;   <br> <br> 16.         Info<String> i2 = new Info<String>() ;   <br> <br> 17.         i1.setVar("HELLO") ;        // 设置内容   <br> <br> 18.         i2.setVar("汤姆") ;       // 设置内容   <br> <br> 19.         add(i1,i2) ;   <br> <br> 20.     }   <br> <br> 21.     public static <T> void add(Info<T> i1,Info<T> <br> <br> i2){   <br> <br> 22.         System.out.println(i1.getVar() + " " + <br> <br> i2.getVar()) ;   <br> <br> 23.     }   <br> <br> 24. }// HELLO 汤姆 <br> <br>  泛型数组 <br> <br> Java代码 <br> <br> 1.  public class GenericsDemo30{   <br> <br> 2.      public static void main(String args[]){   <br> <br> 3.          Integer i[] = fun1(1,2,3,4,5,6) ;   // 返回泛 <br> <br> 型数组   <br> <br> 4.          fun2(i) ;   <br> <br> 5.      }   <br> <br> 6.      public static <T> T[] fun1(T...arg){  // 接收可变 <br> <br> 参数   <br> <br> 7.          return arg ;            // 返回泛型数组   <br> <br> 8.      }   <br> <br> 9.      public static <T> void fun2(T param[]){   // 输出 <br> <br>   <br> <br> 10.         System.out.print("接收泛型数组:") ;   <br> <br> 11.         for(T t:param){   <br> <br> 12.             System.out.print(t + "、") ;   <br> <br> 13.         }   <br> <br> 14.     }   <br> <br> 15. }//  接收泛型数组:1、2、3、4、5、6、 <br> <br>  泛型的嵌套设置 <br> <br> Java代码 <br> <br> 1.  class Info<T,V>{      // 接收两个泛型类型   <br> <br> 2.      private T var ;   <br> <br> 3.      private V value ;   <br> <br> 4.      public Info(T var,V value){   <br> <br> 5.          this.setVar(var) ;   <br> <br> 6.          this.setValue(value) ;   <br> <br> 7.      }   <br> <br> 8.      public void setVar(T var){   <br> <br> 9.          this.var = var ;   <br> <br> 10.     }   <br> <br> 11.     public void setValue(V value){   <br> <br> 12.         this.value = value ;   <br> <br> 13.     }   <br> <br> 14.     public T getVar(){   <br> <br> 15.         return this.var ;   <br> <br> 16.     }   <br> <br> 17.     public V getValue(){   <br> <br> 18.         return this.value ;   <br> <br> 19.     }   <br> <br> 20. }   <br> <br> 21. class Demo<S>{   <br> <br> 22.     private S info ;   <br> <br> 23.     public Demo(S info){   <br> <br> 24.         this.setInfo(info) ;   <br> <br> 25.     }   <br> <br> 26.     public void setInfo(S info){   <br> <br> 27.         this.info = info ;   <br> <br> 28.     }   <br> <br> 29.     public S getInfo(){   <br> <br> 30.         return this.info ;   <br> <br> 31.     }   <br> <br> 32. } <br> <br> 33. public class GenericsDemo31{   <br> <br> 34.     public static void main(String args[]){   <br> <br> 35.         Demo<Info<String,Integer>> d = null ;  // 将 <br> <br> Info作为Demo的泛型类型   <br> <br> 36.         Info<String,Integer> i = null ;   // Info指定 <br> <br> 两个泛型类型   <br> <br> 37.         i = new Info<String,Integer>("汤姆",30) ;     <br> <br> // 实例化Info对象   <br> <br> 38.         d = new Demo<Info<String,Integer>>(i);//在 <br> <br> Demo类中设置Info类的对象   <br> <br> 39.         System.out.println("内容一:" + d.getInfo <br> <br> ().getVar()) ;   <br> <br> 40.         System.out.println("内容二:" + d.getInfo <br> <br> ().getValue()) ;   <br> <br> 41.     }   <br> <br> 42. } // 内容一:汤姆 内容二:30 <br> <br>   泛型方法不一定要通过参数来确定泛型准确类型,可以只通过 <br> <br> 返回值,比如: <br> <br>  public static <E> ArrayList<E> newArrayList() { <br>          return new ArrayList<E>(); <br>  } <br> <br>  public List<PrepaidHistory> queryHistories(Long <br> <br> skyid,PrepaidHistoryType type, Date from, Date end) {  <br> <br>          return Lists.newArrayList(); <br> <br> } <br> <br>  这样Lists.newArrayList(); <br> 智能的知道返回类型为PrepaidHistory <br> <br> 一、 Oracle的安装(windowXP、win7、Linux)和卸载 <br>   1.1 Oracle的安装 <br>     1.1.1 在WindowsXP、Win7下安装 <br>       第一:解压win32_11gR2_database_1of2、 <br> <br> win32_11gR2_database_2of2,生成detabase目录 <br>       第二:安装oracle <br>            A、点击setup图标即可,注意:安装目录不要含有中 <br> <br> 文 <br>            B、在弹出的第一个界面中取消更新选择项,点击下 <br> <br> 一步 <br>            C、在弹出的警告框中选择是 <br>            D、选择创建和配置数据库选项,下一步 <br>            E、选择桌面类安装,点击下一步 <br>            F、弹出的窗口中输入全局数据库名:orcl <br>                  输入管理口令:bluedot <br>                  默认的管理员是:sys和system <br>            G、点完成,开始安装数据库,出现进度条 <br>            H、口令管理 <br>            I、设置口令 <br>            J、完成安装 <br>   1.2 Oracle的卸载: <br>     1、 开始->设置->控制面板->管理工具->服务 停止 <br> <br> 所有Oracle服务。 <br>     2、 开始->程序->Oracle - OraHome81->Oracle <br> <br> Installation Products-> Universal Installer,单击“卸载 <br> <br> 产品”-“全部展开”,选中除“OraDb11g_home1”外的全部目录 <br> <br> ,删除。 <br>     3、 运行regedit,选择HKEY_LOCAL_MACHINE\SOFTWARE <br> <br> \ORACLE,按del键删除这个入口。 <br>     4、 运行regedit,选择HKEY_LOCAL_MACHINE\SYSTEM <br> <br> \CurrentControlSet\Services,滚动这个列表,删除所有Oracle <br> <br> 入口(以oracle或OraWeb开头的键)。 <br>     5、 运行refedit,HKEY_LOCAL_MACHINE\SYSTEM <br> <br> \CurrentControlSet\Services\Eventlog\Application,删除所 <br> <br> 有Oracle入口。e <br>     6、 删除HKEY_CLASSES_ROOT目录下所有以Ora、Oracle、 <br> <br> Orcl或EnumOra为前缀的键。 <br>     7、 删除HKEY_CURRENT_USER\Software\Microsoft\Windows <br> <br> \CurrentVersion\Explorer\MenuOrder\Start Menu\Programs中 <br> <br> 所有以oracle开头的键。 <br>     8、删除HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI <br> <br> 中除Microsoft ODBC for Oracle注册表键以外的所有含有Oracle <br> <br> 的键。 <br>     9、我的电脑-->属性-->高级-->环境变量,删除环境变量 <br> <br> CLASSPATH和PATH中有关Oracle的设定。 <br>     10、从桌面上、STARTUP(启动)组、程序菜单中,删除所有 <br> <br> 有关Oracle的组和图标。 <br>     11、删除所有与Oracle相关的目录(如果删不掉,重启计算机 <br> <br> 后再删就可以了)包括: <br>          1.C:\Program file\Oracle目录。 <br>          2.ORACLE_BASE目录(oracle的安装目录)。 <br>          3.C:\WINDOWS\system32\config\systemprofile <br> <br> \Oracle目录。 <br>          4.C:\Users\Administrator\Oracle或C:\Documents <br> <br> and Settings\Administrator\Oracle目录。 <br>          5.C:\WINDOWS下删除以下文件ORACLE.INI、 <br> <br> oradim73.INI、oradim80.INI、oraodbc.ini等等。 <br>          6.C:\WINDOWS下的WIN.INI文件中若有[ORACLE]的标记 <br> <br> 段,删除该段。 <br>     12、如有必要,删除所有Oracle相关的ODBC的DSN <br>     13、到事件查看器中,删除Oracle相关的日志 说明: 如果 <br> <br> 有个别DLL文件无法删除的情况,则不用理会,重新启动,开始新 <br> <br> 的安装,安装时,选择一个新的目录,则,安装完毕并重新启动 <br> <br> 后,老的目录及文件就可以删除掉了。 <br>   <br> 二、 用户管理 <br>    2.1 创建用户 <br>        注:创建用户只能在管理员下完成 <br>        CREATE USER 用户名 IDENTIFIED BY 密码。 <br>        |-CREATE USER demo IDENTIFIED BY 123456; <br>    2.2 用户分类 <br>      |-管理员和普通用户 <br>         |-管理员 <br>           |-超级管理员:sys/bluedot <br>           |-管理员:system/bluedot <br>         |-普通用户:scott/tiger <br>                        hr/hr <br>      |--常见角色:sysdba、sysoper <br>    2.3 用户登录 <br>      2.3.1 在命令行窗口登录[c/s] <br>         步骤: <br>            运行 sqlplus /nolog <br>            conn demo/123456 <br>       2.3.2 另外的一种登录方式【B/S】 <br>            输入网址----https://localhost:1158/em <br>   输入用户名密码进入主界面 <br>    2.4 修改用户密码 <br>       注:修改密码必须要在级别高的用户下进行修改 <br>      ALTER USER 用户名 IDENTIFIED BY 密码; <br>       <br>      conn sys/bluedot as sysdba <br>      ALTER USER demo IDENTIFIED BY 654321; <br>    2.5 查询用户 <br>        2.5.1查看用户信息 <br>          1、SELECT * FROM DBA_USERS;--------查看所有用户 <br> <br> 的详细信息 <br>          2、SELECT * FROM ALL_USERS;-------查看所有用户简 <br> <br> 要信息 <br>          3、SELECT * FROM USER_USERS;------------查看当前 <br> <br> 用户的所用信息 <br>       2.5.2 查看用户或角色系统权限(直接赋值给用户或角色 <br> <br> 的系统权限) <br>          SELECT * FROM DBA_SYS_PRIVS;----------全部 <br>          SELECT * FROM USER_SYS_PRIVS; ---------当前用户 <br>       2.5.3 查看角色(登录用户拥有的角色)所包含的的权限 <br>          SELECT * FROM ROLE_SYS_PRIVS; <br>       2.5.4 查看用户对象权限 <br>          SELECT * FROM DBA_TAB_PRIVS; <br>          SELECT * FROM ALL_TAB_PRIVS; <br>          SELECT * FROM USER_TAB_PRIVS; <br>       2.5.5 查看所有角色 <br>          SELECT * FROM DBA_ROLES; <br>          SELECT * FROM DBA_ROLE_PRIVS; <br>          SELECT * FROM USER_ROLE_PRIVS; <br>   <br>       2.5.6 查看哪些用户有sysdba或sysoper系统权限(查询时 <br> <br> 需要相应权限) <br>          SELECT * FROM V$PWFILE_USERS; <br>   <br>       2.5.7 查看Oracle提供的系统权限 <br>          SELECT name FROM SYS.SYSTEM_PRIVSILEGE_MAP; <br>    2.6 密码失效 <br>       提示用户第一次连接的时候需要修改密码,让用户的密码 <br> <br> 到期 <br>         |- ALTER USER 用户名 PASSWORD expire ; <br>    2.7 授权 <br>        GRANT 权限/角色 TO 用户 <br>        给 demo 用户以创建 session 的权限:GRANT create <br> <br> session TO demo; <br>        角色:-------------角色就是一堆权限的集合 <br>        Create role myrole; <br>        Grant create table to myrole; <br>        Drop role myrole; 删除角色 <br>       1.CONNECT, RESOURCE, DBA <br>       这些预定义角色主要是为了向后兼容。其主要是用于数据 <br> <br> 库管理。oracle建议用户自己设计数据库管理和安全的权限规划 <br> <br> ,而不要简单的使用这些预定角色。将来的版本中这些角色可能 <br> <br> 不会作为预定义角色。 <br>       2.DELETE_CATALOG_ROLE, EXECUTE_CATALOG_ROLE, <br> <br> SELECT_CATALOG_ROLE 这些角色主要用于访问数据字典视图和包 <br> <br> 。 <br>       3.EXP_FULL_DATABASE, IMP_FULL_DATABASE 这两个角 <br> <br> 色用于数据导入导出工具的使用。 <br>         GRANT 权限(select、update、insert、delete) ON <br> <br> schema.table TO 用户 <br>           |- GRANT select ON scott.emp TO test ; <br>           |- Grant all on scott.emp to test; --将表相关的 <br> <br> 所有权限付给 test <br>           |- Grant update(ename) on emp to test; 可以控制 <br> <br> 到列(还有 insert) <br>    2.8 收权 <br>       REVOKE 权限/角色 ON schema.table FROM 用户 <br>        |- REVOKE select ON scott.emp FROM test ; <br>    2.9 锁住一个用户 <br>        ALTER USER 用户名 ACCOUNT LOCK|UNLOCK <br>          |- ALTER USER test ACCOUNT LOCK ; <br>          |- ALTER USER test ACCOUNT UNLOCK ; <br>     2.10 删除用户 <br>             |-DROP USER 用户名; <br>                   |-Drop user demo; <br>            如果该用户下面已经存在表等一些数据库对象。则必 <br> <br> 须用级联删除 <br>            |-DROP USER 用户名 CASCADE; <br>                    |-Drop user demo cascade; <br>     备注:帮助 <br>         help index <br>         help conn --------显示具体的 <br>         eidt---------------进入编辑文档 <br> 三、 Oracle的体系结构 <br>    3.1 Oracle数据库的整体架构 (DBA) <br>                  ┌─────────────────── <br> <br> ───────────┐ <br> ┌────┐ │ Instance │ <br> │ User │ │ ┌──────────────────── <br> <br> ──────┐ │ <br> │ process│ │ │ ┌────────┐ SGA │ │ <br> └────┘ │ │ │ Shared Pool │ │ │ <br>     ↓ │ │ │ ┌─────┐ │ ┌────┐ ┌──── <br> <br> ┐ │ │ <br>     ↓ │ │ │ │Library │ │ │Database│ │ Redo │ <br> <br> │ │ <br> ┌────┐ │ │ │ │ Cache │ │ │Buffer │ │ Log <br> <br> │ │ │ <br> │ Server │ │ │ │ └─────┘ │ │Cache │ │ <br> <br> Buffer │ │ │ <br> │process │ │ │ │ ┌─────┐ │ │ │ │ │ │ │ <br> └────┘ │ │ │ │Data Dict │ │ └────┘ └─ <br> <br> ───┘ │ │ <br>      ↓ │ │ │ │ Cache │ │ │ │ <br>      →→→→→→│ │ │ └─────┘ │ │ │ <br>                  │ │ └────────┘ │ │ <br>                  │ └───────────────── <br> <br> ─────────┘ │ <br>                  │ ┌──┐ ┌──┐ ┌──┐ ┌──┐ <br> <br> ┌──┐ ┌───┐│ <br>    │ │PMON│ │SNON│ │DBWR│ │LGWR│ │CHPT│ <br> <br> │OTHERS││ <br>                  │ └──┘ └──┘ └──┘ └──┘ <br> <br> └──┘ └───┘│ <br>                  └─────────────────── <br> <br> ───────────┘ <br>                                                  ↑ ↓ <br>                ┌─────┐ ┌──────────── <br> <br> ───────┐ <br>                │Parameter │ │┌───┐ ┌────┐ <br> <br> ┌────┐│ <br>                │ file │ ││Data │ │control │ │Redo <br> <br> Log││ ┌─────┐ <br>                └─────┘ ││files │ │ files │ │ <br> <br> files ││ │Archived │ <br>                ┌─────┐ │└───┘ └────┘ <br> <br> └────┘│ │Log files │ <br>                │ Password │ │ Database │ └───── <br> <br> ┘ <br>         │ file │ │ │ <br>                └─────┘ └──────────── <br> <br> ───────┘ <br> 由上图可知,Oracle数据库由实例和数据库组成。 <br>    3.2 数据库存储结构 <br>       3.2.1 数据库存储结构 <br>       Oracle数据库有物理结构和逻辑结构。数据库的物理结构 <br> <br> 是数据库中的操作系统文件的集合。数据库的物理结构由数据文 <br> <br> 件、控制文件和重做日志文件组成。 <br>       1、数据文件:数据文件是数据的存储仓库。 <br>       2、重做日志文件:重做日志文件包含对数据库所做的更改 <br> <br> 记录,在发生故障时能够恢复数据。重做日志按时间顺序存储应 <br> <br> 用于数据库的一连串的变更向量。其中仅包含重建(重做)所有 <br> <br> 已完成工作的最少限度信息。如果数据文件受损,则可以将这些 <br> <br> 变更向量应用于数据文件备份来重做工作,将它恢复到发生故障 <br> <br> 的那一刻前的状态。重做日志文件包含联机重做日志文件(对于 <br> <br> 连续的数据库操作时必须的)和归档日志文件(对于数据库操作 <br> <br> 是可选的,但对于时间点恢复是必须的)。 <br>       3、控制文件:控制文件包含维护和验证数据库完整性的必 <br> <br> 要的信息。控制文件虽小,但作用非常大。它包含指向数据库其 <br> <br> 余部分的指针:联机重做日志文件和数据文件的位置,以及更新 <br> <br> 的归档日志文件的位置。它还存储着维护数据库完整性所需的信 <br> <br> 息。控制文件不过数MB,却起着至关重要的作用。 <br>       除了三个必须的文件外数据库还能有其它非必须的文件如 <br> <br> :参数文件、口令文件及归档日志文件。 <br>           1、实例参数文件:当启动oracle实例时,SGA结构会 <br> <br> 根据此参数文件的设置内置到内存,后台进程会据此启动。 <br>           2、口令文件:用户通过提交用户名和口令来建立会话 <br> <br> 。Oracle根据存储在数据字典的用户定义对用户名和口令进行验 <br> <br> 证。 <br>           3、归档重做日志文件:当重做日志文件满时将重做日 <br> <br> 志文件进行归档以便还原数据文件备份。 <br>       3.2.2 Oracle数据库结构的16个要点(表空间-->段--> <br> <br> 区-->块) <br>    1、一个数据文件只能归到某一个表空间上,每个表空间可 <br> <br> 以含一个或多个数据文件。包括系统数据和用户数据。 <br>    2、表空间是包括一个或多个数据文件的逻辑结构。用于存 <br> <br> 放数据库表、索引、回滚段等对象的磁盘逻辑空间 <br>    3、数据库文件是存放实际数据的物理文件。包括实例和数 <br> <br> 据库。 <br>    4、数据文件可以在创建表空间时创建,也可以以增加的方 <br> <br> 式创建。 <br>    5、数据文件的大小一般与操作系统限制有关。 <br>    6、控制文件是Oracle的重要文件,主要存放数据文件、日 <br> <br> 志文件和数据库的基本信息,一般在数据打开时访问。 <br>    7、日志文件在数据库活动时使用。 <br>    8、临时表空间是用于存放排序段的磁间;临时表空间由一 <br> <br> 个或多个临时文件组成。 <br>    9、归档日志文件由归档进程将联机日志文件读出并写到一 <br> <br> 个路径上的文件。 <br>    10、Oracle实例由一组后台进程和内存结构组成。 <br>    11、Oracle实例的内存结构常叫系统全局区,简称SGA。 <br>    12、DBA_开头的数据字典存放的字符信息都是大写,而V$_ <br> <br> 开头的视图存放的都是小写。 <br>    13、后台进程是一组完成不同功能的程序,主要包括DBWR、 <br> <br> LGMR、CKPT等。 <br>    14、数据字典是Oracle的重要部分,也就是用于系统内部的 <br> <br> 一组表。 <br>    15、数据字典分为动态和静态两部分,静态主要是DBA_开头 <br> <br> 的数据字典,而动态则是以V$_开头的视图。 <br>    16、SGA分为数据缓冲区、共享池和日志缓冲区。 <br>      3.2.3 Oracle逻辑结构及表空间 <br>         1.ORACLE逻辑结构 <br>              ORACLE将数据逻辑地存放在表空间,物理地存放在 <br> <br> 数据文件中。 <br>              一个表空间任何一个时刻只能属于一个数据库。 <br>   <br>              数据库——表空间——段——区——ORACLE块 <br>              每个数据库由一个或多个表空间组成,至少一个。 <br>              每个表空间基于一个或多个操作系统的数据文件, <br> <br> 至少一个,一个操作系统的数据文件只能属于一个表空间。一个 <br> <br> 表空间可以存放一个或多个段 segment。 <br>              每个段由一个或多个区段extent组成。 <br>              每个区段由一个或多个连续的ORACLE数据库块组成 <br> <br> 。 <br>              每个ORACLE数据块由一个或多个连续的操作系统数 <br> <br> 据块组成。 <br>              每个操作系统数据文件由一个或多个区段组成,由 <br> <br> 一个或多个操作系统数据块组成。 <br>       <br>          ⑴、表空间(tablespace) <br>              表空间是数据库中最大的逻辑单位,每一个表空间 <br> <br> 由一个或多个数据文件组成,一个数据文件只能与一个表空间相 <br> <br> 联系。每一个数据库都有一个SYSTEM表空间,该表空间是在数据 <br> <br> 库创建或数据库安装时自动创建的,用于存储系统的数据字典表 <br> <br> ,程序系统单元,过程函数,包和触发器等,也可用于存储用户 <br> <br> 数据表,索引对象。表空间具有在线(online)和离线(offline <br> <br> )属性,可以将除SYSTME以外的其他任何表空间置为离线。 <br>          ⑵、段(segment) <br>              数据库的段可以分为四类:数据段、索引段、回退 <br> <br> 段和临时段。 <br>          ⑶、区 <br>              区是磁盘空间分配的最小单位。磁盘按区划分,每 <br> <br> 次至少分配一个区。区存储与段中,它由连续的数据块组成。 <br>          ⑷、数据块 <br>              数据块是数据库中最小的数据组织单位与管理单位 <br> <br> ,是数据文件磁盘存储空间单位,也是数据库I/O的最小单位,数 <br> <br> 据块大小由DB_BLOCK_SIZE参数决定,不同的Oracle版本 <br> <br> DB_BLOCK_SIZE的默认值是不同的。 <br>          ⑸、模式对象 <br>              模式对象是一种应用,包括:表、聚簇、视图、索 <br> <br> 引序列生成器、同义词、哈希、程序单元、数据库链等。 <br>              最后,在来说一下Oracle的用户、表空间和数据文 <br> <br> 件的关系: <br>              一个用户可以使用一个或多个表空间,一个表空间 <br> <br> 也可以供多个用户使用。用户和表空间没有隶属关系,表空间是 <br> <br> 一个用来管理数据存储的逻辑概念,表空间只是和数据文件发生 <br> <br> 关系,数据文件是物理的,一个表空间可以包含多个数据文件, <br> <br> 而一个数据文件只能隶属一个表空间。 <br>              总结:解释数据库、表空间、数据文件、表、数据 <br> <br> 的最好办法就是想象一个装满东西的柜子。数据库其实就是柜子 <br> <br> ,柜中的抽屉是表空间,抽屉中的文件夹是数据文件,文件夹中 <br> <br> 的纸是表,写在纸上的信息就是数据。 <br>       2.两类表空间: <br>            系统SYSTEM表空间 非系统表空间 NON-SYSTEM表空间 <br>            系统SYSTEM表空间与数据库一起建立,在系统表空间 <br> <br> 中有数据字典,系统还原段。可以存放用户数据但是不建议。 <br>            非系统表空间NON-SYSTEM表空间 由管理员创建。可 <br> <br> 以方便管理。 <br>    3.3 实例的整体架构 <br>        实例整体架构图: <br>                  ┌─────────────────── <br> <br> ───────────┐ <br>                  │ Instance │ <br>                  │ ┌───────────────── <br> <br> ─────────┐ │ <br>                  │ │ ┌────────┐ SGA │ │ <br>                  │ │ │ Shared Pool │ │ │ <br>                  │ │ │ ┌─────┐ │ ┌────┐ <br> <br> ┌────┐ │ │ <br>                  │ │ │ │Library │ │ │Database│ │ <br> <br> Redo │ │ │ <br>                  │ │ │ │ Cache │ │ │Buffer │ │ <br> <br> Log │ │ │ <br>                  │ │ │ └─────┘ │ │Cache │ │ <br> <br> Buffer │ │ │ <br>                  │ │ │ ┌─────┐ │ │ │ │ │ <br> <br> │ │ <br>                  │ │ │ │Data Dict │ │ └────┘ <br> <br> └────┘ │ │ <br>                  │ │ │ │ Cache │ │ │ │ <br>                  │ │ │ └─────┘ │ │ │ <br>                  │ │ └────────┘ │ │ <br>                  │ └───────────────── <br> <br> ─────────┘ │ <br>                  │ ┌──┐ ┌──┐ ┌──┐ ┌──┐ <br> <br> ┌──┐ ┌───┐│ <br>    │ │PMON│ │SNON│ │DBWR│ │LGWR│ │CHPT│ <br> <br> │OTHERS││ <br>                  │ └──┘ └──┘ └──┘ └──┘ <br> <br> └──┘ └───┘│ <br>                  └─────────────────── <br> <br> ───────────┘ <br>        实例由内存和后台进程组成,它暂时存在于RAM和CPU中。 <br> <br> 当关闭运行的实例时,实例将随即消失。数据库由磁盘上的物理 <br> <br> 文件组成,不管在运行状态还是停止状态,这些文件就一直存在 <br> <br> 。因此,实例的生命周期就是其在内存中存在的时间,可以启动 <br> <br> 和停止。一旦创建数据库,数据库将永久存在。通俗的讲数据库 <br> <br> 就相当于平时安装某个程序所生成的安装目录,而实例就是运行 <br> <br> 某个程序时所需要的进程及消耗的内存。 <br>        Oracle的内存架构包含两部分系统全局区(SGA)和程序 <br> <br> 全局区(PGA)。 <br>        3.3.1 程序全局区 <br>        3.3.2 系统全局区 <br>            在操作系统提供的共享内存段实现的内存结构称为系 <br> <br> 统全局区(SGA)。SGA在实例启动时分配,在关闭时释放。在一 <br> <br> 定范围内,可以在实例运行时通过自动方式或响应DBA的指令,重 <br> <br> 新调整11g实例中的SGA及其中的组件的大小。 <br>            由上图可知SGA至少包含三种数据结构:数据库缓冲 <br> <br> 区缓存、日志缓冲区及共享池。还可能包括:大池、JAVA池。可 <br> <br> 以使用show sga,查看sga的状态。 <br>            1、共享池 <br>                 a.库缓存是内存区域,按其已分析的格式存储 <br> <br> 最近执行的代码。分析就是将编程人员编写的代码转换为可执行 <br> <br> 的代码,这是oracle根据需要执行的一个过程。通过将代码缓存 <br> <br> 在共享池,可以在不重新分析的情况下重用,极大地提高性能。 <br>                 b.数据字典缓存有时称为“行缓存”,它存储 <br> <br> 最近使用的对象定义:表、索引、用户和其他元数据定义的描述 <br> <br> 。 <br>                 c.PL/SQL区:存储的PL/SQL对象是过程、函数 <br> <br> 、打包的过程、打包的函数、对象类型定义和触发器。 <br>            2、数据库缓冲区 <br>                 数据库缓冲区是oracle用来执行SQL的工作区域 <br> <br> 。 <br>            3、日志缓冲区 <br>                 日志缓冲区是小型的、用于短期存储将写入到 <br> <br> 磁盘上的重做日志的变更向量的临时区域。日志缓冲区在启动实 <br> <br> 例时分配,如果不重新启动实例,就不能在随后调整其大小。 <br>  后台进程有: <br>   1、PMON-----程序监控器 <br>   2、SMON-----系统监控区 <br>   3、DBWR-----数据写进程 <br>   4、LGWR-----日志写进程 <br>   5、CKPT-----检查点进程 <br>   6、Others---归档进程 <br> 四、SQL语法基础(DDL、DCL、TCL、DML) <br>   SQL 全名是结构化查询语言(Structured Query Language), <br> <br> 是用于数据库中的标准数据查询语言,IBM 公司最早使用在其开 <br> <br> 发的数据库系统中。1986 年 10 月,美国 ANSI 对 SQL 进行规 <br> <br> 范后,以此作为关系式数据库管理系统的标准语言 (ANSI X3. <br> <br> 135-1986),1987 年得到国际标准组织的支持下成为国际标准。 <br> <br> 不过各种通行的数据库系统在其实践过程中都对 SQL 规范作了某 <br> <br> 些编改和扩充。所以,实际上不同数据库系统之间的 SQL 语言不 <br> <br> 能完全相互通用 <br>         DML 语句(数据操作语言)Insert、Update、 Delete、 <br> <br> Select <br>         DDL 语句(数据定义语言)Create、Alter、 Drop <br>         DCL 语句(数据控制语言)Grant、Revoke <br>         TCL 事务控制语句 Commit 、Rollback、Savepoint <br>   4.1 入门语句 <br>       普通用户连接: Conn scott/tiger <br>       超级管理员连接: Conn “sys/bluesot as sysdba” <br>       Disconnect; 断开连接-------------disc <br>       Save c:\1.txt 把 SQL 存到文件 <br>       Ed c:\1.txt 编辑 SQL 语句 <br>       @ c:\1.txt 运行 SQL 语句 <br>       Desc emp; 描述 Emp 结构 <br>       Select * from tab; 查看该用户下的所有对象 <br>       Show user; 显示当前用户 <br>       如果在 sys 用户下: 查询 Select * from emp; 会报错 <br> <br> ,原因:emp 是属于 scott,所以此时必须使用:select * from <br> <br> scott.emp; / 运行上一条语句 <br>   4.2 DDL(数据定义语言)----改变表结构 <br>      4.2.1 创建表 <br>         CREATE TABLE name ( <br>           tid VARCHAR2(5), <br>           tname VARCHAR2(20), <br>           tdate DATE, <br>           as VARCHAR(7,2) <br>         ); <br>      4.2.2 添加一列 <br>          ALTER TABLE 表名 ADD 列名 属性; <br>          ALTER TABLE student ADD age number(5); <br>      4.2.4 删除一列 <br>          ALTER TABLE table_name DROP COLUMN column_name; <br>          ALTER TABLE student DROP COLUMN age; <br>      4.2.5 修改一列的属性 <br>          ALTER TABLE table_name MODIFY column_name type; <br>          修改列名 <br>          ALTER TABLE table_name RENAME COLUMN columnname <br> <br> TO newname; <br>          修改表名 <br>          ALTER TABLE table_name RENAME TO newname; <br>      4.2.6 查看表中数据 <br>          DESC table_name; <br>      4.2.7 删除表 <br>          DROP TABLE table_name; <br>    4.3 DCL(数据控制语言) <br>      4.3.1 授权 <br>         GRANT 权限/角色 TO 用户 <br>         给 demo 用户以创建 session 的权限:GRANT create <br> <br> session TO demo; <br>         角色:-------------角色就是一堆权限的集合Create <br> <br> role myrole; <br>         Grant create table to myrole; <br>         Drop role myrole; 删除角色 <br>          1.CONNECT, RESOURCE, DBA <br>          这些预定义角色主要是为了向后兼容。其主要是用于数 <br> <br> 据库管理。oracle建议用户自己设计数据库管理和安全的权限规 <br> <br> 划,而不要简单的使用这些预定角色。将来的版本中这些角色可 <br> <br> 能不会作为预定义角色。 <br>          2.DELETE_CATALOG_ROLE, EXECUTE_CATALOG_ROLE, <br> <br> SELECT_CATALOG_ROLE 这些角色主要用于访问数据字典视图和包 <br> <br> 。 <br>          3.EXP_FULL_DATABASE, IMP_FULL_DATABASE 这两个 <br> <br> 角色用于数据导入导出工具的使用。 <br>           GRANT 权限(select、update、insert、delete) ON <br> <br> schema.table TO 用户 <br>            |- GRANT select ON scott.emp TO test ; <br>            |- Grant all on scott.emp to test; --将表相关 <br> <br> 的所有权限付给 test <br>            |- Grant update(ename) on emp to test; 可以控 <br> <br> 制到列(还有 insert) <br>      4.3.2 收权 <br>           REVOKE 权限/角色 ON schema.table FROM 用户 <br>             |- REVOKE select ON scott.emp FROM test ; <br>     4.4 TCL(事务控制语言) <br>        事务的概念:事务是一系列对数据库操作命令的集合,它 <br> <br> 有边界(commit---commit) <br>        事务的特征:A ------原子性-----不可分割性-------要 <br> <br> 么执行要么不执行 <br>                    C------一致性-----rollback <br>                    I-------隔离性-----锁的机制来保证的, <br> <br> 锁有粒度【表、行】---------只读、修改锁 <br>                              上锁---SELECT * FROM DEMO1 <br> <br> FOR UPDATE; <br>                              释放------commit、rollback <br>                    D -----持久性-------commit <br>           系统时间-----sysdate <br>                         to_date <br> <br> (‘2013/11/09’,‘yyyy/mm/dd’)--------修改日期格式 <br>         转换函数 <br>               1、To_char <br>                       select to_char(sysdate,'yyyy') from <br> <br> dual; <br>                       select to_char(sysdate,'fmyyyy-mm- <br> <br> dd') from dual; <br>                       select to_char(sal,'L999,999,999') <br> <br> from emp; <br>                       select to_char(sysdate,’D’) from <br> <br> dual;//返回星期 <br>               2、To_number <br>                       select to_number('13')+to_number <br> <br> ('14') from dual; <br>               3、To_date <br>                       Select to_date <br> <br> (‘20090210’,‘yyyyMMdd’) from dual; <br>         4.4.1 ROLLBACK <br>   回滚------回滚到它上面的离它最近的commit <br>  4.4.2 COMMIT <br>   提交-----------将数据缓冲区的数据提交到文件中去 <br>  4.4.3 SAVEPOINT------保存点 <br>   回滚点例子: <br>   INSERT INTO DEMO1(TID,TNAME) VALUES(11,'AS'); <br>   SAVEPOINT P1; <br>   INSERT INTO DEMO1(TID,TNAME) VALUES(22,'AS'); <br>   INSERT INTO DEMO1(TID,TNAME) VALUES(33,'AS'); <br>   SAVEPOINT P2; <br>   INSERT INTO DEMO1(TID,TNAME) VALUES(44,'AS'); <br>   ROLLBACK TO P2; <br>   COMMIT; <br>   INSERT INTO DEMO1(TID,TNAME) VALUES(55,'AS'); <br>   ROLLBACK TO P1;----------无法回滚 <br>     ------------查询结果:11,22,33 由于55没有提交所以没有 <br> <br> 写入文件 <br>     4.5 DML(数据操作语言)---------改变数据结构 <br>  4.5.1 insert 语句 <br>   INSERT INTO table_name() VALUES(); <br>   INSERT INTO table_name VALUES(); <br>       插入空值时,用三种格式 <br>   1、INSERT INTO demo VALUES(''); <br>   2、INSERT INTO demo VALUES(' '); <br>   3、INSERT INTO demo VALUES(NULL); <br>   INSERT INTO demo(tid,tname,tdate) VALUES <br> <br> (1,null,sysdate); <br>   INSERT INTO demo(tid,tname,tdate) VALUES(1,'',to_date <br> <br> (sysdate,'yyyy-mm-dd')); <br>   INSERT INTO demo VALUES(1,'',to_date <br> <br> ('2013/11/11','yyyy/mm/dd')); <br>   <br>   注意: <br>   1、字符串类型的字段值必须用单引号括起来,如:‘rain’; <br>   2、如果字段值里包含单引号需要进行字符串转换,把它替换成 <br> <br> 两个单引号‘’,如:‘''c''' 数据库中将插入‘c’; <br>   3、字符串类型的字段值超过定义长度会报错,最好在插入前进 <br> <br> 行长度校验; <br>   4、日期字段的字段值可以使用当前数据库的系统时间sysdate <br> <br> ,精确到秒; <br>   5、INSERT时如果要用到从1开始自动增长的序列号,应该先建 <br> <br> 立一个序列号。 <br>   <br>  4.5.2 update 语句 <br>   UPDATE table_name SET column_name=值 WHERE 查询条件 <br>   UPDATE demo SET tname='张三' WHERE tid=1; <br>   COMMIT;------是更新生效 <br>  4.5.3 delete 语句-----不能回退 <br>   DELETE TABLE table_name;--------------只能删除数据,不 <br> <br> 能释放空间 <br>   TRUNCATE TABLE table_name;---------------删除数据并释 <br> <br> 放空间 <br>   DELETE TABLE demo; <br>   TRUNCATE TABLE demo; <br>   4.5.4 select 语句 <br>   A 、简单的 Select 语句 <br>   SELECT * FROM table_name; <br>   SELECT * FROM demo; <br>   B、空值 is null <br>   SELECT * FROM demo where tname is null; <br> <br> 第五章 Select查询 <br> 结构: 执行顺序 <br> SELECT * 5 <br>        FROM table_name 1 <br>             WHERE -----分组前的条件 2 <br>    GROUP BY 3 <br> HAVING -----分组后的条件 4 <br>                            ORDER BY column_name ASC/DESC; <br> <br> 6 <br> ----------------------------- <br> 子句、聚合函数、友好列 列名 AS 别名 <br> ----------------------------- <br> 5.1 简单查询 <br> 5.1.1 查看表结构 <br> DESC table_name; <br> DESC emp; <br>   <br> 5.1.2查看所有的列 <br> SELECT * FROM table_name; <br> SELECT * FROM emp; <br>   <br> 5.1.3 查看指定列 <br> SELECT 列名 FROM table_name; <br> SELECT empno FROM emp; <br> 5.1.4 查看指定行 <br> SELECT * FROM table_name WHERE column_name=值; <br> SELECT * FROM emp WHERE empno=7369; <br> 5.1.5 使用算术表达式 + 、- 、/ 、* <br> SELECT ename,sal+1 FROM EMP; <br> ENAME SAL+1 <br> ---------- ---------- <br> SMITH 801 <br> ALLEN 1601 <br> WARD 1251 <br> SELECT ename,sal-2 FROM EMP; <br> ENAME SAL-1 <br> ---------- ---------- <br> SMITH 799 <br> ALLEN 1599 <br> WARD 1249 <br> SELECT ename,sal*2 FROM EMP; <br> ENAME SAL*2 <br> ---------- ---------- <br> SMITH 1600 <br> ALLEN 3200 <br> WARD 2500 <br> SELECT ename,sal/2 FROM EMP; <br> ENAME SAL/2 <br> ---------- ---------- <br> SMITH 400 <br> ALLEN 800 <br> WARD 625 <br> nvl(comm,0)的意思是,如果comm中有值,则nvl(comm,0)=comm; <br> <br> comm中无值,则nvl(comm,0)=0 <br> 5.1.3 连接运算符 || <br> SELECT 'how'||'do' ||sno; <br> 5.1.4 使用字段别名 AS <br> SELECT * FROM DEMO1 "Asd";-------带引号可以保证输入的结果 <br> <br> 有大小写 <br> SELECT * FROM DEMO1 asd; <br> 5.1.5 空值 IS NULL、 IS NOT NULL <br> SQL>SELECT * FROM EMP WHERE COMM IS NOT NULL AND SAL IN <br> <br> (SELECT ENAME,sal FROM emp WHERE ENAME LIKE '_O%') ; <br> 5.1.6 去除重复行 DISTINCT <br> SQL>SELECT DISTINCT DEPTNO FROM EMP ORDER BY DEPTNO <br> SQL>SELECT DEPTNO FROM EMP GROUP BY DEPTNO ORDER BY <br> <br> DEPTNO <br> 5.1.7 查询结果排序 ORDER BY ASC/DESC <br> 逆序: <br> SQL> SELECT * FROM emp WHERE job='CLERK' OR <br> <br> ename='MILLER' ORDER BY SAL DESC; <br> 顺序: <br> SQL> SELECT * FROM emp WHERE job='CLERK' OR <br> <br> ename='MILLER' ORDER BY SAL ASC; <br> SQL> SELECT * FROM emp WHERE job='CLERK' OR <br> <br> ename='MILLER' ORDER BY SAL ; <br> 5.1.8 关系运算符 >、 < 、=、(!= or <>) MOD(模,类似于%)、 <br> <br> BETWEEN AND、 NOT BETWEEN AND <br> SQL> SELECT DISTINCT MGR FROM emp WHERE MGR<>7788; <br> SQL>SELECT DISTINCT MGR FROM emp WHERE MGR BETWEEN 7788 <br> <br> AND 7902; <br> SQL>SELECT * FROM emp WHERE MOD(DEPTNO,100)=2; <br> SQL>SELECT * FROM EMP1 WHERE EMPNO NOT BETWEEN 7369 AND <br> <br> 7521; <br> SQL>SELECT * FROM EMP1 WHERE EMPNO>=7369 AND EMPNO<=7521; <br> 5.1.9 操作 IN、NOT IN <br> SQL> SELECT ENAME,SAL FROM EMP WHERE SAL IN(SELECT MAX <br> <br> (SAL) FROM EMP1 GROUP BY DEPTNO); <br> 5.1.10 模糊查询 LIKE、NOT LIKE----只针对字符型 <br> % 表示零或多个字符 <br> _ 表示一个字符 <br> 对于特殊符号可使用ESCAPE 标识符来查找 <br> select * from emp where ename like '%*_%' escape '*' <br> 上面的escape表示*后面的那个符号不当成特殊字符处理,就是查 <br> <br> 找普通的_符号 <br> 5.1.11 逻辑运算符 AND、OR、NOT <br> SQL> select * from emp where job='CLERK' OR <br> <br> ename='MILLER'; <br> SQL> select * from emp where job='CLERK' AND <br> <br> ename='MILLER'; <br> 5.1.12 ANY、ALL <br> SQL>SELECT * FROM EMP WHERE EMPNO IN(7369,7521,7782); <br> SQL>SELECT * FROM EMP WHERE EMPNO>ANY(7369,7521,7782);-- <br> <br> 大于min <br> SQL>SELECT * FROM EMP WHERE EMPNO>ALL(7369,7521,7782);-- <br> <br> 大于max <br> SQL>SELECT * FROM EMP WHERE EMPNO<ANY(7369,7521,7782);-- <br> <br> 小于max <br> SQL>SELECT * FROM EMP WHERE EMPNO<ALL(7369,7521,7782);-- <br> <br> 小于min <br> 5.1.13 练习 <br> 1、选择在部门30中员工的所有信息 <br> Select * from emp where deptno=30; <br> 2、列出职位为(MANAGER)的员工的编号,姓名 <br> Select empno,ename from emp where job ="Manager"; <br> 3、找出奖金高于工资的员工 <br> Select * from emp where comm>sal; <br> 4、找出每个员工奖金和工资的总和 <br> Select sal+comm,ename from emp; <br> 5、找出部门10中的经理(MANAGER)和部门20中的普通员工(CLERK) <br> Select * from emp where (deptno=10 and job=?MANAGER?) or <br> <br> (deptno=20 and job=?CLERK?); <br> 6、找出部门10中既不是经理也不是普通员工,而且工资大于等于 <br> <br> 2000的员工 <br> Select * from emp where deptno=10 and job not in <br> <br> ('MANAGER') and sal>=2000; <br> 7、找出有奖金的员工的不同工作 <br> Select distinct job from emp where comm is not null and <br> <br> comm>0; <br> 8、找出没有奖金或者奖金低于500的员工 <br> Select * from emp where comm<500 or comm is null; <br> 9、显示雇员姓名,根据其服务年限,将最老的雇员排在最前面 <br> select ename from emp order by hiredate ; <br> 10、SQL>SELECT DEPTNO,MAX(SAL) AS tot, <br>                MIN(COMM) AS MCOMM, <br>                SUM(COMM) SUMC, <br>                TRUNC(AVG(SAL+NVL(COMM,0)))TAVG, <br>                ROUND(AVG(SAL+NVL(COMM,0)),2)RAVG, <br>                COUNT(*) <br>        FROM EMP <br>             HAVING COUNT(*)>3 <br>                   GROUP BY DEPTNO <br>                         ORDER BY DEPTNO <br>             <br>             11、SQL>SELECT ENAME,SAL <br>                 FROM EMP <br>                          WHERE SAL IN(SELECT MAX(SAL) <br>                                FROM EMP1 <br>                                             GROUP BY <br> <br> DEPTNO); <br> 5.2 多表查询 <br> INNER JOIN:内连接 <br> JOIN: 如果表中有至少一个匹配,则返回行 <br> LEFT JOIN: 即使右表中没有匹配,也从左表返回所有的行 <br> RIGHT JOIN: 即使左表中没有匹配,也从右表返回所有的行 <br> FULL JOIN: 只要其中一个表中存在匹配,就返回行 <br> 5.2.1、笛卡尔集(Cross Join)------------列相加,行相乘 <br> Select * from emp,dept; <br> 5.2.2、等值连接(Equijoin)(Natural join..on)---------隐式 <br> <br> 内联 <br> select empno, ename, sal, emp.deptno, dname from emp, <br> <br> dept where emp.deptno = dept.deptno; <br> 5.2.3、非等值连接(Non-Equijoin) <br> select ename,empno,grade from emp,salgrade where sal <br> <br> between losal and hisal; <br> 5.2.4、自联接(Self join) <br> select column_name from table_name1,table_name2 where 条 <br> <br> 件; <br> select e.empno,e.ename,m.empno,m.ename from emp e,emp m <br> <br> where m.mgr = e.empno; <br> 5.2.5、内联接(Inner Join)----------显式外联 <br> SELECT column_name(s) <br> FROM table_name1 <br> INNER JOIN table_name2 <br> ON table_name1.column_name=table_name2.column_name <br> 5.2.6、 左外联接(Left Outer Join ) <br> 左外连接:在内联接的基础上,增加左表中没有匹配的行,也就 <br> <br> 是说,左表中的记录总会出现在最终结果集中 <br> SELECT column_name(s) <br> FROM table_name1 <br> LEFT JOIN table_name2 <br> ON table_name1.column_name=table_name2.column_name <br> select s.sid,s.sname,s1.sid,s1.sname from student <br> <br> s,student1 s1 where s.sid=s1.sid(+); <br> 1、先通过from自句判断左表和右表; <br> 2、接着看加号作用在那个表别名上; <br> 3、如果作用在右表上,则为左外连接,否则为右外连接 <br> select empno,ename,dname from emp left outer join dept on <br> <br> emp.deptno = dept.deptno; <br> 5.2.7、右外联接(Right Outer Join) <br> 右外连接:在内联接的基础上,增加右表中没有匹配的行,也就 <br> <br> 是说,右表中的记录总会出现在最终结果集中 <br> SELECT column_name(s) <br> FROM table_name1 <br> RIGHT JOIN table_name2 <br> ON table_name1.column_name=table_name2.column_name <br> 右外联接转换为内联接 <br> SELECT column_name(s) <br> FROM table_name1 <br> RIGHT JOIN table_name2 <br> ON table_name1.column_name=table_name2.column_name WHERE <br> <br> table_name1.column_name is not null; <br> select s.sid,s.sname,s1.sid,s1.sname from student <br> <br> s,student1 s1 where s.sid(+)=s1.sid; <br> select empno,ename,dname from emp right outer join dept <br> <br> on emp.deptno= dept.deptno; <br> select * from emp1 e right join dept d on <br> <br> e.deptno=d.deptno where e.deptno is not null; <br> 5.2.8、全外联接(Full Outer Join) <br> SELECT column_name(s) <br> FROM table_name1 <br> FULL JOIN table_name2 <br> ON table_name1.column_name=table_name2.column_name <br> select empno,ename,dname from emp full outer join dept on <br> <br> emp.deptno = dept.deptno; <br> 5.2.9、集合操作 <br>  · UNION:并集,所有的内容都查询,重复的显示一次 <br>   ·UNION ALL:并集,所有的内容都显示,包括重复的 <br>  · INTERSECT:交集:只显示重复的 <br>  · MINUS:差集:只显示对方没有的(跟顺序是有关系的) <br> SELECT column_name(s) FROM table_name1 <br> UNION/INTERSECT/MINUS <br> SELECT column_name(s) FROM table_name2 <br> 首先建立一张只包含 20 部门员工信息的表: <br>  CREATE TABLE emp20 AS SELECT * FROM emp WHERE deptno=20 <br> <br> ; <br> 1、验证 UNION 及 UNION ALL <br>  UNION:SELECT * FROM emp UNION SELECT * FROM emp20 ; <br>  使用此语句重复的内容不再显示了 <br>  UNION ALL:SELECT * FROM emp UNION ALL SELECT * FROM <br> <br> emp20 ; <br>  重复的内容依然显示 <br> 2、验证 INTERSECT <br>  SELECT * FROM emp INTERSECT SELECT * FROM emp20 ; 只显示 <br> <br> 了两个表中彼此重复的记录。 <br>   <br> MINUS:返回差异的记录 <br>  SELECT * FROM emp MINUS SELECT * FROM emp20 ; 只显示了两 <br> <br> 张表中的不同记录满链接也可以用以下的方式来表示: <br> select t1.id,t2.id from table1 t1,table t2 where <br> <br> t1.id=t2.id(+) union <br> select t1.id,t2.id from table1 t1,table t2 where t1.id <br> <br> (+)=t2.id <br> 5.3 子查询 <br> 5.3.1、单行子查询 <br> select * from emp <br> where sal > (select sal from emp where empno = 7566); <br> 5.3.2、 子查询空值/多值问题 <br> 如果子查询未返回任何行,则主查询也不会返回任何结果 <br> (空值)select * from emp where sal > (select sal from emp <br> <br> where empno = 8888); <br> 如果子查询返回单行结果,则为单行子查询,可以在主查询中对 <br> <br> 其使用相应的单行记录比较运算符 <br> (正常)select * from emp where sal > (select sal from emp <br> <br> where empno = 7566); <br> 如果子查询返回多行结果,则为多行子查询,此时不允许对其使 <br> <br> 用单行记录比较运算符 <br> (多值)select * from emp where sal > (select avg(sal) from <br> <br> emp group by deptno);//非法----错误的 <br>   <br> 5.3.3、 多行子查询 <br> select * from emp where sal > any(select avg(sal) from <br> <br> emp group by deptno); <br> select * from emp where sal > all(select avg(sal) from <br> <br> emp group by deptno); <br> select * from emp where job in (select job from emp where <br> <br> ename = 'MARTIN' or ename = 'SMITH'); <br> 5.3.4、 分页查询 <br> Oracle分页 <br> ①采用rownum关键字(三层嵌套) <br> SELECT * FROM( <br>   SELECT A.*,ROWNUM num FROM ( <br> SELECT * FROM t_order)A <br> WHERE ROWNUM<=15) <br> WHERE num>=5; --返回第5-15行数据 <br> ②采用row_number解析函数进行分页(效率更高) <br> SELECT xx.* FROM( <br> SELECT t.*,row_number() over(ORDER BY o_id)AS num <br> FROM t_order t <br> )xx <br> WHERE num BETWEEN 5 AND 15; <br> ROWID和ROWNUM的区别 <br> 1、ROWID是物理地址,用于定位ORACLE中具体数据的物理存储位 <br> <br> 置是唯一的18位物理编号,而ROWNUM则是根据sql查询后得到的结 <br> <br> 果自动加上去的 <br> 2、ROWNUM是暂时的并且总是从1开始排起,而ROWID是永久的。 <br> 解析函数能用格式 <br> 函数() over(pertion by 字段 order by 字段); <br> ROW_NUMBER(): Row_number函数返回一个唯一的值,当碰到相同 <br> <br> 数据时,排名按照记录集中记录的顺序依次递增。 row_number() <br> <br> 和rownum差不多,功能更强一点(可以在各个分组内从1开时排序 <br> <br> ),因为row_number()是分析函数而rownum是伪列所以 <br> <br> row_number()一定要over而rownum不能over。 <br> RANK():Rank函数返回一个唯一的值,除非遇到相同的数据,此 <br> <br> 时所有相同数据的排名是一样的,同时会在最后一条相同记录和 <br> <br> 下一条不同记录的排名之间空出排名。rank()是跳跃排序,有两 <br> <br> 个第二名时接下来就是第四名(同样是在各个分组内)。 <br> DENSE_RANK():Dense_rank函数返回一个唯一的值,除非当碰到 <br> <br> 相同数据,此时所有相同数据的排名都是一样的。 <br> dense_rank()是连续排序,有两个第二名时仍然跟着第三名。他 <br> <br> 和row_number的区别在于row_number是没有重复值的。 <br> dense_rank()是连续排序,有两个第二名时仍然跟着第三名。他 <br> <br> 和row_number的区别在于row_number是没有重复值的。 <br>  下面举个例子: <br> SQL> select * from user_order order by customer_sales; <br>  REGION_ID CUSTOMER_ID CUSTOMER_SALES <br> ---------- ----------- -------------- <br>         10 30 1216858 <br>          5 2 1224992 <br>          9 24 1224992 <br>          9 23 1224992 <br>          8 18 1253840 <br> 【3】row_number()、rank()、dense_rank()这三个分析函数的区 <br> <br> 别实例 <br> SQL>SELECT empno, deptno, SUM(sal) total, <br>            RANK() OVER(ORDER BY SUM(sal) DESC) RANK, <br>            dense_rank() OVER(ORDER BY SUM(sal) DESC) <br> <br> dense_rank, <br>            row_number() OVER(ORDER BY SUM(sal) DESC) <br> <br> row_number <br> FROM emp1 GROUP BY empno, deptno; <br> -------------------------------------------------- <br> 1 7839 10 5000 1 1 1 <br> 2 7902 20 3000 2 2 2 <br> 3 7788 20 3000 2 2 3 <br> 4 7566 20 2975 4 3 4 <br> 5 7698 30 2850 5 4 5 <br> 6 7782 10 2450 6 5 6 <br> 7 7499 30 1600 7 6 7 <br> 比较上面3种不同的策略,我们在选择的时候就要根据客户的需求 <br> <br> 来定夺了: <br> ①假如客户就只需要指定数目的记录,那么采用row_number是最 <br> <br> 简单的,但有漏掉的记录的危险 <br> ②假如客户需要所有达到排名水平的记录,那么采用rank或 <br> <br> dense_rank是不错的选择。至于选择哪一种则看客户的需要,选 <br> <br> 择dense_rank或得到最大的记录 <br> Mysql分页采用limt关键字 <br> select * from t_order limit 5,10; #返回第6-15行数据 <br> select * from t_order limit 5; #返回前5行 <br> select * from t_order limit 0,5; #返回前5行 <br> Mssql 2000分页采用top关键字(20005以上版本也支持关键字 <br> <br> rownum) <br> Select top 10 * from t_order where id not in (select id <br> <br> from t_order where id>5 ); //返回第6到15行数据其中10表示 <br> <br> 取10记录 5表示从第5条记录开始取 <br> sql server 分页采用top关键字 <br> 5.3.5、 in 、exists <br> EXISTS 的执行流程 <br> select * from t1 where exists ( select null from t2 where <br> <br> y = x ) <br> 可以理解为: <br>   for x in ( select * from t1 ) loop <br>  if ( exists ( select null from t2 where y = x.x ) then <br>         OUTPUT THE RECORD <br>  end if; <br>  end loop; <br> 对于 in 和 exists 的性能区别: <br>   如果子查询得出的结果集记录较少,主查询中的表较大且又有 <br> <br> 索引时应该用 in,反之如果外层的主查询记录较少,子查询中的 <br> <br> 表大,又有索引时使用 exists。 <br>   其实我们区分 in 和 exists 主要是造成了驱动顺序的改变( <br> <br> 这是性能变化的关键),如果是 exists,那么以外层表为驱动表 <br> <br> ,先被访问,如果是 IN,那么先执行子查询,所以我们会以驱动 <br> <br> 表的快速返回为目标,那么就会考虑到索引及结果集的关系了 另 <br> <br> 外 IN 是不对 NULL 进行处理 <br> 如: <br> select 1 from dual where not in (0,1,2,null) 为空 <br> 第六章 约束 <br> 约束就是指对插入数据的各种限制,例如:人员的姓名不能为空 <br> <br> ,人的年龄只能在0~150 岁之间。约束可以对数据库中的数据进 <br> <br> 行保护。 约束可以在建表的时候直接声明,也可以为已建好的表 <br> <br> 添加约束。 <br>   <br> 6.1、NOT NULL:非空约束 例如:姓名不能为空 <br> CREATE TABLE person( <br> pid NUMBER , <br> name VARCHAR2(30) NOT NULL <br> ) ; <br>   <br> alter table emp <br> -- 插入数据 <br> INSERT INTO person(pid,name) VALUES (11,'张三'); <br> -- 错误的数据,会受到约束限制,无法插入 <br> INSERT INTO person(pid) VALUES (12); <br>   <br> 6.2、 PRIMARY KEY:主键约束 <br>  · 不能重复,不能为空 · 例如:身份证号不能为空。 现在假 <br> <br> 设pid字段不能为空,且不能重复。 <br> DROP TABLE person ; <br> CREATE TABLE person <br> ( <br>  pid NUMBER PRIMARY KEY , name VARCHAR(30) NOT NULL <br> ) ; <br> -- 插入数据 <br> INSERT INTO person(pid,name) VALUES (11,'张三'); <br> -- 主键重复了 <br> INSERT INTO person(pid,name) VALUES (11,'李四'); <br>   <br> 6.3、UNIQUE:唯一约束,值不能重复(空值除外) 人员中有电 <br> <br> 话号码,电话号码不能重复。 <br> DROP TABLE person ; <br> CREATE TABLE person <br> ( <br>  pid NUMBER PRIMARY KEY NOT NULL , name VARCHAR(30) NOT <br> <br> NULL , tel VARCHAR(50) UNIQUE <br> ) ; <br> -- 插入数据 <br> INSERT INTO person(pid,name,tel) VALUES (11,'张 <br> <br> 三','1234567'); <br> -- 电话重复了 <br> INSERT INTO person(pid,name,tel) VALUES (12,'李 <br> <br> 四','1234567'); <br>   <br> 6.4、CHECK:条件约束,插入的数据必须满足某些条件 <br>  例如:人员有年龄,年龄的取值只能是 0~150 岁之间 <br> DROP TABLE person ; <br> CREATE TABLE person( <br>    pid NUMBER PRIMARY KEY NOT NULL , <br>  name VARCHAR2(30) NOT NULL , <br> tel VARCHAR2(50) NOT NULL UNIQUE , <br> age NUMBER CHECK(age BETWEEN 0 AND 150) <br> ) ; <br> -- 插入数据 <br> INSERT INTO person(pid,name,tel,age) VALUES (11,'张 <br> <br> 三','1234567',30); <br> -- 年龄的输入错误 <br> INSERT INTO person(pid,name,tel,age) VALUES (12,'李 <br> <br> 四','2345678',-100); <br>  alter table product <br> add constriant chk_product_unitprice check(unitprice>0); <br> 6.5、Foreign Key:外键 <br>  例如:有以下一种情况: <br>  · 一个人有很多本书: <br>   |- Person 表 <br>   |- Book 表:而且book 中的每一条记录表示一本书的信息,一 <br> <br> 本书的信息属于一个人 <br> CREATE TABLE book( <br>  bid NUMBER PRIMARY KEY NOT NULL , <br>  name VARCHAR(50) , <br>  -- 书应该属于一个人 pid NUMBER <br> ) ; <br>  如果使用了以上的表直接创建,则插入下面的记录有效: <br> INSERT INTO book(bid,name,pid) VALUES(1001,'JAVA',12) ; <br>  以上的代码没有任何错误,但是没有任何意义,因为一本书应该 <br> <br> 属于一个人,所以在此处的pid的取值应该与person 表中的pid一 <br> <br> 致。 <br>  此时就需要外键的支持。修改book 的表结构 <br> DROP TABLE book ; <br> CREATE TABLE book <br> ( <br>  bid NUMBER PRIMARY KEY NOT NULL , name VARCHAR(50) , <br>  -- 书应该属于一个人 pid NUMBER REFERENCES person(pid) ON <br> <br> DELETE CASCADE <br>  -- 建立约束:book_pid_fk,与person中的pid 为主-外键关系 <br>  --CONSTRAINT book_pid_fk FOREIGN KEY(pid) REFERENCES <br> <br> person(pid) <br> ) ; <br>   <br> INSERT INTO book(bid,name,pid) VALUES(1001,'JAVA',12) ; <br> 6.6、级联删除 <br>  此时如果想完成删除person 表的数据同时自动删除掉book 表的 <br> <br> 数据操作,则必须使用级联删除。 <br>  在建立外键的时候必须指定级联删除(ON DELETE CASCADE)。 <br> CREATE TABLE book <br> ( <br>  bid NUMBER PRIMARY KEY NOT NULL , name VARCHAR(50) , <br>  -- 书应该属于一个人 <br>  pid NUMBER , <br>  -- 建立约束:book_pid_fk,与person中的pid 为主-外键关系 <br>  CONSTRAINT book_pid_fk FOREIGN KEY(pid) REFERENCES <br> <br> person(pid) ON DELETE CASCADE <br> ) ; <br> DROP TABLE book ; <br> DROP TABLE person ; <br> CREATE TABLE person( <br>       pid NUMBER , <br>       name VARCHAR(30) NOT NULL , <br>       tel VARCHAR(50) , <br>       age NUMBER <br> ) ; <br> CREATE TABLE book( <br>       bid NUMBER , <br>       name VARCHAR2(50) , <br>       pid NUMBER <br> ) ; <br>   <br>  以上两张表中没有任何约束,下面使用 alter 命令为表添加约 <br> <br> 束 <br> ALTER TABLE table_name ADD CONSTRAINT column_name 约束; <br> 1、 为两个表添加主键: <br>   · person 表 pid 为主键: <br>    ALTER TABLE person ADD CONSTRAINT person_pid_pk <br> <br> PRIMARY KEY(pid) ; <br>   · book 表 bid 为主键: <br>    ALTER TABLE book ADD CONSTRAINT book_bid_pk PRIMARY <br> <br> KEY(bid) ; <br> 2、 为 person 表中的 tel 添加唯一约束: <br>   ALTER TABLE person ADD CONSTRAINT person_tel_uk UNIQUE <br> <br> (tel) ; <br> 3、 为 person 表中的 age 添加检查约束: <br>   ALTER TABLE person ADD CONSTRAINT person_age_ck CHECK <br> <br> (age BETWEEN 0 AND <br> 150) ; <br>  4、 为 book 表中的 pid 添加与 person 的主-外键约束,要求 <br> <br> 带级联删除 <br>   ALTER TABLE book ADD CONSTRAINT person_book_pid_fk <br> <br> FOREIGN KEY (pid) <br> REFERENCES person(pid) ON DELETE CASCADE ; <br>   <br> Q:如何用alter添加非空约束 <br> A:用 check约束 <br> 6.7、删除约束: <br>  ALTER TABLE book DROP CONSTRAINT person_book_pid_fk ; <br> alter table student drop unique(tel); <br> 6.8、 启用约束 <br> ALTER TABLE book enable CONSTRAINT person_book_pid_fk ; <br> 6.9、 禁用约束 <br> ALTER TABLE book disable CONSTRAINT person_book_pid_fk ; <br> 第七章 SQL函数 <br> 7.1 单行函数 <br> 1、字符函数 <br> Upper -------大写 <br> SELECT Upper ('abcde') FROM dual ; <br> SELECT * FROM emp WHERE ename=UPPER('smith') ; <br> Lower --------小写 <br> SELECT lower('ABCDE') FROM dual ; <br> Initcap--------首字母大写 <br> Select initcap(ename) from emp; <br> Concat----联接 <br> Select concat('a','b') from dual; <br> Select 'a'||'b' from dual; <br> Substr------截取 <br> Select substr('abcde',length('abcde')-2) from dual; <br> Select substr('abcde',-3,3) from dual; <br> Length------长度 <br> Select length(ename) from emp; <br> Replace------替代 <br> Select replace(ename,'a','A') from emp; <br> Instr---------- indexof <br> Select instr('Hello World','or') from dual; <br> Lpad------------左侧填充 lpad() *****Smith <br> lpad('Smith',10,'*') <br> Rpad-------------右侧填充 rpad()Smith***** <br> rpad('Smith',10,'*') <br> Trim-------------过滤首尾空格 trim() Mr Smith <br> trim(' Mr Smith ') <br> 2、数值函数 <br> Round <br> select round(412,-2) from dual; --400 <br> select round(412.313,2) from dual; <br> Mod <br> select MOD(412,3) from dual; <br> Trunc <br> select trunc(412.13,-2) from dual; <br> 3、日期函数 <br> Months_between() <br> select months_between(sysdate,hiredate) from emp; <br> Add_months() <br> select add_months(sysdate,1) from dual; <br> Next_day() <br> select next_day(sysdate,'星期一') from dual; <br> Last_day <br> select last_day(sysdate) from dual; <br> 4.4、转换函数 <br> To_char <br> select to_char(sysdate,'yyyy') from dual; select to_char <br> <br> (sysdate,'fmyyyy-mm-dd') from dual; select to_char <br> <br> (sal,'L999,999,999') from emp; select to_char(sysdate,’D <br> <br> ’) from dual;//返回星期 <br> To_number <br> select to_number('13')+to_number('14') from dual; <br> To_date <br> Select to_date(?20090210?,?yyyyMMdd?) from dual; <br> 5、通用函数 <br> NVL()函数 <br> select nvl(comm,0) from emp; <br> NULLIF()函数 <br> 如果表达式 exp1 与 exp2 的值相等则返回 null,否则返回 <br> <br> exp1 的值 <br> NVL2()函数 select empno, ename, sal, comm, nvl2(comm, <br> <br> sal+comm, sal) total from emp; <br> COALESCE()函数 <br> 依次考察各参数表达式,遇到非 null 值即停止并返回该值。 <br> select empno, ename, sal, comm, coalesce(sal+comm, sal, <br> <br> 0)总收入 from emp; <br> CASE 表达式------区间 <br> SQL>select empno, <br>           ename, <br>           sal, <br>           case deptno <br> when 10 then '财务部' <br> when 20 then '研发部' <br> when 30 then '销售部' <br> else '未知部门' <br> end 部门 <br> from emp; <br> SQL>SELECT e.*, <br>     CASE <br>         WHEN sal>=3000 THEN '高' <br>         WHEN sal>=2000 AND sal<3000 THEN '中' <br>         WHEN sal<2000 AND sal>0 THEN '高' <br>         ELSE 'un' <br>      END ca <br> FROM emp1 e; <br> DECODE()函数------------离散的值 <br> SQL>select empno, ename, sal, <br>     decode(deptno, <br>                                 10, '财务部', <br>                                 20, '研发部', <br>                                 30, '销售部', <br>                                 '未知部门') 部门 <br> from emp; <br>   <br> 单行函数嵌套 <br> select empno, lpad(initcap(trim(ename)),10,' ') name, <br> <br> job, sal from emp; <br> 7.2 分组函数 <br> 1、COUNT <br> 如果数据库表的没有数据,count(*)返回的不是 null,而是 0 <br> 2、Avg,max,min,sum <br> 3、nvl----分组函数与空值 <br> 分组函数省略列中的空值 <br> select avg(comm) from emp; select sum(comm) from emp; <br> 可使用 NVL()函数强制分组函数处理空值 select avg(nvl(comm, <br> <br> 0)) from emp; <br> 4、GROUP BY 子句 <br> 出现在 SELECT 列表中的字段或者出现在 order by 后面的字段 <br> <br> ,如果不是包含在分组函数中,那么该字段必须同时在 GROUP BY <br> <br> 子句中出现。包含在 GROUP BY 子句中的字段则不必须出现在 <br> <br> SELECT 列表中。 <br> 可使用 where 字句限定查询条件,可使用 Order by 子句指定排 <br> <br> 序方式 <br> 如果没有 GROUP BY 子句,SELECT 列表中不允许出现字段(单行 <br> <br> 函数)与分组函数混用的情况。 <br> select empno, sal from emp; //合法 select avg(sal) from <br> <br> emp; //合法 select empno, initcap(ename), avg(sal) from <br> <br> emp; //非法 <br>  不允许在 WHERE 子句中使用分组函数。 select deptno, avg <br> <br> (sal) from emp where avg(sal) > 2000; group by deptno; <br> 5、HAVING 子句 <br> select deptno, job, avg(sal) <br> from emp <br> where hiredate >= to_date('1981-05-01','yyyy-mm-dd') <br> <br> group by deptno,job having avg(sal) > 1200 order by <br> <br> deptno,job; <br> 6、分组函数嵌套 <br> select max(avg(sal)) from emp group by deptno; <br>   <br> 第八章 PLSQL变量与常量 <br> 1、声明变量 <br>   变量一般都在PL/SQL块的声明部分声明,引用变量前必须首 <br> <br> 先声明,要在执行或异常处理部分使用变量,那么变量必须首先 <br> <br> 在声明部分进行声明。 <br>   声明变量的语法如下: <br> Variable_name [CONSTANT] databyte [NOT NULL][:=|DEFAULT <br> <br> expression] <br>      注意:可以在声明变量的同时给变量强制性的加上NOT NULL <br> <br> 约束条件,此时变量在初始化时必须赋值。 <br> 2、给变量赋值 <br>   给变量赋值有两种方式: <br>   . 直接给变量赋值 <br>    X:=200; <br>    Y=Y+(X*20); <br>   . 通过SQL SELECT INTO 或FETCH INTO给变量赋值 <br> SELECT SUM(SALARY),SUM(SALARY*0.1) <br> INTO TOTAL_SALARY,TATAL_COMMISSION <br> FROM EMPLOYEE <br> WHERE DEPT=10; <br> 3、常量 <br>   常量与变量相似,但常量的值在程序内部不能改变,常量的 <br> <br> 值在定义时赋予,,他的声明方式与变量相似,但必须包括关键 <br> <br> 字CONSTANT。常量和变量都可被定义为SQL和用户定义的数据类型 <br> <br> 。 <br> ZERO_VALUE CONSTANT NUMBER:=0; <br> 4、标量(scalar)数据类型 <br>   标量(scalar)数据类型没有内部组件,他们大致可分为以下 <br> <br> 四类: <br>    . number <br> . char <br> . date/time <br> . boolean <br>   表1 Numer <br> Datatype Range Subtypes description <br> BINARY_INTEGER -214748-2147483647 NATURAL <br> NATURAL <br> NPOSITIVE <br> POSITIVEN <br> SIGNTYPE <br> 用于存储单字节整数。 <br> 要求存储长度低于NUMBER值。 <br> 用于限制范围的子类型(SUBTYPE): <br>  NATURAL:用于非负数 <br>  POSITIVE:只用于正数 <br>  NATURALN:只用于非负数和非NULL值 <br>  POSITIVEN:只用于正数,不能用于NULL值 <br>  SIGNTYPE:只有值:-1、0或1. <br> NUMBER 1.0E-130-9.99E125 DEC <br> DECIMAL <br> DOUBLE <br> PRECISION <br> FLOAT <br> INTEGERIC <br> INT <br> NUMERIC <br> REAL <br> SMALLINT 存储数字值,包括整数和浮点数。可以选择精度和刻度 <br> <br> 方式,语法: <br> number[([,])]。 <br> 缺省的精度是38,scale是0. <br> PLS_INTEGER -2147483647-2147483647 与BINARY_INTEGER基本相 <br> <br> 同,但采用机器运算时,PLS_INTEGER提供更好的性能 。 <br>   表2 字符数据类型 <br> datatype rang subtype description <br> CHAR 最大长度32767字节 CHARACTER 存储定长字符串,如果长度 <br> <br> 没有确定,缺省是1 <br> LONG 最大长度2147483647字节 存储可变长度字符串 <br> RAW 最大长度32767字节 用于存储二进制数据和字节字符串,当 <br> <br> 在两个数据库之间进行传递时,RAW数据不在字符集之间进行转换 <br> <br> 。 <br> LONGRAW 最大长度2147483647 与LONG数据类型相似,同样他也不 <br> <br> 能在字符集之间进行转换。 <br> ROWID 18个字节 与数据库ROWID伪列类型相同,能够存储一个行 <br> <br> 标示符,可以将行标示符看作数据库中每一行的唯一键值。 <br> VARCHAR2 最大长度32767字节 STRINGVARCHAR 与VARCHAR数据类 <br> <br> 型相似,存储可变长度的字符串。声明方法与VARCHAR相同 <br>   表3 DATE和BOOLEAN <br> datatype range description <br> BOOLEAN TRUE/FALSE 存储逻辑值TRUE或FALSE,无参数 <br> DATE 01/01/4712 BC 存储固定长的日期和时间值,日期值中包含 <br> <br> 时间 <br> LOB数据类型 <br>   LOB(大对象,Large object) 数据类型用于存储类似图像,声 <br> <br> 音这样的大型数据对象,LOB数据对象可以是二进制数据也可以是 <br> <br> 字符数据,其最大长度不超过4G。LOB数据类型支持任意访问方式 <br> <br> ,LONG只支持顺序访问方式。LOB存储在一个单独的位置上,同时 <br> <br> 一个"LOB定位符"(LOB locator)存储在原始的表中,该定位符是 <br> <br> 一个指向实际数据的指针。在PL/SQL中操作LOB数据对象使用 <br> <br> ORACLE提供的包DBMS_LOB.LOB数据类型可分为以下四类: <br>   . BFILE----------------二进制文件 <br>   . BLOB--------------二进制对象 <br>   . CLOB---------------字符型对象 <br>   . NCLOB-------------nchar类型对象 <br> 操作符 <br>   PL/SQL有一系列操作符。操作符分为下面几类: <br>   . 算术操作符 <br>   . 关系操作符 <br>   . 比较操作符 <br>   . 逻辑操作符 <br>   算术操作符如表4所示 <br> operator operation <br> + 加 <br> - 减 <br> / 除 <br> * 乘 <br> ** 乘方 <br>   关系操作符主要用于条件判断语句或用于where子串中,关系 <br> <br> 操作符检查条件和结果是否为true或false, <br> 表5PL/SQL中的关系操作符 <br> operator operation <br> < 小于操作符 <br> <= 小于或等于操作符 <br> > 大于操作符 <br> >= 大于或等于操作符 <br> = 等于操作符 <br> != 不等于操作符 <br> <> 不等于操作符 <br> := 赋值操作符 <br>   表6 显示的是比较操作符 <br> operator operation <br> IS NULL 如果操作数为NULL返回TRUE <br> LIKE 比较字符串值 <br> BETWEEN 验证值是否在范围之内 <br> IN 验证操作数在设定的一系列值中 <br>   表7显示的是逻辑操作符 <br> operator operation <br> AND 两个条件都必须满足 <br> OR 只要满足两个条件中的一个 <br> NOT 取反 <br> 第九章 PL/SQL--------动态SQL <br> PL/SQL动态SQL(原创) <br> 概念:动态SQL,编译阶段无法明确SQL命令,只有在运行阶段才 <br> <br> 能被识别 <br> 动态SQL和静态SQL两者的异同 <br> 静态SQL为直接嵌入到PL/SQL中的代码,而动态SQL在运行时,根 <br> <br> 据不同的情况产生不同的SQL语句。 <br> 静态SQL在执行前编译,一次编译,多次运行。动态SQL同样在执 <br> <br> 行前编译,但每次执行需要重新编译。 <br> 静态SQL可以使用相同的执行计划,对于确定的任务而言,静态 <br> <br> SQL更具有高效性,但缺乏灵活性;动态SQL使用了不同的执行计 <br> <br> 划,效率不如静态SQL,但能够解决复杂的问题。 <br> 动态SQL容易产生SQL注入,为数据库安全带来隐患。 <br> 动态SQL语句的几种方法 <br> a.使用EXECUTE IMMEDIATE语句 <br> 包括DDL语句,DCL语句,DML语句以及单行的SELECT 语句。该方 <br> <br> 法不能用于处理多行查询语句。 <br> b.使用OPEN-FOR,FETCH和CLOSE语句 <br> 对于处理动态多行的查询操作,可以使用OPEN-FOR语句打开游标 <br> <br> ,使用FETCH语句循环提取数据,最终使用CLOSE语句关闭游标。 <br> c.使用批量动态SQL <br> 即在动态SQL中使用BULK子句,或使用游标变量时在fetch中使用 <br> <br> BULK ,或在FORALL语句中使用BULK子句来实现。 <br> d.使用系统提供的PL/SQL包DBMS_SQL来实现动态SQL <br>   <br> 动态SQL的语法 <br> 下面是动态SQL常用的语法之一 <br> EXECUTE IMMEDIATE dynamic_SQL_string <br> [INTO defined_variable1, defined_variable2, ...] <br> [USING [IN | OUT | IN OUT] bind_argument1, <br> <br> bind_argument2,...] <br> [{RETURNING | RETURN} field1, field2, ... INTO <br> <br> bind_argument1, <br> bind_argument2, ...] <br> 语法描述 <br> dynamic_SQL_string:存放指定的SQL语句或PL/SQL块的字符串变 <br> <br> 量 <br> defined_variable1:用于存放单行查询结果,使用时必须使用 <br> <br> INTO关键字,类似于使用 <br> SELECT ename INTO v_name FROM scott.emp; <br> 只不过在动态SQL时,将INTO defined_variable1移出到 <br> <br> dynamic_SQL_string语句之外。 <br> bind_argument1:用于给动态SQL语句传入或传出参数,使用时必 <br> <br> 须使用USING关键字,IN表示传入的参数,OUT表示传出的参数, <br> <br> IN OUT则既可以传入,也可传出。 <br> RETURNING | RETURN 子句也是存放SQL动态返回值的变量。 <br> 使用要点 <br> a.EXECUTE IMMEDIATE执行DML时,不会提交该DML事务,需要使用 <br> <br> 显示提交(COMMIT)或作为EXECUTE IMMEDIATE自身的一部分。 <br> b.EXECUTE IMMEDIATE执行DDL,DCL时会自动提交其执行的事务。 <br> c.对于多行结果集的查询,需要使用游标变量或批量动态SQL,或 <br> <br> 者使用临时表来实现。 <br> d.当执行SQL时,其尾部不需要使用分号,当执行PL/SQL 代码时 <br> <br> ,其尾部需要使用分号。 <br> f.动态SQL中的占位符以冒号开头,紧跟任意字母或数字表示。 <br> 动态SQL的使用(DDL,DCL,DML以及单行结果集) <br> DECLARE <br>   v_table VARCHAR2(30):='emp1'; <br>   v_sql LONG:='SELECT ename FROM emp1 WHERE empno=:1';-- <br> <br> 占位符\可以用任何符号(数字或字母) <br>   --v_no emp1.empno%TYPE:='&请输入号码';--&是变量绑定符 <br> <br> 绑定的数据是字符串类型时必须要加引号 <br>   --v_no emp1.empno%TYPE:=&请输入号码; <br>   v_name emp1.ename%TYPE; <br> BEGIN <br>   --EXECUTE IMMEDIATE v_sql INTO v_name USING IN v_no; <br>   dbms_output.put_line('ename='||v_name); <br>   --EXECUTE IMMEDIATE 'create table emp2 as select * from <br> <br> emp'; <br>   --EXECUTE IMMEDIATE 'drop table '||v_table; <br>   --EXECUTE IMMEDIATE 'alter table emp enable row <br> <br> movement'; <br> END; <br> BULK子句和动态SQL的使用 <br> 动态SQL中使用BULK子句的语法 <br> EXECUTE IMMEDIATE dynamic_string --dynamic_string用于存放 <br> <br> 动态SQL字符串 <br> [BULK COLLECT INTO define_variable[,define_variable...]] <br> <br> --存放查询结果的集合变量 <br> [USING bind_argument[,argument...]] --使用参数传递给动态 <br> <br> SQL <br> [{RETURNING | RETURN} --返回子句 <br> BULK COLLECT INTO return_variable[,return_variable...]]; <br> <br> --存放返回结果的集合变量 <br> 使用bulk collect into子句处理动态SQL中T的多行查询可以加快 <br> <br> 处理速度,从而提高应用程序的性能。当使用bulk子句时,集合 <br> <br> 类型可以是PL/SQL所支持的索引表、嵌套表和VARRY,但集合元 <br> <br> 素必须使用SQL数据类型。常用的三种语句支持BULK子句,分别为 <br> <br> EXECUTE IMMEDIATE,FETCH 和FORALL。 <br> 使用EXECUTE IMMEDIATE 结合BULK子句处理多行查询。使用了 <br> <br> BULK COLLECT INTO来传递结果。 <br> SQL>declare <br>   type ename_table_type is table of emp1.ename%type index <br> <br> by binary_integer; <br>   type sal_table_type is table OF emp1.sal%type index by <br> <br> binary_integer; <br>      ename_table ename_table_type; <br>      sal_table sal_table_type; <br>      sql_stat varchar2(100); <br>      v_dno number := 7369; <br> begin <br>     sql_stat := 'select ename,sal from emp1 where deptno <br> <br> = :v_dno'; --动态DQL语句,未使用RETURNING子句 <br>     execute immediate sql_stat <br>     bulk collect into ename_table,sal_table using v_dno; <br>     for i in 1..ename_table.count loop <br>         dbms_output.put_line('Employee ' || ename_table <br> <br> (i) || ' Salary is: ' || sal_table(i)); <br>     end loop; <br> end; <br> 使用FETCH子句结合BULK子句处理多行结果集 <br> 下面的示例中首先定义了游标类型,游标变量以及复合类型,复 <br> <br> 合变量,接下来从动态SQL中OPEN游标,然后使用FETCH将结果存 <br> <br> 放到复合变量中。即使用OPEN,FETCH代替了EXECUTE IMMEDIATE <br> <br> 来完成动态SQL的执行。 <br> SQL> declare <br>   2 type empcurtype is ref cursor; <br>   3 emp_cv empcurtype; <br>   4 type ename_table_type is table of tb2.ename%type <br> <br> index by binary_integer; <br>   5 ename_table ename_table_type; <br>   6 sql_stat varchar2(120); <br>   7 begin <br>   8 sql_stat := 'select ename from tb2 where deptno = <br> <br> :dno'; <br>   9 open emp_cv for sql_stat using &dno; <br>  10 fetch emp_cv bulk collect into ename_table; <br>  11 for i in 1..ename_table.count loop <br>  12 dbms_output.put_line('Employee Name: ' || <br> <br> ename_table(i)); <br>  13 end loop; <br>  14 close emp_cv; <br>  15* end; <br> 在FORALL语句中使用BULK子句 <br> 下面是FORALL子句的语法 <br> FORALL index IN lower bound..upper bound --FORALL循环计数 <br> EXECUTE IMMEDIATE dynamic_string --结合EXECUTE IMMEDIATE <br> <br> 来执行动态SQL语句 <br> USING bind_argument | bind_argument(index) --绑定输入参数 <br> [bind_argument | bind_argument(index)]... <br> [{RETURNING | RETURN} BULK COLLECT INTO bind_argument <br> <br> [,bind_argument...]]; --绑定返回结果集 <br> FORALL子句允许为动态SQL输入变量,但FORALL子句仅支持的DML <br> <br> (INSERT,DELETE,UPDATE)语句,不支持动态的SELECT语句。 <br> 下面的示例中,首先声明了两个复合类型以及复合变量,接下来 <br> <br> 为复合变量ename_table赋值,以形成动态SQL语句。紧接着使用 <br> <br> FORALL子句结合EXECUTE IMMEDIATE 来提取结果集。 <br> SQL> declare <br>   2 type ename_table_type is table of tb2.ename%type; <br>   3 type sal_table_type is table of tb2.sal%type; <br>   4 ename_table ename_table_type; <br>   5 sal_table sal_table_type; <br>   6 sql_stat varchar2(100); <br>   7 begin <br>   8 ename_table := ename_table_type <br> <br> ('BLAKE','FORD','MILLER'); <br>   9 sql_stat := 'update tb2 set sal = sal * 1.1 where <br> <br> ename = :1' <br>  10 || ' returning sal into :2'; <br>  11 forall i in 1..ename_table.count <br>  12 execute immediate sql_stat using ename_table(i) <br> <br> returning bulk collect into sal_table; <br>  13 for j in 1..sal_table.count loop <br>  14 dbms_output.put_line('The ' || ename_table(j) || '''' <br> <br> || 's new salalry is ' || sal_table(j)); <br>  15 end loop; <br>  16* end; <br> 常见错误 <br> 1、使用动态DDL时,不能使用绑定变量。 <br> EXECUTE IMMEDIATE 'CREATE TABLE dsa '||'as select * from <br> <br> :1' USING IN v_table; <br> 解决办法,将绑定变量直接拼接,如下: <br> EXECUTE IMMEDIATE 'CREATE TABLE dsa '||'as select * from <br> <br> '|| v_table; <br> 2、不能使用schema对象作为绑定参数,下面的示例中,动态SQL <br> <br> 语句查询需要传递表名,因此收到了错误提示。 <br> EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM:tb_name ' into <br> <br> v_count; <br> 解决办法,将绑定变量直接拼接,如下: <br> EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || tb_name into <br> <br> v_count; <br> 3、动态SQL块不能使用分号结束(;) <br>   execute immediate 'select count(*) from emp;' --此处多 <br> <br> 出了分号,应该去掉 <br>   <br> 4、动态PL/SQL块不能使用正斜杠来结束块,但是块结尾处必须要 <br> <br> 使用分号(;) <br> SQL> declare <br>   2 plsql_block varchar2(300); <br>   3 begin <br>   4 plsql_block := 'Declare ' || <br>   5 ' v_date date; ' || <br>   6 ' begin ' || <br>   7 ' select sysdate into v_date from dual; ' || <br>   8 ' dbms_output.put_line(to_char(v_date,''yyyy-mm- <br> <br> dd'')); ' || <br>   9 ' end; <br>  10 /'; --此处多出了/,应该将其去掉 <br>  11 execute immediate plsql_block; <br>  12* end; <br> 4、空值传递的问题 <br> 下面的示例中对表tb_emp更新,并将空值更新到sal列,直接使用 <br> <br> USING NULL收到错误提示。 <br>   execute immediate sql_stat using null,v_empno; <br> 正确的处理方法 <br>     v_sal tb2.sal%type; --声明一个新变量,但不赋值 <br>     execute immediate sql_stat using v_sal,v_empno; <br> 5、日期和字符型必须要使用引号来处理 <br> DECLARE <br>   sql_stat VARCHAR2(100); <br>   v_date DATE :=TO_DATE('2013-11-21','yyyy-mm-dd'); <br>   v_empno NUMBER :=7900; <br>   v_ename emp.ename%TYPE; <br>   v_sal emp.sal%TYPE; <br> BEGIN <br>   sql_stat := 'SELECT ename,sal FROM emp WHERE <br> <br> hiredate=:v_date'; <br>   EXECUTE IMMEDIATE sql_stat <br>   INTO v_ename,v_sal <br>   USING v_date; <br>   DBMS_OUTPUT.PUT_LINE('Employee Name '||v_ename||', sal <br> <br> is '||v_sal); <br> END; <br> 6、单行SELECT 查询不能使用RETURNING INTO返回 <br> 下面的示例中,使用了动态的单行SELECT查询,并且使用了 <br> <br> RETURNING子句来返回值。事实上,RETURNING coloumn_name <br> <br> INTO 子句仅仅支持对DML结果集的返回,因此,收到了错误提示 <br> <br> 。 <br> SQL>declare <br> v_empno emp.empno%type := &empno; <br>  v_ename emp.ename%type; <br> begin <br>  execute immediate 'select ename from emp where empno = <br> <br> :eno' into v_ename using v_empno; <br>  dbms_output.put_line('Employee name: ' || v_ename); <br> end; <br> 第十章 PL/SQL---------游标 <br> 游标的使用 <br>     在 PL/SQL 程序中,对于处理多行记录的事务经常使用游标 <br> <br> 来实现。 <br> 4.1 游标概念 <br> 对于不同的SQL语句,游标的使用情况不同: <br> SQL语句 <br> 游标 <br> 非查询语句 <br> 隐式的 <br> 结果是单行的查询语句 <br> 隐式的或显示的 <br> 结果是多行的查询语句 <br> 显示的 <br> 游标名%属性名 <br> 显式游标的名字右用户定义,隐式游标名为SQL <br> 隐式游标只是一个状态 <br> 4.1.1 处理显式游标 <br>   <br> 1. 显式游标处理 <br> 语法格式: <br> CURSOR cursor_name is select * from emp; <br> OPEN cursor_name; <br> FETCH cursor_name INTO variables_list; <br> CLOSE cursor_name; <br> 例1: <br> DECLARE <br>   v_deptno NUMBER:=&inputno; <br>   v_row emp1%ROWTYPE; <br>   CURSOR v_cursor IS SELECT * FROM emp1 WHERE <br> <br> deptno=v_deptno; <br> BEGIN <br>   --打开 <br>   OPEN v_cursor; <br>   --提取 <br>   LOOP <br>     FETCH v_cursor INTO v_row;--先提取 <br>     EXIT WHEN v_cursor%NOTFOUND; <br>     dbms_output.put_line('Employee Name: ' || v_row.ename <br> <br> || ' ,Salary: ' || v_row.sal); <br>   END LOOP; <br>   --关闭 <br>   CLOSE v_cursor; <br> END; <br> 显式游标处理需四个 PL/SQL步骤: <br> l 定义/声明游标:就是定义一个游标名,以及与其相对应的 <br> <br> SELECT 语句。 <br> 格式: <br>   <br>     CURSOR cursor_name[(parameter[, parameter]…)] <br>             <br>            [RETURN datatype] <br>     IS <br>         select_statement; <br>         select_statement; <br>   <br> 游标参数只能为输入参数,其格式为: <br>   <br> parameter_name [IN] datatype [{:= | DEFAULT} expression] <br> 在指定数据类型时,不能使用长度约束。如NUMBER(4),CHAR(10) <br> <br> 等都是错误的。 <br> [RETURN datatype]是可选的,表示游标返回数据的数据。如果选 <br> <br> 择,则应该严格与select_statement中的选择列表在次序和数据 <br> <br> 类型上匹配。一般是记录数据类型或带“%ROWTYPE”的数据。 <br>   <br> l 打开游标:就是执行游标所对应的SELECT 语句,将其查询结果 <br> <br> 放入工作区,并且指针指向工作区的首部,标识游标结果集合。 <br> <br> 如果游标查询语句中带有FOR UPDATE选项,OPEN 语句还将锁定数 <br> <br> 据库表中游标结果集合对应的数据行。 <br> 格式: <br>   <br> OPEN cursor_name[([parameter =>] value[, [parameter =>] <br> <br> value]…)]; <br>   <br> 在向游标传递参数时,可以使用与函数参数相同的传值方法,即 <br> <br> 位置表示法和名称表示法。PL/SQL 程序不能用OPEN 语句重复打 <br> <br> 开一个游标。 <br>   <br> l 提取游标数据:就是检索结果集合中的数据行,放入指定的输 <br> <br> 出变量中。 <br> 格式: <br>   <br> FETCH cursor_name INTO {variable_list | record_variable <br> <br> }; <br>   <br> 执行FETCH语句时,每次返回一个数据行,然后自动将游标移动指 <br> <br> 向下一个数据行。当检索到最后一行数据时,如果再次执行FETCH <br> <br> 语句,将操作失败,并将游标属性%NOTFOUND置为TRUE。所以每次 <br> <br> 执行完FETCH语句后,检查游标属性%NOTFOUND就可以判断FETCH语 <br> <br> 句是否执行成功并返回一个数据行,以便确定是否给对应的变量 <br> <br> 赋了值。 <br> l 对该记录进行处理; <br> l 继续处理,直到活动集合中没有记录; <br> l 关闭游标:当提取和处理完游标结果集合数据后,应及时关闭 <br> <br> 游标,以释放该游标所占用的系统资源,并使该游标的工作区变 <br> <br> 成无效,不能再使用FETCH 语句取其中数据。关闭后的游标可以 <br> <br> 使用OPEN 语句重新打开。 <br> 格式: <br>   <br> CLOSE cursor_name; <br>   <br>      注:定义的游标不能有INTO 子句。 <br>   <br> 例1. 查询前10名员工的信息。 <br> DECLARE <br>    CURSOR c_cursor <br>    IS SELECT first_name || last_name, Salary FROM <br> <br> EMPLOYEES WHERE rownum<11; <br>    v_ename EMPLOYEES.first_name%TYPE; <br>    v_sal EMPLOYEES.Salary%TYPE; <br> BEGIN <br>   OPEN c_cursor; <br>   FETCH c_cursor INTO v_ename, v_sal; <br>   WHILE c_cursor%FOUND LOOP <br>      DBMS_OUTPUT.PUT_LINE(v_ename||'---'||to_char(v_sal) <br> <br> ); <br>      FETCH c_cursor INTO v_ename, v_sal; <br>   END LOOP; <br>   CLOSE c_cursor; <br> END; <br>   <br> 2.游标属性 <br>  Cursor_name%FOUND 布尔型属性,当最近一次提取游标操作 <br> <br> FETCH成功则为 TRUE,否则为FALSE; <br>  Cursor_name%NOTFOUND 布尔型属性,与%FOUND相反; <br>  Cursor_name%ISOPEN 布尔型属性,当游标已打开时返回 TRUE; <br>  Cursor_name%ROWCOUNT 数字型属性,返回已从游标中读取的记 <br> <br> 录数。 <br>   <br> 例2:没有参数且没有返回值的游标。 <br> DECLARE <br>    v_f_name employees.first_name%TYPE; <br>    v_j_id employees.job_id%TYPE; <br>     <br>    CURSOR c1 --声明游标,没有参数没有返回值 <br>    IS <br>       SELECT first_name, job_id FROM employees WHERE <br> <br> department_id = 20; <br> BEGIN <br>    OPEN c1; --打开游标 <br>    LOOP <br>       FETCH c1 INTO v_f_name, v_j_id; --提取游标 <br>       IF c1%FOUND THEN <br>          DBMS_OUTPUT.PUT_LINE(v_f_name||'的岗位是'|| <br> <br> v_j_id); <br>       ELSE <br>          DBMS_OUTPUT.PUT_LINE('已经处理完结果集了'); <br>          EXIT; <br>       END IF; <br>    END LOOP; <br>    CLOSE c1; --关闭游标 <br> END; <br>   <br> 例3:有参数且没有返回值的游标。 <br> DECLARE <br>    v_f_name employees.first_name%TYPE; <br>    v_h_date employees.hire_date%TYPE; <br>     <br>    CURSOR c2(dept_id NUMBER, j_id VARCHAR2) --声明游标,有 <br> <br> 参数没有返回值 <br>    IS <br>       SELECT first_name, hire_date FROM employees WHERE <br> <br> department_id = dept_id AND job_id = j_id; <br> BEGIN <br>    OPEN c2(90, 'AD_VP'); --打开游标,传递参数值 <br>    LOOP <br>       FETCH c2 INTO v_f_name, v_h_date; --提取游标 <br>       IF c2%FOUND THEN <br>          DBMS_OUTPUT.PUT_LINE(v_f_name||'的雇佣日期是'|| <br> <br> v_h_date); <br>       ELSE <br>          DBMS_OUTPUT.PUT_LINE('已经处理完结果集了'); <br>          EXIT; <br>       END IF; <br>    END LOOP; <br>    CLOSE c2; --关闭游标 <br> END; <br> 例4:有参数且有返回值的游标。 <br> DECLARE <br>    TYPE emp_record_type IS RECORD( <br>         f_name employees.first_name%TYPE, <br>         h_date employees.hire_date%TYPE); <br>    v_emp_record EMP_RECORD_TYPE; <br>    v_emp_record EMP_RECORD_TYPE; <br>    CURSOR c3(dept_id NUMBER, j_id VARCHAR2) --声明游标,有 <br> <br> 参数有返回值 <br>           RETURN EMP_RECORD_TYPE <br>    IS <br>       SELECT first_name, hire_date FROM employees WHERE <br> <br> department_id = dept_id AND job_id = j_id; <br> BEGIN <br>    OPEN c3(j_id => 'AD_VP', dept_id => 90); --打开游标,传 <br> <br> 递参数值 <br>    LOOP <br>       FETCH c3 INTO v_emp_record; --提取游标 <br>       IF c3%FOUND THEN <br>          DBMS_OUTPUT.PUT_LINE(v_emp_record.f_name||'的雇 <br> <br> 佣日期是'||v_emp_record.h_date); <br>       ELSE <br>          DBMS_OUTPUT.PUT_LINE('已经处理完结果集了'); <br>          EXIT; <br>       END IF; <br>    END LOOP; <br>    CLOSE c3; --关闭游标 <br> END; <br>  例5:基于游标定义记录变量。 <br> DECLARE <br>    CURSOR c4(dept_id NUMBER, j_id VARCHAR2) --声明游标,有 <br> <br> 参数没有返回值 <br>    IS <br>       SELECT first_name f_name, hire_date FROM employees <br> <br> WHERE department_id = dept_id AND job_id = j_id; <br>     --基于游标定义记录变量,比声明记录类型变量要方便,不 <br> <br> 容易出错 <br>     v_emp_record c4%ROWTYPE; <br> BEGIN <br>    OPEN c4(90, 'AD_VP'); --打开游标,传递参数值 <br>    LOOP <br>       FETCH c4 INTO v_emp_record; --提取游标 <br>       IF c4%FOUND THEN <br>          DBMS_OUTPUT.PUT_LINE(v_emp_record.f_name||'的雇 <br> <br> 佣日期是'||v_emp_record.hire_date); <br>       ELSE <br>          DBMS_OUTPUT.PUT_LINE('已经处理完结果集了'); <br>          EXIT; <br>       END IF; <br>    END LOOP; <br>    CLOSE c4; --关闭游标 <br> END; <br> 3. 游标的FOR循环 <br>     PL/SQL语言提供了游标FOR循环语句,自动执行游标的OPEN、 <br> <br> FETCH、CLOSE语句和循环语句的功能;当进入循环时,游标FOR循 <br> <br> 环语句自动打开游标,并提取第一行游标数据,当程序处理完当 <br> <br> 前所提取的数据而进入下一次循环时,游标FOR循环语句自动提取 <br> <br> 下一行数据供程序处理,当提取完结果集合中的所有数据行后结 <br> <br> 束循环,并自动关闭游标。 <br> 格式: <br>    FOR index_variable IN cursor_name[(value[, value]…)] <br> <br> LOOP <br>     -- 游标数据处理代码 <br>    END LOOP; <br> 其中: <br> index_variable为游标FOR 循环语句隐含声明的索引变量,该变 <br> <br> 量为记录变量,其结构与游标查询语句返回的结构集合的结构相 <br> <br> 同。在程序中可以通过引用该索引记录变量元素来读取所提取的 <br> <br> 游标数据,index_variable中各元素的名称与游标查询语句选择 <br> <br> 列表中所制定的列名相同。如果在游标查询语句的选择列表中存 <br> <br> 在计算列,则必须为这些计算列指定别名后才能通过游标FOR 循 <br> <br> 环语句中的索引变量来访问这些列数据。 <br> 注:不要在程序中对游标进行人工操作;不要在程序中定义用于 <br> <br> 控制FOR循环的记录。 <br>   <br> 例6:当所声明的游标带有参数时,通过游标FOR 循环语句为游标 <br> <br> 传递参数。 <br> DECLARE <br>   CURSOR c_cursor(dept_no NUMBER DEFAULT 10) <br>   IS <br>   SELECT department_name, location_id FROM departments <br> <br> WHERE department_id <= dept_no; <br> BEGIN <br>     DBMS_OUTPUT.PUT_LINE('当dept_no参数值为30:'); <br>     FOR c1_rec IN c_cursor(30) LOOP <br>    DBMS_OUTPUT.PUT_LINE(c1_rec.department_name||'---'|| <br> <br> c1_rec.location_id); <br>     END LOOP; <br>     DBMS_OUTPUT.PUT_LINE(CHR(10)||'使用默认的dept_no参数 <br> <br> 值10:'); <br>     FOR c1_rec IN c_cursor LOOP <br>    DBMS_OUTPUT.PUT_LINE(c1_rec.department_name||'---'|| <br> <br> c1_rec.location_id); <br>     END LOOP; <br> END; <br>   <br> 例7:PL/SQL还允许在游标FOR循环语句中使用子查询来实现游标 <br> <br> 的功能。 <br> BEGIN <br> --隐含打开游标 <br>    FOR r IN (SELECT * FROM emp1 WHERE deptno=v_deptno) <br> <br> LOOP <br> --隐含执行一个FETCH语句 <br>       dbms_output.put_line('Employee Name: ' || r.ename <br> <br> || ' ,Salary: ' || r.sal); <br> --隐含监测c_sal%NOTFOUND <br>    END LOOP; <br> --隐含关闭游标 <br> END; <br>   <br> 4.1.2 处理隐式游标 <br> 对于非查询语句,如修改、删除操作,则由ORACLE 系统自动地为 <br> <br> 这些操作设置游标并创建其工作区,这些由系统隐含创建的游标 <br> <br> 称为隐式游标,隐式游标的名字为SQL,这是由ORACLE 系统定义 <br> <br> 的。对于隐式游标的操作,如定义、打开、取值及关闭操作,都 <br> <br> 由ORACLE 系统自动地完成,无需用户进行处理。用户只能通过隐 <br> <br> 式游标的相关属性,来完成相应的操作。在隐式游标的工作区中 <br> <br> ,所存放的数据是与用户自定义的显示游标无关的、最新处理的 <br> <br> 一条SQL 语句所包含的数据。 <br> 格式调用为: SQL% <br>   <br> 注:INSERT, UPDATE, DELETE, SELECT(单查询) 语句中不必明 <br> <br> 确定义游标。 <br>   <br> 隐式游标属性 <br> 属性 <br> 值 <br> SELECT <br> INSERT <br> UPDATE <br> DELETE <br> SQL%ISOPEN <br>   <br> FALSE <br> FALSE <br> FALSE <br> FALSE <br> SQL%FOUND <br> TRUE <br> 有结果 <br>   <br> 成功 <br> 成功 <br> SQL%FOUND <br> FALSE <br> 没结果 <br>   <br> 失败 <br> 失败 <br> SQL%NOTFUOND <br> TRUE <br> 没结果 <br>   <br> 失败 <br> 失败 <br> SQL%NOTFOUND <br> FALSE <br> 有结果 <br>   <br> 成功 <br> 失败 <br> SQL%ROWCOUNT <br>   <br> 返回行数,只为1 <br> 插入的行数 <br> 修改的行数 <br> 删除的行数 <br>   <br> 例8: 通过隐式游标SQL的%ROWCOUNT属性来了解修改了多少行。 <br> DECLARE <br>    v_rows NUMBER; <br> BEGIN <br> --更新数据 <br>    UPDATE employees SET salary = 30000 <br>    WHERE department_id = 90 AND job_id = 'AD_VP'; <br> --获取默认游标的属性值 <br>    v_rows := SQL%ROWCOUNT; <br>    DBMS_OUTPUT.PUT_LINE( <br>    DBMS_OUTPUT.PUT_LINE('更新了'||v_rows||'个雇员的工 <br> <br> 资'); <br> --回退更新,以便使数据库的数据保持原样 <br>    ROLLBACK; <br> END; <br>   <br> 4.1.3 使用游标更新和删除数据 <br> 游标修改和删除操作是指在游标定位下,修改或删除表中指定的 <br> <br> 数据行。这时,要求游标查询语句中必须使用FOR UPDATE选项, <br> <br> 以便在打开游标时锁定游标结果集合在表中对应数据行的所有列 <br> <br> 和部分列。 <br> 为了对正在处理(查询)的行不被另外的用户改动,ORACLE 提供一 <br> <br> 个 FOR UPDATE 子句来对所选择的行进行锁住。该需求迫使 <br> <br> ORACLE锁定游标结果集合的行,可以防止其他事务处理更新或删 <br> <br> 除相同的行,直到您的事务处理提交或回退为止。 <br> 语法: <br>   <br> SELECT column_list FROM table_list FOR UPDATE [OF column <br> <br> [, column]…] [NOWAIT] <br>   <br> 如果使用 FOR UPDATE 声明游标,则可在DELETE和UPDATE 语句中 <br> <br> 使用 <br> WHERE CURRENT OF cursor_name子句,修改或删除游标结果集合 <br> <br> 当前行对应的数据库表中的数据行。 <br>   <br> 例9:从EMPLOYEES表中查询某部门的员工情况,将其工资最低定 <br> <br> 为 1500; <br> DECLARE <br>     V_deptno employees.department_id <br>     V_deptno employees.department_id%TYPE :=&p_deptno; <br>     <br>   CURSOR emp_cursor <br>   IS <br>   SELECT employees.employee_id, employees.salary FROM <br> <br> employees WHERE employees.department_id=v_deptno FOR <br> <br> UPDATE NOWAIT; <br> BEGIN <br>     FOR emp_record IN emp_cursor LOOP <br>     IF emp_record.salary < 1500 THEN <br>         UPDATE employees SET salary=1500 WHERE CURRENT OF <br> <br> emp_cursor; <br>     END IF; <br>     END LOOP; <br>     COMMIT; <br> END; <br> 4.2 游标变量 <br> 与游标一样,游标变量也是一个指向多行查询结果集合中当前数 <br> <br> 据行的指针。但与游标不同的是,游标变量是动态的,而游标是 <br> <br> 静态的。游标只能与指定的查询相连,即固定指向一个查询的内 <br> <br> 存处理区域,而游标变量则可与不同的查询语句相连,它可以指 <br> <br> 向不同查询语句的内存处理区域(但不能同时指向多个内存处理 <br> <br> 区域,在某一时刻只能与一个查询语句相连),只要这些查询语 <br> <br> 句的返回类型兼容即可。 <br> 4.2.1 声明游标变量 <br> 游标变量为一个指针,它属于参照类型,所以在声明游标变量类 <br> <br> 型之前必须先定义游标变量类型。在PL/SQL中,可以在块、子程 <br> <br> 序和包的声明区域内定义游标变量类型。 <br> 语法格式为: <br> 1.定义游标变量 <br> TYPE cursortype IS REF CURSOR; <br> cursor_variable cursortype; <br> 2.打开游标变量 <br> OPEN cursor_variable FOR dynamic_string <br> [USING bind_argument[,bind_argument]...] <br> 3.循环提取数据 <br> FETCH cursor_variable INTO {var1[,var2]...| <br> <br> record_variable}; <br> EXIT WHEN cursor_variable%NOTFOUND <br> 4.关闭游标变量 <br> CLOSE cursor_variable; <br>   <br> 例10:使用游标变量(没有RETURN子句) <br> DECLARE <br> --定义一个游标数据类型 <br>    TYPE emp_cursor_type IS REF CURSOR; <br> --声明一个游标变量 <br>    c1 EMP_CURSOR_TYPE; <br> --声明两个记录变量 <br>    v_emp_record employees%ROWTYPE; <br>    v_reg_record regions%ROWTYPE; <br> BEGIN <br>    OPEN c1 FOR SELECT * FROM employees WHERE <br> <br> department_id = 20; <br>    LOOP <br>       FETCH c1 INTO v_emp_record; <br>       EXIT WHEN c1%NOTFOUND; <br>       DBMS_OUTPUT.PUT_LINE(v_emp_record.first_name||'的雇 <br> <br> 佣日期是'||v_emp_record.hire_date); <br>    END LOOP; <br> --将同一个游标变量对应到另一个SELECT语句 <br>    OPEN c1 FOR SELECT * FROM regions WHERE region_id IN( <br> <br> 1,2); <br>    LOOP <br>       FETCH c1 INTO v_reg_record; <br>       <br>       EXIT WHEN c1%NOTFOUND; <br>       DBMS_OUTPUT.PUT_LINE(v_reg_record.region_id||'表 <br> <br> 示'||v_reg_record.region_name); <br>    END LOOP; <br>    CLOSE c1; <br> END; <br>   <br> 例11:使用游标变量(有RETURN子句) <br> DECLARE <br> --定义一个与employees表中的这几个列相同的记录数据类型 <br>    TYPE emp_record_type IS RECORD( <br>         f_name employees.first_name <br>         f_name employees.first_name%TYPE, <br>         h_date employees.hire_date <br>         h_date employees.hire_date%TYPE, <br>         j_id employees.job_id <br>         j_id employees.job_id%TYPE); <br> --声明一个该记录数据类型的记录变量 <br>    v_emp_record EMP_RECORD_TYPE; <br> --定义一个游标数据类型 <br>    TYPE emp_cursor_type IS REF CURSOR <br>         RETURN EMP_RECORD_TYPE; <br> --声明一个游标变量 <br>    c1 EMP_CURSOR_TYPE; <br> BEGIN <br>    OPEN c1 FOR SELECT first_name, hire_date, job_id FROM <br> <br> employees WHERE department_id = 20; <br>    LOOP <br>       FETCH c1 INTO v_emp_record; <br>       EXIT WHEN c1%NOTFOUND; <br>       DBMS_OUTPUT.PUT_LINE('雇员名称:'|| <br> <br> v_emp_record.f_name||' 雇佣日期:'|| <br> <br> v_emp_record.h_date||' 岗位:'||v_emp_record.j_id); <br>    END LOOP; <br>    CLOSE c1; <br> END; <br>   <br> 第十一章 视图 <br> 视图:是一个封装了各种复杂查询的语句,就称为视图。不存储 <br> <br> 数据,只存储定义,定义被保存在数据字典中 <br> 作用:1、可以保证安全,隐藏一些数据,保证数据不会被误删; <br>            2、多表连接,可以使复杂的查询易于理解和使用 <br> 15.1、创建视图 <br> 需要权限才能创建 <br> grant create view to scott; <br>  CREATE OR REPLACE VIEW 视图名字(字段) AS 子查 <br>  CREATE OR REPLACE VIEW v_表名_业务 AS 查询语句 <br> 建立一个只包含 20 部门雇员信息的视图(雇员的编号、姓名、 <br> <br> 工资) <br>  CREATE VIEW empv20 (empno,ename,sal) AS SELECT <br> <br> empno,ename,sal FROM emp WHERE deptno=20 ; <br>  现在直接更新视图里的数据 将 7369 的部门编号修改为 30。此 <br> <br> 操作在视图中完成。 <br>    update empv20 SET deptno=30 where empno=7369 ; 此时, <br> <br> 提示更新完成。 <br>  默认情况下创建的视图,如果更新了,则会自动将此数据从视图 <br> <br> 中删除,之后会更新原本的数据。 <br>   <br> 在建立视图的时候有两个参数: <br>  · WITH CHECK OPTION à 保护视图的创建规则 <br> CREATE OR REPLACE VIEW empv20 <br> AS SELECT empno,ename,sal,deptno FROM emp WHERE deptno=20 <br> WITH CHECK OPTION CONSTRAINT empv20_ck;----约束条件 <br> ALTER TABLE emp1 add CONSTRAINT empv20_ck check(约束条 <br> <br> 件); <br>  再执行更新操作: <br>   update empv20 SET deptno=30 where empno=7369 ; à 此处更 <br> <br> 新的是部门编号,失败 <br>    |- 之前是按照部门编号建立的视图,所以不能修改部门编号 <br>   update empv20 SET ename='tom' where empno=7369 ; à 可以 <br> <br> 更新,更新的是名字,成功 <br>  · WITH READ ONLY(只读,不可修改),视图最好不要轻易的 <br> <br> 修改 <br> CREATE OR REPLACE VIEW empv20 <br> AS SELECT empno,ename,sal,deptno FROM emp WHERE deptno=20 <br> WITH READ ONLY; <br>  现在任意的字段都不可更改,所以现在的视图是只读的。 <br> 如果视图的基表有多行查询(比如:group by,distinct)那么该 <br> <br> 视图也是只读的 <br>   <br> 15.1、查看视图 <br> SELECT * FROM v_emp; <br> update v_emp SET deptno=20 where empno=7369; <br> DELETE FROM v_emp WHERE empno=7369; <br> ROLLBACK; <br> DROP VIEW v_emp; <br> 在视图终不能被修改删除,1、多表构成的视图;2、group by <br> 资料: <br> http://database.51cto.com/art/200904/118306.htm <br> http://blog.csdn.net/fan_xiao_ming/article/details/617406 <br> <br> 5 <br> 第十六章 索引 <br> 工作原理:rowid <br> 用执行计划检测索引是否起作用(set autot on exp) <br> 执行计划 cbo(选择)和cro(规则) <br>     <br> 16.1、索引 <br> 索引是一种用于提升查询效率的数据库对象,通过快速定位数据 <br> <br> 的方法,索引信息与表独立存放,Oracle数据库自动使用和维护 <br> <br> 索引 <br> 索引的存储 <br>        索引和表都是独立存在的。在为索引指定表空间的时候, <br> <br> 不要将被索引的表和索引指向同一个表空间,这样可以避免产生 <br> <br> IO 冲突。使 Oracle 能够并行访问存放在不同硬盘中的索引数据 <br> <br> 和表数据,更好的提高查询速度。 <br> 16.2、索引优缺点 <br> 建立索引的优点 <br>   1.加快数据的检索速度; <br>   2.创建唯一性索引,保证数据库表中每一行数据的唯一性; <br>   3.加速表和表之间的连接; <br>   4.在使用分组和排序子句进行数据检索时,可以显著减少查询 <br> <br> 中分组和排序的时间。 <br> 索引的缺点 <br>   1.索引需要占物理空间。 <br>   2.当对表中的数据进行增加、删除和修改的时候,索引也要动 <br> <br> 态的维护,降低了数据的维护速度。 <br> 16.3、创建索引 <br> 创建索引的方式 <br> 1、自动创建:在定义主键或唯一键约束时系统会自动在相应的字 <br> <br> 段上创建唯一性索引 <br> 2、手动创建:用户可以在其他列上创建非唯一索引,以加速查询 <br> <br> 。 <br> 创建索引:创建索引一般有以下两个目的:维护被索引列的唯一 <br> <br> 性和提供快速访问表中数据的策略。 <br> --在 select 操作占大部分的表上创建索引; <br> --在 where 子句中出现最频繁的列上创建索引; <br> --在选择性高的列上创建索引(补充索引选择性,最高是 1,eg <br> <br> :primary key) <br> --复合索引的主列应该是最有选择性的和 where 限定条件最常用 <br> <br> 的列,并以此类推第二列……。 <br> --小于 5M 的表,最好不要使用索引来查询,表越小,越适合用 <br> <br> 全表扫描。 <br> Create [UNIQUE|BITMAP] index <br> [schema.]index_name on [schema.]table_name(column_name <br> <br> [ASC|DESC],…n,[column_expression])|CLUSTER [schema.] <br> <br> cluster_name <br> [INITRANS integer] <br> [MAXTRANS integer] <br> [PCTFREE integer] <br> [PCTUESD integer] <br> [TABLESPACE tablespace_name] <br> [STORAGE storage_clause] <br> [NOSORT] <br> [REVERSE] <br> UNIQUE 指定索引所基于的列(或多列)值必须唯一。默认的索引 <br> <br> 是非唯一的。 <br> BITMAP 指定建立位映射索引而不是B*索引。位映射索引保存的行 <br> <br> 标识符与作为位映射的键值有关。位映射中的每一位都对应于一 <br> <br> 个可能的行标识符,位设置意味着具有对应行标识符的行包含该 <br> <br> 键值。 <br> ON table_name 建立基于函数的索引。用table_name的列、常数 <br> <br> 、SQL函数和自定义函数创建的表达式。指定column_expression <br> <br> ,以后用基于函数的索引查询时,必须保证查询该 <br> <br> column_expression不为空。 <br> CLUSTER 创建cluster_name簇索引。若表不用schema限制, <br> <br> oracle假设簇包含在你自己的方案中。不能为散列簇创建簇索引 <br> <br> 。 <br> NOSORT 数据库中的行以升序保存,在创建索引时不必对行排序。 <br> <br> 若索引列或多列的行不以升序保存,oracle会返回错误。 <br> REVERSE 指定以反序索引块的字节,不包含行标识符。NOSORT不 <br> <br> 能与REVERSE一起指定。 <br> CREATE INDEX idx_表名_列名 on 表名(列1,列2...) <br> create index abc on student(sid,sname); <br> create index abc1 on student(sname,sid); <br> 这两种索引方式是不一样的 <br> 索引 abc 对 Select * from student where sid=1; 这样的查询 <br> <br> 语句更有效索引 abc1 对 Select * from student where <br> <br> sname=?louis?; 这样的查询语句更有效 <br> 因此建立索引的时候,字段的组合顺序是非常重要的。一般情况 <br> <br> 下,需要经常访问的字段放在组合字段的前面 <br> 16.4、使用索引的原则 <br> --查询结果是所有数据行的 5%以下时,使用 index 查询效果最 <br> <br> 好; <br> --where 条件中经常用到表的多列时,使用复合索引效果会好于 <br> <br> 几个单列索引。因为当 sql 语句所查询的列,全部都出现在复合 <br> <br> 索引中时,此时由于 Oracle 只需要查询索引块即可获得所有数 <br> <br> 据,当然比使用多个单列索引要快得多; <br> --索引利于 select,但对经常 insert,delte 尤其 update 的 <br> <br> 表,会降低效率。 <br> eg:试比较下面两条 SQL 语句(emp 表的 deptno 列上建有 <br> <br> ununique index): <br> 语句 A:SELECT dname, deptno FROM dept WHERE deptno NOT <br> <br> IN (SELECT deptno FROM emp); <br> 语句 B:SELECT dname, deptno FROM dept WHERE NOT EXISTS <br> <br> (SELECT deptno FROM emp WHERE dept.deptno = emp.deptno); <br> 这两条查询语句实现的结果是相同的,但是执行语句 A 的时候, <br> <br> ORACLE 会对整个 emp 表进行扫描,没有使用建立在 emp 表上的 <br> <br> deptno 索引,执行语句 B 的时候,由于在子查询中使用了联合 <br> <br> 查询,ORACLE 只是对 emp 表进行的部分数据扫描,并利用了 <br> <br> deptno 列的索引,所以语句 B 的效率要比语句 A 的效率高。 <br>   <br> ----where 子句中的这个字段,必须是复合索引的第一个字段; <br> eg:一个索引是按 f1, f2, f3 的次序建立的,若 where 子句是 <br> <br> f2 = : var2, 则因为 f2 不是索引的第 1 个字段,无法使用该 <br> <br> 索引。 <br> ---- where 子句中的这个字段,不应该参与任何形式的计算:任 <br> <br> 何对列的操作都将导致表扫描,它包括数据库函数、计算表达式 <br> <br> 等等,查询时要尽可能将操作移至等号右边。 ----应尽量熟悉各 <br> <br> 种操作符对 Oracle 是否使用索引的影响:以下这些操作会显式 <br> (explicitly)地阻止 Oracle 使用索引: is null ; is not <br> <br> null ; not in; !=; like ; numeric_col+0;date_col+0; <br> <br> char_col||' '; to_char; to_number,to_date 等。 <br> Eg: <br> Select jobid from mytabs where isReq='0' and to_date <br> <br> (updatedate) >= to_Date ( '2001-7-18', <br> 'YYYY-MM-DD');--updatedate 列的索引也不会生效。 <br> 在正确使用索引的前提下,索引可以提高检索相应的表的速度。 <br> <br> 当用户考虑在表中使用索引时,应遵循下列一些基本原则。 <br> (1)在表中插入数据后创建索引。在表中插入数据后,创建索引 <br> <br> 效率将更高。如果在装载数据之前创建索引,那么插入每行时 <br> <br> oracle都必须更改索引。 <br> (2)索引正确的表和列。如果经常检索包含大量数据的表中小于 <br> <br> 15%的行,就需要创建索引。为了改善多个表的相互关系,常常使 <br> <br> 用索引列进行关系连接。 <br> (3)主键和唯一关键字所在的列自动具有索引,但应该在与之关 <br> <br> 联的表中的外部关键字所在的列上创建索引。 <br> (4)合理安排索引列。在create index 语句中,列的排序会影 <br> <br> 响查询的性能,通常将最常用的列放在前面。创建一个索引来提 <br> <br> 高多列的查询效率时,应该清楚地了解这个多列的索引对什么列 <br> <br> 的存取有效,对什么列的存取无效。 <br> (5)限制表中索引的数量。尽管表可以有任意数量的索引,可是 <br> <br> 索引越多,在修改表中的数据时对索引做出相应更改的工作量也 <br> <br> 越大,效率也就越低。同样,目前不用的索引应该及时删除。 <br> (6)指定索引数据块空间的使用。创建索引时,索引的数据块是 <br> <br> 用表中现存的值填充的,直到达到PCTFREE为止。如果打算将许多 <br> <br> 行插入到被索引的表中,PCTFREE就应设置得大一点,不能给索引 <br> <br> 指定PCTUSED。 <br> (7)根据索引大小设置存储参数。创建索引之前应先估计索引的 <br> <br> 大小,以便更好地促进规划和管理磁盘空间。单个索引项的最大 <br> <br> 值大约是数据块大小的一半。 <br> 16.6、删除索引 <br>  drop index PK_DEPT1; <br> 16.7、索引类型 <br> B树索引 B-tree indexes; <br> B树索引又可分为以下子类: <br> 索引组织表Index-organized tables; <br> 反转索引Reverse key indexes; <br> 降序索引Descending indexes; <br> B树聚簇索引B-tree cluster indexes; <br> 位图和位图联合索引Bitmap and bitmap join indexes; <br> 基于函数的索引Function-based indexes; <br> 应用域索引Application domain indexes; <br> B-Tree是一个平衡树的结构【注意这里的B表示Balanced平衡的意 <br> <br> 思,而不是Binary二叉】,B树索引也是Oracle里最为常见的索引 <br> <br> 类型。B树索引里的数据是已经按照关键字或者是被索引字段事先 <br> <br> 排好序存放的,默认是升序存放。 <br> 对于这幅B树存储结构图作以下几点介绍: <br> 1 、索引高度是指从根块到达叶子块时所遍历的数据块的个数, <br> <br> 而索引层次=索引高度-1;本图中的索引的高度是3,索引层次等 <br> <br> 于2;通常,索引的高度是2或者3,即使表中有上百万条记录,也 <br> <br> 就意味着,从索引中定位一个键字只需要2或3次I/O,索引越高, <br> <br> 性能越差; <br> 2、 B树索引包含两种数据块儿:分枝块(Branch Block)和叶子块 <br> <br> (Leaf Block); <br> 3 、分枝块里存放指向下级分枝块(索引高度大于2,即有超过两 <br> <br> 层分枝块的情况)或者直接指向叶子块的指针(索引高度等于2,即 <br> <br> 层次为1的索引); <br> 4 、叶子块,就是位于B树结构里最底层的数据块。叶子块里存放 <br> <br> 的是索引条目,即索引关键字和rowid,rowid用来精确定位表里 <br> <br> 的记录;索引条目都是按照索引关键字+rowid已经排好序存放的 <br> <br> ;同一个叶子块里的索引条目同时又和左右兄弟条目形成链表, <br> <br> 并且是一个双向链表; <br> 5 、B树索引的所有叶子块一定位于同一层上,这是由B树的数据 <br> <br> 结构定义的。因此,从根块到达任何一个叶子块的遍历代价都是 <br> <br> 相同的; <br> B 树索引(B-Tree Index) <br> 创建索引的默认类型,结构是一颗树,采用的是平衡 B 树算法: <br> l 右子树节点的键值大于等于父节点的键值 l 左子树节点的键值 <br> <br> 小于等于父节点的键值 <br> 位图索引(BitMap Index) <br> 如果表中的某些字段取值范围比较小,比如职员性别、分数列 <br> <br> ABC 级等。只有两个值。 <br> 这样的字段如果建 B 树索引没有意义,不能提高检索速度。这时 <br> <br> 我们推荐用位图索引 <br> Create BitMap Index student on(sex); <br> 索引按功能和索引对象分还有以下类型。 <br>     (1)唯一索引意味着不会有两行记录相同的索引键值。唯一 <br> <br> 索引表中的记录没有RowID,不能再对其建立其他索引。在 <br> <br> oracle10g中,要建立唯一索引,必须在表中设置主关键字,建立 <br> <br> 了唯一索引的表只按照该唯一索引结构排序。 <br>     (2)非唯一索引不对索引列的值进行唯一性限制。 <br>     (3)分区索引是指索引可以分散地存在于多个不同的表空间 <br> <br> 中,其优点是可以提高数据查询的效率。 <br>     (4)未排序索引也称为正向索引。Oracle10g数据库中的行 <br> <br> 是按升序排序的,创建索引时不必指定对其排序而使用默认的顺 <br> <br> 序。 <br>     (5)逆序索引也称反向索引。该索引同样保持列按顺序排列 <br> <br> ,但是颠倒已索引的每列的字节。 <br>     按照索引所包含的列数可以把索引分为单列索引和复合索引 <br> <br> 。索引列只有一列的索引为单列索引,对多列同时索引称为复合 <br> <br> 索引。 <br> 16.8、管理索引 <br> 1)先插入数据后创建索引 <br> 向表中插入大量数据之前最好不要先创建索引,因为如果先建立 <br> <br> 索引。那么在插入每行数据的时候都要更改索引。这样会大大降 <br> <br> 低插入数据的速度。 <br> 2)设置合理的索引列顺序 <br> 3)限制每个表索引的数量 <br> 4)删除不必要的索引 <br> 5)为每个索引指定表空间 <br> 6)经常做 insert,delete 尤其是 update 的表最好定期 <br> <br> exp/imp 表数据,整理数据,降低碎片(缺点:要停应用,以保 <br> <br> 持数据一致性,不实用); <br>      有索引的最好定期 rebuild 索引(rebuild期间只允许表的 <br> <br> select 操作,可在数据库较空闲时间提交),以降低索引碎片, <br> <br> 提高效率 <br>   <br> 16.8、索引问题 <br> 1.一个表的查询语句可以同时用到两个索引。 <br>   <br> 2.索引是以独立于表存在的一种数据库对象,它是对基表的一种 <br> <br> 排序(默认是 B 树索引就是二叉树的排序方式),比如: <br> 3.这样的查询效率,肯定是大于没有索引情况的全表扫描(table <br> <br> access full),但是有两个问题。 <br>     问题一:建立索引将占用额外的数据库空间,更重要的是增 <br> <br> 删改操作的时候,索引的排序也必须改变,加大的维护的成本 问 <br> <br> 题二:如果经常查询 x=?和 y=?,那推荐使用组合 index(x,y), <br> <br> 这种情况下组合索引的效率是远高于两个单独的索引的。 <br> 同时在用组合索引的时候,大家一定要注意一个细节:建立组合 <br> <br> 索引 index(x,y,z)的时候,那在查询条件中出现 x,xy,xyz,yzx <br> <br> 都是可以用到该组合索引,但是 y,yz,z 是不能用到该索引的。 <br> 第十三章 序列、同义词 <br> 13.1、 创建序列(sequence) <br> CREATE SEQUENCE seq <br>   INCREMENT BY 2--增量 <br>   START WITH 2--起始值 不能小于min <br>   MAXVALUE 10--最大值 <br>   MINVALUE 1--最小值 <br>   CYCLE--/NOCYCLE 序列号是否可循环(到了maxvalue在从min开 <br> <br> 始) <br>   CACHE 5--/NOCACHE 缓存下一个值,必须满足大于1,小于等于 <br> <br> (MAXVALUE-MINVALUE)/INCREMENT <br>   NOORDER--/NOORDER 序列号是否顺序产生 <br> 13.2、 属性 NextVal,CurrVal <br> --当前值 -----currval <br> SELECT seq.currval FROM dual; <br> --下一个值------nextval <br> SELECT seq.nextval FROM dual; <br> (必须先有 nextval,才能有 currval) <br> --在向表中插入数据时使用 <br> INSERT INTO emp1(empno) VALUES(seq.nextval); <br>  使用 cache 或许会跳号, 比如数据库突然不正常 down 掉 <br> (shutdown abort),cache中的sequence就会丢失. 所以可以在 <br> <br> create sequence的时候用nocache防止这种情况 <br> 13.3、 修改 <br> 不能改变当前值,但是可以改变增量 <br> ALTER SEQUENCE seq INCREMENT BY 3; <br> ALTER SEQUENCE seq CACHE 3; <br> 13.4、 删除 <br>  DROP SEQUENCE seq; <br> 13.5、 同义词 (synonym) <br> Select * from dual; <br> 为什么?因为同义词的存在 <br> Dual 其实是 sys 用户下的一张表 <br> select table_name from user_tables where lower <br> <br> (table_name) = 'dual'; <br> 1、概念 <br> 同义词是数据库方案对象的一个别名,经常用于简化对象访问和 <br> <br> 提高对象访问的安全性。在使用同义词时,Oracle数据库将它翻 <br> <br> 译成对应方案对象的名字。与视图类似,同义词并不占用实际存 <br> <br> 储空间,只有在数据字典中保存了同义词的定义。在Oracle数据 <br> <br> 库中的大部分数据库对象,如表、视图、同义词、序列、存储过 <br> <br> 程、包等等,数据库管理员都可以根据实际情况为他们定义同义 <br> <br> 词。 <br> 同义词,顾名思义就是两个词的意思一样,可以互相替换. <br> 2、作用: <br> 1) 多用户协同开发中,可以屏蔽对象的名字及其持有者。如果没 <br> <br> 有同义词,当操作其他用户的表时,必须通过user名.object名的 <br> <br> 形式,采用了Oracle同义词之后就可以隐蔽掉user名,当然这里 <br> <br> 要注意的是:public同义词只是为数据库对象定义了一个公共的 <br> <br> 别名,其他用户能否通过这个别名访问这个数据库对象,还要看 <br> <br> 是否已经为这个用户授权。 <br> 2) 简化sql语句。上面的一条其实就是一种简化sql的体现,同时 <br> <br> 如果自己建的表的名字很长,可以为这个表创建一个Oracle同义 <br> <br> 词来简化sql开发。 <br> 3)为分布式数据库的远程对象提供位置透明性。 <br> 4)Oracle同义词在数据库链接中的作用 <br> 数据库链接是一个命名的对象,说明一个数据库到另一个数据库 <br> <br> 的路径,通过其可以实现不同数据库之间的通信。 <br> Create database link 数据库链名 connect to user名 <br> <br> identified by 口令 using ‘Oracle连接串’; <br> 访问对象要通过 object名@数据库链名。同义词在数据库链中的 <br> <br> 作用就是提供位置透明性。 <br> 3、分类: <br> Create synonym dept for soctt.dept;(这样创建的同义词是私 <br> <br> 有的,只有创建者才能用) <br> Drop synonym dept; <br> Create public synonym dept for soctt.dept;(这样创建的同 <br> <br> 义词才是公有的) <br> Drop public synonym dept; <br> 4、权限管理 <br> 与同义词相关的权限有CREATE SYNONYM、CREATE ANY SYNONYM、 <br> <br> CREATE PUBLIC SYNONYM权限。 <br> 1:用户在自己的模式下创建私有同义词,这个用户必须拥有 <br> <br> CREATE SYNONYM权限,否则不能创建私有同义词。 <br> 2:如果需要在其它模式下创建同义词,则必须具有CREATE ANY <br> <br> SYNONYM的权限。 <br> 3:创建公有同义词则需要CREATE PUBLIC SYNONYM系统权限。 <br> 5、查看同义词 <br> SQL> SELECT * FROM DBA_SYNONYMS WHERE SYNONYM_NAME IN ( <br> <br> 'SYSN_TEST','PUBLIC_TEST'); <br> OWNER SYNONYM_NAME TABLE_OWNER TABLE_NAME DB_LINK <br> ------------------------------ <br> <br> ------------------------------ <br> PUBLIC PUBLIC_TEST ETL TEST <br> ETL SYSN_TEST ETL TEST <br> SQL> SELECT * FROM USER_SYNONYMS <br> 6、使用同义词 <br> SELECT * FROM SYSN_TEST; <br> 使用同义词可以保证当数据库的位置或对象名称发生改变时,应 <br> <br> 用程序的代码保持稳定不变,仅需要改变同义词; <br> 当使用一个没有指定schema的同义词是,首先在用户自己的 <br> <br> schema中寻找,然后再公共同义词中寻找 <br> 7、删除同义词 <br> DROP [ PUBLIC ] SYNONYM [ schema. ] 同义词名称 [ FORCE ]; <br> DROP SYNONYM SYSN_TEST; <br> DROP PUBLIC SYNONYM PUBLIC_TEST;--当同义词的原对象被删除 <br> <br> 是,同义词并不会被删除 <br> 8、编译同义词 <br> ALTER SYNONYM T COMPILE; --当同义词的原对象被重新建立时, <br> <br> 同义词需要重新编译 <br> 对原对象进行DDL操作后,同义词的状态会变成INVALID;当再次 <br> <br> 引用这个同义词时,同义词会自动编译,状态会变成VALID,无需 <br> <br> 人工干预,当然前提是不改变原对象的名称 <br> 问题锦集 <br> 1:公用同义词与私有同义词能否同名呢?如果可以,访问同义词 <br> <br> 时,是共有同义词还是私有同义词优先? <br> 可以,如果存在公用同义词和私有同义词同名的情况,在访问同 <br> <br> 义词是,访问的是私有同义词的指向的对象。 <br> 2:为啥OE用户创建的公用同义词,HR用户不能访问呢? <br> 因为HR没有访问OE模式下对象的权限,如果OE模式给HR用户赋予 <br> <br> 了SELECT对象等权限,那么HR用户即可访问。 <br> 3:对象、私有同义词、公共同义词是否可以存在三者同名的情况 <br> <br> ? <br> 存在同名对象和公共同义词时,数据库优先选择对象作为目标, <br> <br> 存在同名私有对象和公共对象时,数据库优先选择私有同义词作 <br> <br> 为目标 <br> 第十四章 函数 <br> in 只读 <br> out 只写 <br> in out 可读写 <br>  函数就是一个有返回值的过程。 <br> 定义一个函数:此函数可以根据雇员的编号查询出雇员的年薪 <br> CREATE OR REPLACE FUNCTION myfun(eno emp.empno%TYPE) <br> RETURN NUMBER <br> AS <br>  rsal NUMBER ; <br> BEGIN <br>  SELECT (sal+nvl(comm,0))*12 INTO rsal FROM emp WHERE <br> <br> empno=eno ; <br> RETURN rsal ; <br> END ; <br> / <br> 直接写 SQL 语句,调用此函数: <br> SELECT myfun(7369) FROM dual ; <br> 第十五章 触发器 <br> 15.1分类: <br> DML触发器-----------基于表的(insert、alter、update) <br> 替代触发器-----------基于VIEW的 <br> 系统触发器-----------基于系统的 <br> 好处:自动调用、记录日志、保证数据安全、用数据库触发器可 <br> <br> 以保证数据的一致性和完整性。 <br> 语法: <br> CREATE [OR REPLACE] TRIGGER trigger_name <br> {BEFORE | AFTER } <br> {INSERT | DELETE | UPDATE [OF column [, column …]]} <br> [OR {INSERT | DELETE | UPDATE [OF column [, column <br> <br> …]]}...] <br> ON [schema.]table_name | [schema.]view_name <br> [REFERENCING {OLD [AS] old | NEW [AS] new| PARENT as <br> <br> parent}] <br> [FOR EACH ROW ] <br> [WHEN condition] <br> PL/SQL_BLOCK | CALL procedure_name; <br>         <br>        BEFORE 和AFTER指出触发器的触发时序分别为前触发和后 <br> <br> 触发方式,前触发是在执行触发事件之前触发当前所创建的触发 <br> <br> 器,后触发是在执行触发事件之后触发当前所创建的触发器。 <br>        FOR EACH ROW选项说明触发器为行触发器。行触发器和语 <br> <br> 句触发器的区别表现在:行触发器要求当一个DML语句操走影响数 <br> <br> 据库中的多行数据时,对于其中的每个数据行,只要它们符合触 <br> <br> 发约束条件,均激活一次触发器;而语句触发器将整个语句操作 <br> <br> 作为触发事件,当它符合约束条件时,激活一次触发器。当省略 <br> <br> FOR EACH ROW 选项时,BEFORE 和AFTER 触发器为语句触发器, <br> <br> 而INSTEAD OF 触发器则只能为行触发器。 <br>        REFERENCING 子句说明相关名称,在行触发器的PL/SQL块 <br> <br> 和WHEN 子句中可以使用相关名称参照当前的新、旧列值,默认的 <br> <br> 相关名称分别为OLD和NEW。触发器的PL/SQL块中应用相关名称时 <br> <br> ,必须在它们之前加冒号(:),但在WHEN子句中则不能加冒号。 <br>       WHEN 子句说明触发约束条件。Condition 为一个逻辑表达 <br> <br> 时,其中必须包含相关名称,而不能包含查询语句,也不能调用 <br> <br> PL/SQL 函数。WHEN 子句指定的触发约束条件只能用在BEFORE 和 <br> <br> AFTER行触发器中,不能用在INSTEAD OF 行触发器和其它类型的 <br> <br> 触发器中。 <br> 15.2、 触发器触发次序 <br> 1. 执行 BEFORE语句级触发器; <br> 2. 对与受语句影响的每一行: <br> l 执行 BEFORE行级触发器 <br> l 执行 DML语句 <br> l 执行 AFTER行级触发器 <br> 3. 执行 AFTER语句级触发器 <br> 15.3、语句触发器 <br> after 语句触发器 <br> Before 语句触发器 <br> 例如:禁止工作人员在休息日改变雇员信息 <br> create or replace trigger tr_src_emp <br> before insert or update or delete <br> on emp <br> begin <br> if to_char(sysdate,'DY','nls_date_language=AMERICAN') in( <br> <br> 'SAT','SUN') then <br> raise_application_error(-20001,'can?t modify user <br> <br> information in weekend'); <br> end if; <br> end; <br> / <br>   <br> 使用条件谓语---------inserting、updating、deleting <br>  create or replace trigger tr_src_emp <br> before insert or update or delete <br> on emp <br> begin <br> if to_char(sysdate,'DY') in( '星期六','星期天') then <br> case <br> when inserting then <br>   raise_application_error(-20001,'fail to insert'); <br> when updating then <br>   raise_application_error(-20001,'fail to update'); <br>  when deleting then <br>   raise_application_error(-20001,'fail to delete'); <br> end case; <br> end if; <br> end; <br> / <br> 15.4、行触发器 <br> 执行 DML 操作时,每作用一行就触发一次触发器。 <br> Bofre 行触发器 <br> 例如:确保员工工资不能低于原有工资 <br> Create or replace trigger tr_emp_sal <br> before update of sal <br> on emp <br> for each row <br> begin <br> if :new.sal<:old.sal then <br>  raise_application_error(-20010,'sal should not be <br> <br> less'); <br> end if; <br> end; <br> / <br> after 行触发器 <br> 例如:统计员工工资变化 <br> Create table audit_emp_change( <br> Name varchar2(10), <br> Oldsal number(6,2), <br> Newsal number(6,2), <br> Time date); <br> Create or replace trigger tr_sal_sal after update of sal <br> <br> on emp for each row declare v_temp int; <br> begin <br> select count(*) into v_temp from audit_emp_change where <br> <br> name=:old.ename; if v_temp=0 then <br> insert into audit_emp_change values <br> <br> (:old.ename,:old.sal,:new.sal,sysdate); else <br>  update audit_emp_change set <br> <br> oldsal=:old.sal,newsal=:new.sal,time=sysdate where <br> <br> name=:old.ename; <br> end if; end; <br> / <br> 限制行触发器 <br> Create or replace trigger tr_sal_sal <br> after update of sal <br> on emp <br> for each row when (old.job=?SALESMAN?) <br> declare <br> v_temp int; <br> begin <br> select count(*) into v_temp from audit_emp_change where <br> <br> name=:old.ename; <br> if v_temp=0 then <br> insert into audit_emp_change values <br> <br> (:old.ename,:old.sal,:new.sal,sysdate); <br> else <br>  update audit_emp_change set <br> <br> oldsal=:old.sal,newsal=:new.sal,time=sysdate where <br> <br> name=:old.ename; <br> end if; <br> end; <br> / <br> 注意: <br> 例如:如果要基于 EMP 表建立触发器。那么该触发器的执行代码 <br> <br> 不能包含对 EMP 表的查询操作编写 DML 触发器的时,触发器代 <br> <br> 码不能从触发器所对应的基表中读取数据。 <br> Create or replace trigger tr_emp_sal <br> Before update of sal <br> on emp <br> For each row <br> declare <br> Maxsal number(6,2); <br> Begin <br> If :new.sal>maxsal then Select max(sal) into maxsal from <br> <br> emp; <br> Raise_application_error(-21000,?error?); <br> End if; <br> End; <br> / <br>  创建的时候不会报错。但是一旦执行就报错了 <br> update emp set sal=sal*1.1 where deptno=30 <br> DML触发器的限制 <br> l CREATE TRIGGER语句文本的字符长度不能超过32KB; <br> l 触发器体内的SELECT 语句只能为SELECT … INTO …结构,或 <br> <br> 者为定义游标所使用的SELECT语句。 <br> l 触发器中不能使用数据库事务控制语句 COMMIT; ROLLBACK, <br> <br> SVAEPOINT 语句; <br> l 由触发器所调用的过程或函数也不能使用数据库事务控制语句 <br> <br> ; <br> l 触发器中不能使用LONG, LONG RAW 类型; <br> l 触发器内可以参照LOB 类型列的列值,但不能通过 :NEW 修改 <br> <br> LOB列中的数据; <br>   <br>  :NEW 修饰符访问操作完成后列的值 <br>  :OLD 修饰符访问操作完成前列的值 <br> 特性 <br> INSERT <br> UPDATE <br> DELETE <br> OLD <br> NULL <br> 实际值 <br> 实际值 <br> NEW <br> 实际值 <br> 实际值 <br> NULL <br>   <br> 15.4 替代触发器 <br> 语法: <br> CREATE [OR REPLACE] TRIGGER trigger_name <br> INSTEAD OF <br> {INSERT | DELETE | UPDATE [OF column [, column …]]} <br> [OR {INSERT | DELETE | UPDATE [OF column [, column <br> <br> …]]}...] <br> ON [schema.] view_name --只能定义在视图上 <br> [REFERENCING {OLD [AS] old | NEW [AS] new| PARENT as <br> <br> parent}] <br> [FOR EACH ROW ] --因为INSTEAD OF触发器只能在行级上触发,所 <br> <br> 以没有必要指定 <br> [WHEN condition] <br> PL/SQL_block | CALL procedure_name; <br> 例2:创建复杂视图,针对INSERT操作创建INSTEAD OF触发器,向 <br> <br> 复杂视图插入数据。 <br> l 创建视图: <br> CREATE OR REPLACE FORCE VIEW "HR"."V_REG_COU" ("R_ID", <br> <br> "R_NAME", "C_ID", "C_NAME") <br> AS <br>  SELECT r.region_id, <br>     r.region_name, <br>     c.country_id, <br>     c.country_name <br>  FROM regions r, <br>     countries c <br>  WHERE r.region_id = c.region_id; <br>   <br> l 创建触发器: <br> CREATE OR REPLACE TRIGGER "HR"."TR_I_O_REG_COU" <br> INSTEAD OF INSERT <br> ON v_reg_cou <br> FOR EACH ROW <br> DECLARE <br> v_count NUMBER; <br> BEGIN <br>  SELECT COUNT(*) INTO v_count FROM regions WHERE <br> <br> region_id = :new.r_id; <br>  IF v_count = 0 THEN <br>     INSERT INTO regions <br>       (region_id, region_name <br>       ) VALUES <br>       (:new.r_id, :new.r_name <br>       ); <br>  END IF; <br>  SELECT COUNT(*) INTO v_count FROM countries WHERE <br> <br> country_id = :new.c_id; <br>  IF v_count = 0 THEN <br>     INSERT <br>     INTO countries <br>       ( <br>         country_id, <br>         country_name, <br>         region_id <br>       ) <br>       VALUES <br>       ( <br>         :new.c_id, <br>         :new.c_name, <br>         :new.r_id <br>       ); <br>  END IF; <br> END; <br>   <br> 创建INSTEAD OF触发器需要注意以下几点: <br> l 只能被创建在视图上,并且该视图没有指定WITH CHECK OPTION <br> <br> 选项。 <br> l 不能指定BEFORE 或 AFTER选项。 <br> l FOR EACH ROW子可是可选的,即INSTEAD OF触发器只能在行级 <br> <br> 上触发、或只能是行级触发器,没有必要指定。 <br> l 没有必要在针对一个表的视图上创建INSTEAD OF触发器,只要 <br> <br> 创建DML触发器就可以了。 <br>   <br> 15.5、系统事件触发器 <br> 语法: <br> CREATE OR REPLACE TRIGGER [sachema.]trigger_name <br> {BEFORE <br> {BEFORE|AFTER} <br> {ddl_event_list <br> {ddl_event_list | database_event_list} <br> ON { DATABASE | [schema.]SCHEMA } <br> [WHEN condition] <br> PL/SQL_block | CALL procedure_name; <br> 其中: ddl_event_list:一个或多个DDL 事件,事件间用 OR 分 <br> <br> 开; <br>          database_event_list:一个或多个数据库事件,事件 <br> <br> 间用 OR 分开; <br> 下面给出系统触发器的种类和事件出现的时机(前或后): <br> 事件 <br> 允许的时机 <br> 说明 <br> STARTUP <br> AFTER <br> 启动数据库实例之后触发 <br> SHUTDOWN <br> BEFORE <br> 关闭数据库实例之前触发(非正常关闭不触发) <br> SERVERERROR <br> AFTER <br> 数据库服务器发生错误之后触发 <br> LOGON <br> AFTER <br> 成功登录连接到数据库后触发 <br> LOGOFF <br> BEFORE <br> 开始断开数据库连接之前触发 <br> CREATE <br> BEFORE,AFTER <br> 在执行CREATE语句创建数据库对象之前、之后触发 <br> DROP <br> BEFORE,AFTER <br> 在执行DROP语句删除数据库对象之前、之后触发 <br> ALTER <br> BEFORE,AFTER <br> 在执行ALTER语句更新数据库对象之前、之后触发 <br> DDL <br> BEFORE,AFTER <br> 在执行大多数DDL语句之前、之后触发 <br> GRANT <br> BEFORE,AFTER <br> 执行GRANT语句授予权限之前、之后触发 <br> REVOKE <br> BEFORE,AFTER <br> 执行REVOKE语句收权限之前、之后触犯发 <br> RENAME <br> BEFORE,AFTER <br> 执行RENAME语句更改数据库对象名称之前、之后触犯发 <br> AUDIT / NOAUDIT <br> BEFORE,AFTER <br> 执行AUDIT或NOAUDIT进行审计或停止审计之前、之后触发 <br> /*create or replace trigger tr_emp1_1 <br>   --before update on emp1 <br>   after update on emp1 <br>   for each row <br> declare <br>   -- local variables here <br> begin <br>   if :new.sal<:old.sal then <br>     Raise_application_error(-20000, ':new.sal>:old.sal'); <br>   end if; <br> end tr;*/ <br> /*create or replace trigger tr_emp1_2 <br>    after delete on emp1 <br>    --before delete on emp1 <br>    for each row <br> begin <br>   Raise_application_error(-20001, '不能删'); <br> end;*/ <br> create or replace trigger tr_emp1_3 <br> after delete or update or insert on emp1 <br> for each ROW <br> begin <br>   if deleting then <br>     if :new.sal>0 then <br>        Raise_application_error(-20000, 'deleting'); <br>     end IF; <br>   /*elsif updating then <br>     if :new.sal<:old.sal then <br>        Raise_application_error(-20001, 'updating'); <br>     end if; <br>   else <br>     if :new.sal<:old.sal then <br>        Raise_application_error(-20002, 'inserting'); <br>     end if;*/ <br>   end if; <br> end; <br> 资料: <br> http://www.cnblogs.com/huyong/archive/2011/04/27/2030466. <br> <br> html <br> 第十六章 存储过程 <br> 16.1、存储过程 <br> CREATE OR REPLACE PROCEDURE procedure_name AS PL/SQL块 <br> 现在定义一个简单的过程,就是打印一个数字 <br> CREATE OR REPLACE PROCEDURE myproc AS <br>  i NUMBER ; <br> BEGIN <br>  i := 100 ; <br>  DBMS_OUTPUT.put_line('i = '||i) ; <br> END ; <br> / <br> 执行过程: exec 过程名字---------set serveroutput on <br> 下面编写一个过程,要求,可以传入部门的编号,部门的名称, <br> <br> 部门的位置,之后调用此过程就可以完成部门的增加操作。 <br> CREATE OR REPLACE PROCEDURE myproc(dno dept.deptno%TYPE, <br>   name dept.dname%TYPE, <br>   dl dept.loc%TYPE) <br> AS <br> cou NUMBER ; <br> BEGIN <br>  -- 判断插入的部门编号是否存在,如果存在则不能插入 <br>  SELECT COUNT(deptno) INTO cou FROM dept WHERE deptno=dno <br> <br> ; <br>  IF cou=0 THEN <br>   -- 可以增加新的部门 <br> INSERT INTO dept(deptno,dname,loc) VALUES(dno,name,dl) ; <br> <br> DBMS_OUTPUT.put_line('部门插入成功!') ; <br> ELSE <br>   DBMS_OUTPUT.put_line('部门已存在,无法插入!') ; <br>  END IF ; <br> END ; <br> / <br> 16.2 过程的参数类型: <br> ? IN:值传递,默认的-----只读 <br> ? IN OUT:带值进,带值出---可读写 <br> ? OUT:不带值进,带值出----只写 <br> IN OUT 类型: <br> CREATE OR REPLACE PROCEDURE myproc(dno IN OUT <br> <br> dept.deptno%TYPE, <br> name dept.dname%TYPE, <br> dl dept.loc%TYPE) AS <br>  cou NUMBER ; <br> BEGIN <br>  -- 判断插入的部门编号是否存在,如果存在则不能插入 <br>  SELECT COUNT(deptno) INTO cou FROM dept WHERE deptno=dno <br> <br> ; <br>  IF cou=0 THEN <br>   -- 可以增加新的部门 <br>   INSERT INTO dept(deptno,dname,loc) VALUES(dno,name,dl) <br> <br> ; <br>   DBMS_OUTPUT.put_line('部门插入成功!') ; <br>   -- 修改 dno 的值 <br>   dno := 1 ; <br>  ELSE <br>   DBMS_OUTPUT.put_line('部门已存在,无法插入!') ; dno := <br> <br> -1 ; <br>  END IF ; <br> END ; <br> / <br> 编写 PL/SQL 块验证过程: <br> DECLARE <br>  deptno dept.deptno%TYPE ; BEGIN <br>  deptno := 12 ; <br>  myproc(deptno,'开发','南京') ; <br>  DBMS_OUTPUT.put_line(deptno) ; <br> END ; <br> / <br> OUT 类型 不带任何值进,只把值带出来。 <br> CREATE OR REPLACE PROCEDURE myproc(dno OUT dept.deptno <br> <br> %TYPE) <br> AS <br>  I number <br> BEGIN <br>   I:= dno; <br> END ; <br> / <br> 执行上面的存储过程 <br> DECLARE <br>  deptno dept.deptno%TYPE ; <br> BEGIN <br> deptno :=myproc(deptno) ; <br>  DBMS_OUTPUT.put_line(deptno) ; <br> END ; <br> / <br> 第十七章 包 <br> 17.1 定义 <br> 包------规范和主体 <br> 包就是将一系列的相关联的PLSQL类型、项目和子程序等有计划的 <br> <br> 组织起来封装在一起 <br> 规范(包头)---------一个操作或应用的接口部分 <br> 主体----------对包的规范部分进行实现 <br> 语法; <br> 包的规范 <br> CREATE OR REPLACE PACKAGE package_name AS|IS <br> 参数、类型(type)、异常(exception)、游标(cursor)、 <br> <br> procedure、function <br> END[package_name]; <br> 包的主体 <br> CREATE OR REPLACE PACKAGE BODY package_name AS|IS <br> 参数、类型(type)、异常(exception)、游标(cursor)、 <br> <br> procedure、function <br> END[package_name]; <br> 调用: <br> package_name.type_name; <br> package_name.item_name; <br> package_name.call_spec_name; <br> 删除: <br> drop package package_name; <br> drop package body package_name; <br> 好处: <br> 1、模块化;-----提高应用程序的交互性 <br> 2、信息隐藏 <br> 例: <br> CREATE OR REPLACE PACKAGE DEMO_PKG <br> IS <br>   DEPTREC DEPT%ROWTYPE; <br>   <br>   --Add dept... <br>   FUNCTION add_dept( <br>            dept_no NUMBER, <br>            dept_name VARCHAR2, <br>            location VARCHAR2) <br>   RETURN NUMBER; <br>   <br>   --delete dept... <br>   FUNCTION delete_dept(dept_no NUMBER) <br>   RETURN NUMBER; <br>   <br>   --query dept... <br>   PROCEDURE query_dept(dept_no IN NUMBER); <br> END DEMO_PKG; <br> CREATE OR REPLACE PACKAGE BODY DEMO_PKG <br> IS <br> FUNCTION add_dept <br> ( <br>    dept_no NUMBER, <br>    dept_name VARCHAR2, <br>    location VARCHAR2 <br> ) <br> RETURN NUMBER <br> IS <br>   empno_remaining EXCEPTION; --自定义异常 <br>   PRAGMA EXCEPTION_INIT(empno_remaining, -1); <br>    /* -1 是违反唯一约束条件的错误代码 */ <br> BEGIN <br>   INSERT INTO dept VALUES(dept_no, dept_name, location); <br>   IF SQL%FOUND THEN <br>      RETURN 1; <br>   END IF; <br> EXCEPTION <br>      WHEN empno_remaining THEN <br>         RETURN 0; <br>      WHEN OTHERS THEN <br>         RETURN -1; <br> END add_dept; <br> FUNCTION delete_dept(dept_no NUMBER) <br> RETURN NUMBER <br> IS <br> BEGIN <br>   DELETE FROM dept WHERE deptno = dept_no; <br>   IF SQL%FOUND THEN <br>     RETURN 1; <br>   ELSE <br>     RETURN 0; <br>    END IF; <br> EXCEPTION <br>   WHEN OTHERS THEN <br>     RETURN -1; <br> END delete_dept; <br> PROCEDURE query_dept <br> (dept_no IN NUMBER) <br> IS <br> BEGIN <br>       SELECT * INTO DeptRec FROM dept WHERE <br> <br> deptno=dept_no; <br> EXCEPTION <br>        WHEN NO_DATA_FOUND THEN <br>           DBMS_OUTPUT.PUT_LINE('温馨提示:数据库中没有编码 <br> <br> 为'||dept_no||'的部门'); <br>        WHEN TOO_MANY_ROWS THEN <br>           DBMS_OUTPUT.PUT_LINE('程序运行错误,请使用游标进 <br> <br> 行操作!'); <br>        WHEN OTHERS THEN <br>            DBMS_OUTPUT.PUT_LINE(SQLCODE||'----'|| <br> <br> SQLERRM); <br> END query_dept; <br> BEGIN <br>     Null; <br> END DEMO_PKG; <br> <br> <br> 一、数据库连接 <br>     1、JDBC连接 <br>           1、加载JDBC驱动程序; <br>                     Class.forName <br> <br> ("com.mysql.jdbc.Driver");//oracle.jdbc.OracleDriver <br> <br>     2、创建数据库的连接; <br> <br>         Connection conn = DriverManager.getConnection <br> <br> (url,user,password); <br> <br>     3、创建一个Statement对象; <br> <br>         Statement stat = conn.createStatement() ; <br>         //PreparedStatement pstat = <br> <br> conn.prepareStatement(SQL_classification_INSERT); <br> <br>     4、执行SQL语句; <br> <br>         executeQuery 、executeUpdate  和execute <br>         ResultSet rs = stmt.executeQuery("SELECT * FROM <br> <br> ...") ; <br>         //rs=pstat.executeQuery(); <br> <br>     5、返回并处理结果; <br> <br>         while(rs.next()){ <br> <br>             ... <br> <br>         } <br> <br>     6、关闭连接; <br> <br>         rs.close() ; <br>         stat.close(); <br>         conn.close(); <br> <br>     2、Hibernate连接 <br>             <session-factory> <br> <br>           <property <br> <br> name="dialect">org.hibernate.dialect.MySQLDialect</proper <br> <br> ty> <br> <br>           <property <br> <br> name="connection.url">jdbc:mysql://localhost:3306/eshop_1 <br> <br> </property> <br> <br>           <property <br> <br> name="connection.username">root</property> <br> <br>           <property <br> <br> name="connection.password">107510</property> <br> <br>           <property <br> <br> name="connection.driver_class">com.mysql.jdbc.Driver</pro <br> <br> perty> <br> <br>           <property <br> <br> name="myeclipse.connection.profile">eshop_1</property> <br> <br>           <property name="show_sql">true</property> <br> <br>           <property name="format_sql">true</property> <br> <br>           <mapping class="com.yhtb.entity.TUsers" /> <br> <br>      </session-factory> <br> <br>     Configuration cfg=new Configuration().configure(); <br>               SessionFactory sf=cfg.buildSessionFactory <br> <br> ();------------------2级缓存 <br>               Session session=sf.openSession <br> <br> ();-------------------------------------1级缓存 <br>               Transaction tx=session.beginTransaction(); <br>               session.save()//增删改查的动作 <br>               tx.commit(); <br>               session.close(); <br>               sf.close(); <br> <br>     3、SSH中数据源连接 <br>              <bean id="dataSource" <br> <br> class="org.apache.commons.dbcp.BasicDataSource"> <br> <br>           <property name="url" <br> <br> value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"></property> <br> <br>           <property name="driverClassName" <br> <br> value="oracle.jdbc.OracleDriver"/> <br> <br>           <property name="username" <br> <br> value="scott"></property> <br> <br>           <property name="password" <br> <br> value="tiger"></property> <br> <br>           <property name="defaultAutoCommit" <br> <br> value="false"></property> <br> <br>          </bean> <br> <br>     <bean id="sessionFactory"     <br> <br> class="org.springframework.orm.hibernate3.annotation.Anno <br> <br> tationSessionFactoryBean"> <br> <br>           <property name="dataSource"> <br> <br>            <ref bean="dataSource" /></property> <br> <br>           <property name="hibernateProperties"> <br> <br>            <props><prop <br> <br> key="hibernate.dialect">org.hibernate.dialect.OracleDiale <br> <br> ct</prop> <br> <br>             <prop key="hibernate.show_sql">true</prop> <br> <br>             <prop <br> <br> key="hibernate.format_sql">true</prop></props></property> <br> <br>           <property <br> <br> name="annotatedClasses"><list><value>com.rain.entity.Emp< <br> <br> /value></list></property> <br> <br>          </bean> <br> <br> 二、Oracle <br>     1、 事务的特性 <br>         原子性、隔离性、持久性、一致性 <br>         savepoint p <br>        commit <br>        rollback <br> <br>     2、 动态SQL <br>             dml: <br> <br>       ddl: <br>       占位符’:‘ <br>     declare <br>       v_no emp1.ename%type:='&请输入号码'; --&变量绑定符 <br>       v_name emp1.ename%type; <br>       v_job emp1.job%type; <br>       v_sql long:='select ename,job from emp1 where <br> <br> ename=:xxx';--占位符 <br>     begin <br>        execute immediate v_sql into v_name,v_job using <br> <br> v_no; <br>        dbms_output.put_line('name= '||v_name||' job='|| <br> <br> v_job); <br>     end; <br> <br>     3、游标 <br>         1、分类: <br>             显示游标----游标名%属性名 <br>             隐式游标----SQL% <br>         2、步骤; <br> <br>           显示游标 语法格式: <br> <br>         CURSOR cursor_name is select * from emp;--声明游 <br> <br> 标 <br> <br>         OPEN cursor_name;--打开游标 <br> <br>         FETCH cursor_name INTO variables_list;--提取游标 <br> <br>         CLOSE cursor_name;--关闭游标 <br> <br>         例1: <br> <br>         DECLARE <br> <br>           v_deptno NUMBER:=&inputno; <br> <br>           v_row emp1%ROWTYPE; <br> <br>           CURSOR v_cursor IS SELECT * FROM emp1 WHERE <br> <br> deptno=v_deptno;--声明游标 <br> <br>         BEGIN <br> <br>           OPEN v_cursor; --打开 <br> <br>           --提取 <br> <br>           LOOP <br> <br>             FETCH v_cursor INTO v_row;--先提取 <br> <br>             EXIT WHEN v_cursor%NOTFOUND; <br> <br>             dbms_output.put_line('Employee Name: ' || <br> <br> v_row.ename || ' ,Salary: ' || v_row.sal); <br> <br>           END LOOP; <br> <br>           --关闭 <br> <br>           CLOSE v_cursor; <br> <br>         END; <br> <br> <br>         --隐式游标 <br> <br>             自动打开游标 <br> <br>             自动关闭游标 <br> <br>         通过隐式游标SQL的%ROWCOUNT属性来了解修改了多少行 <br> <br> 。 <br>         DECLARE <br>            v_rows NUMBER; <br>         BEGIN <br>         --更新数据 <br>            UPDATE employees SET salary = 30000 <br>            WHERE department_id = 90 AND job_id = 'AD_VP'; <br>         --获取默认游标的属性值 <br>            v_rows := SQL%ROWCOUNT; <br>            DBMS_OUTPUT.PUT_LINE('更新了'||v_rows||'个雇员 <br> <br> 的工资'); <br>         --回退更新,以便使数据库的数据保持原样 <br>            ROLLBACK; <br>         END; <br> <br>         3、应用中---for游标----无需声明、打开、提取、关闭 <br>            BEGIN <br> <br>     --隐含打开游标 <br>        FOR r IN (SELECT * FROM emp1 WHERE <br> <br> deptno=v_deptno) LOOP <br>     --隐含执行一个FETCH语句 <br>           dbms_output.put_line('Employee Name: ' || <br> <br> r.ename || ' ,Salary: ' || r.sal); <br>     --隐含监测c_sal%NOTFOUND <br>        END LOOP; <br>     --隐含关闭游标 <br> <br>          END; <br> <br>     4、视图 <br>                1、假表【不存储数据,只存储定义,定义被保 <br> <br> 存数据字典】 <br> <br>          2、作用:数据安全:(隐藏行或者列,保证数据不会 <br> <br> 被误删除) <br>                简化查询 <br>          3、定义格式: <br>            CREATE OR REPLACE VIEW v_表名_业务 <br>            as <br>              查询语句 <br> <br>     5、索引 <br> <br>         1、原理:先在索引中根据关键字找到记录的rowid,然 <br> <br> 后利用rowid在基表中直接定位记录并检索出来,所以速度快 <br>         2、特征:1、索引自动维护 <br>                         2、索引需要占据实际存储空间 <br>                         3、对于表中的主键列,将自动建立唯 <br> <br> 一索引           <br>         3、语法: <br> <br>             create index 索引名 <br> <br>             on <br> <br>             表名(列1,列2,...) <br> <br>             drop index 索引名 <br> <br>        4、作用:提高查询速度,通常情况下,索引应该建立在 <br> <br> 那些经常出现在where子句中的列上 <br> <br> <br>     6、序列 <br>           1、步骤 <br> <br>         CREATE SEQUENCE seq <br> <br>           INCREMENT BY 2--增量 <br> <br>           START WITH 2--起始值 不能小于min <br> <br>           MAXVALUE 10--最大值 <br> <br>           MINVALUE 1--最小值 <br> <br>           CYCLE--/NOCYCLE 序列号是否可循环(到了maxvalue <br> <br> 在从min开始) <br> <br>           CACHE 5--/NOCACHE 缓存下一个值,必须满足大于1, <br> <br> 小于等于(MAXVALUE-MINVALUE)/INCREMENT <br> <br>           NOORDER--/NOORDER 序列号是否顺序产生 <br> <br>     2、 属性   NextVal,CurrVal <br> <br>           3、作用 <br>                 序列通常和触发器一起使用,来自动生成主键 <br> <br>     7、函数 <br>           1、定义:函数就是一个有返回值的过程。 <br> <br>     2、步骤:此函数可以根据雇员的编号查询出雇员的年薪 <br> <br>         CREATE OR REPLACE FUNCTION myfun(eno emp.empno <br> <br> %TYPE) <br> <br>         RETURN NUMBER <br> <br>         AS <br> <br>              rsal NUMBER ; <br> <br>         BEGIN <br> <br>              SELECT (sal+nvl(comm,0))*12 INTO rsal FROM <br> <br> emp WHERE empno=eno ; <br> <br>             RETURN rsal ; <br> <br>         END ; <br> <br>         / <br> <br>     3、直接写 SQL 语句,调用此函数: <br> <br>         SELECT myfun(7369) FROM dual ; <br> <br>         v_dfd := EXEC myfun(7369); <br> <br> <br>     8、触发器 <br>         1、分类; <br> <br>         DML触发器-----------基于表的(insert、alter、 <br> <br> update) <br> <br>         替代触发器-----------基于VIEW的---行级 <br> <br>         系统触发器-----------基于系统的 <br> <br>       2、创建步骤; <br>             CREATE [OR REPLACE] TRIGGER trigger_name <br> <br>         {BEFORE | AFTER } <br> <br>         {INSERT | DELETE | UPDATE [OF column [, column … <br> <br> ]]} <br> <br>         [OR {INSERT | DELETE | UPDATE [OF column [, <br> <br> column …]]}...] <br> <br>         ON [schema.]table_name | [schema.]view_name <br> <br>         [REFERENCING {OLD [AS] old | NEW [AS] new| PARENT <br> <br> as parent}] <br> <br>         [FOR EACH ROW ] <br> <br>         [WHEN condition] <br> <br>         PL/SQL_BLOCK | CALL procedure_name; <br> <br>       3、作用 <br>             自动调用、记录日志、保证数据安全、用数据库触 <br> <br> 发器可以保证数据的一致性和完整性。 <br>         <br>          触发器(语句级、行级、谓词、分类、作用) <br>              基于表的触发器:[delete\update\insert] <br> <br>     create or replace trigger tr_src_emp <br>     before insert or update or delete <br>     on emp <br>     begin <br>     if to_char(sysdate,'DY') in( '星期六','星期天') then <br>     case <br> <br>     when inserting then <br>       raise_application_error(-20001,'fail to insert');   <br>     when updating then <br>       raise_application_error(-20001,'fail to update'); <br>      when deleting then <br>       raise_application_error(-20001,'fail to delete'); <br>     end case; <br>     end if; <br>     end; <br> <br>     / <br> <br> <br>     9、存储过程 <br>         1、定义 <br>             CREATE OR REPLACE PROCEDURE procedure_name <br>             AS PL/SQL块 <br>         2、参数类型 <br>             ?  IN:值传递,默认的-----只读 <br> <br>     ?  IN OUT:带值进,带值出---可读写 <br> <br>     ?  OUT:不带值进,带值出----只写 <br> <br>         3、作用 <br>             将通用的执行过程封装起来 <br> <br>     10、包 <br>             1、语法; <br> <br>     包的规范 <br> <br>     CREATE OR REPLACE PACKAGE package_name AS|IS <br> <br>         参数、类型(type)、异常(exception)、游标(cursor) <br> <br> 、procedure、function <br> <br>     END[package_name]; <br> <br> <br>     包的主体 <br> <br>     CREATE OR REPLACE PACKAGE BODY package_name AS|IS <br> <br>         参数、类型(type)、异常(exception)、游标(cursor) <br> <br> 、procedure、function <br> <br>     END[package_name]; <br> <br>     2、调用: <br> <br>         package_name.type_name; <br> <br>         package_name.item_name; <br> <br>         package_name.call_spec_name; <br> <br>            3、作用 <br>                 1、模块化;-----提高应用程序的交互性 <br>                 2、信息隐藏 <br> <br>     11、体系结构 <br> 三、Struts 2.1 <br>           1、校验框架 <br> <br>     2、配置文件 <br>     <struts> <br>       <package name="mypackage" extends="json-default"> <br>         <action name="login" class="UsersAction" <br> <br> method="login"> <br>           <result name="success" >/index.jsp</result> <br>           <result name="error" >/login.jsp</result> <br>         </action> <br>     </package> <br>     </struts> <br> <br>     3、国际化 <br>     <constant name="struts.i18n.encoding" value="utf-8" <br> <br> /> <br>     4、工作原理 <br> <br>         1、struts1 工作原理 <br>         2、struts2工作原理 <br> <br>     6、struts2标签 <br> <br>         <%@taglib uri="/struts-tags" prefix="s"%> <br> <br>     7、EL表达式的四个范围 <br>             pageScope、requestScope、sessionScope、 <br> <br> appalicationScope <br>     8、客户端校验和服务端校验的优缺点 <br>             客户端校验比服务端校验快,但如果用户禁掉js的 <br> <br> 话,客户端校验即失效,服务端校验用户不能禁掉 <br>     9、struts2的校验框架------服务端校验有基于action的硬 <br> <br> 编码和基于xml配置文件两种-------------十三中内置校验器 <br> <br>         一、基于Action的硬编码实现步骤 <br>         1、Action必须extends ActionSpport <br>         2、对某个方法进行校验,需要在Action中添加一个 <br> <br> validateXxx().该方法无需返回值,在该方法中加入 <br> <br> addFieldError(" "," ")或者addActionError(" "); <br>         3、在配置文件struts.xml中,必须增加一个<result <br> <br> name="input">/验证页面</result> <br>         4、在错误页面上显示错误信息。 <br>            a、页面必须使用struts标签<s: addFieldError>、 <br> <br> <s:addActionError> <br>             b、修改配置文件中的过滤器 <br>                   <filter-mapping> <br> <br>                 <filter-name>struts2</filter-name> <br> <br>                 <url-pattern>/*</url-pattern> <br> <br>               </filter-mapping> <br>             二、基于XML配置文件的实现步骤 <br> <br> <br>         a、找到对应的DTD文件头 <br>         <!DOCTYPE validators PUBLIC <br>             "-//OpenSymphony Group//XWork Validator <br> <br> 1.0.2//EN" <br>             "http://www.opensymphony.com/xwork/xwork- <br> <br> validator-1.0.2.dtd"> <br> <br> 四、Hibernate 3.3 <br>         1、查询方式 <br>             HQL【delete、update、select】 <br>             QBC【条件】 <br>             QBE【FindByExample】 <br>              load/get查询 <br> <br>        native SQL查询 <br>        命名SQL查询 <br> <br>         2、缓存 <br>             一级缓存:session <br>             二级缓存:sessionFactory <br> <br>         3、接口 <br>             SessionFactory <br>             Session <br>             Transacation <br>             Query <br>             Criteroa <br> <br>         4、对象状态 <br>              瞬时态、持久态、游离态 <br>         5、关联映射 <br>             one-to-many,many-to-one,one-to-one,many- <br> <br> to-many <br>         6、hibernate常见主键增长方式: <br>             increment、identity、native、assigned、 <br> <br> foreign、sequence <br>             select max(id) from TABLE <br>             id+1            n+1 <br>         7、 hibernate的抓取策略: <br>                select、join、fetch <br>         8、hibernate的延迟策略: <br>               proxy <br> <br>         lazy[关联级别、类级别] <br> <br>          <br> 五、Spring 3.0 <br> <br>     1、Spring是什么? <br>        Spring是一个容器框架,它管理所有的JavaBean的生命周 <br> <br> 期 <br>        Spring提供了六大模块:(core、aop、dao、orm、JEE、 <br> <br> web) <br>        Spring提供了强大的解耦,【IOC/DI,aop】 <br>     2、IOC <br>        DI注入的方式:setter、construstor <br> <br>         3、AOP <br> <br>     切面(aspect):用来切插业务方法的类。 <br>     连接点(joinpoint):是切面类和业务类的连接点,其实就是 <br> <br> 封装了业务方法的一些基本属性,作为通知的参数来解析。 <br>     通知(advice):在切面类中,声明对业务方法做额外处理的 <br> <br> 方法。 <br>     切入点(pointcut):业务类中指定的方法,作为切面切入的 <br> <br> 点。其实就是指定某个方法作为切面切的地方。 <br>     目标对象(target object):被代理对象。 <br>     AOP代理(aop proxy):代理对象。 <br> <br> AOP通知类型: <br> <br>     前置通知(before advice):在切入点之前执行。 <br>     后置通知(after returning advice):在切入点执行完成后 <br> <br> ,执行通知。 <br>     环绕通知(around advice):包围切入点,调用方法前后完成 <br> <br> 自定义行为。 <br>     异常通知(after throwing advice):在切入点抛出异常后, <br> <br> 执行通知。 <br> <br> 11、AJAX <br>       1、什么是AJAX <br>             AJAX = Asynchronous JavaScript and XML(异步 <br> <br> 的 JavaScript 和 XML)。 <br>     2、ajax的特点:局部刷新 <br>     3、Ajax所涉及的技术:JavaScript、XML、CSS、DOM(文档对 <br> <br> 象模型,在内存中以树结构存储的模型) <br>     4、Ajax的核心类:XMLHttpRequest                <br>             注意:不同的厂家ActiveXObject(IE5及以下) <br>     5、Ajax常见的框架:JQuery、DOJO、prototype(原型)、 <br> <br> DWR(直接web远程访问)、YUI(雅虎用户界面)、ExtJS <br>     6、Ajax应用的开发步骤: <br> <br>     //1、创建XMLHttpRequest()对象 <br>        if (window.XMLHttpRequest){// code for IE7+, <br> <br> Firefox, Chrome, Opera, Safari <br>          xmlhttp=new XMLHttpRequest(); <br>        }else{// code for IE6, IE5 <br>          xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); <br>        } <br>      //2、处理响应(responseText或responseXML) <br>        xmlhttp.onreadystatechange=function(){ <br>           if (xmlhttp.readyState==4 && <br> <br> xmlhttp.status==200){ <br>             //局部刷新的代码,通常有以下语句         <br> <br> document.getElementById <br> <br> ("data").innerHTML=xmlhttp.responseText; <br>             //js操作Html <br>            } <br>          }; <br>        //3、向服务器发送请求 <br>        xmlhttp.open("GET","/ajax1/index.jsp? <br> <br> t="+Math.random(),true); <br>        xmlhttp.send();//只有是GET提交时才赋值为NULL <br> <br> 12、JSON <br> <br>     1、JSON是什么 <br> <br>            a、JavaScript 对象表示法(JavaScript Object <br> <br> Notation)。 <br>           { <br> <br> <br>         "employees": [ <br> <br> <br>         { "firstName":"Bill" , "lastName":"Gates" }, <br> <br> <br>         { "firstName":"George" , "lastName":"Bush" }, <br> <br> <br>         { "firstName":"Thomas" , "lastName":"Carter" } <br> <br> <br>         ] <br> <br> <br>     } <br> <br>           b、JSON 是存储和交换文本信息的语法。类似 XML。 <br> <br>           c、JSON 比 XML 更小、更快,更易解析 <br> <br>      <br> <br> 13、js的对象 <br> <br>      1、内置对象 <br> <br>             String: var s = new String("23213"); <br> <br>             Date:      var d = new Date(); <br> <br>             Math:     Math.random(); <br> <br>             Array:     var a = new Array(); <br> <br>             Object:   var o = new Object(); <br> <br>     2、js的浏览器对象(BOM) <br> <br>             window: window.alert()、 window.confirm、 <br> <br> window.setTimeout()                                        <br> <br>          <br> <br>             document:document.getElementById()、 <br> <br>                                <br> <br> document.getElementByTagName() <br> <br>             location:window.location.href <br> <br>     3、js中的DOM对象 <br> <br>         HTML、BODY、SELECT、INPUT <br> <br>     4、js的自定义对象 <br> <br>           <script type="text/javascript"> <br> <br>           <!-- <br> <br>         方法一: <br> <br>          //1、定义类 <br> <br>           function person(name,sex){ <br> <br>                this.name=name; <br> <br>                this.sex=sex; <br> <br>           } <br> <br>          //2、实例化 <br> <br>          var p1 = new person("rain","man"); <br> <br> <br>         方法二:--------------------JSON <br> <br>         定义并实例化: <br> <br>         var p2 = {"name":"你的","sex":"women"}; <br> <br> <br>         var p = [{"name":"张三丰","sex":"男","tel": <br> <br> {"t1":"332","t2":"445"}},{"name":"张无忌","sex":"男 "}, <br> <br> {"name":"张翠山","sex":"男 "}]; <br> <br> <br>          //3、显示数据 <br> <br>          alert(p.name); <br> <br>          alert(p.sex); <br> <br>          confirm(p.name); <br> <br> <br>         //alert(p[1].name); <br> <br>          //alert(p[0].sex); <br> <br>          //confirm(p[2].name); <br> <br>          alert(p[0].tel.t1); <br> <br> <br>         //将字符串转化成对象-----------JSON <br> <br>          var pp = '{"name":"张三丰","sex":"男","tel": <br> <br> {"t1":"332","t2":"445"}}'; <br> <br>          alert(eval('('+pp+')').name); <br> <br> <br>           //--> <br> <br>       </script> <br> <br> <br> 14、JQuery <br>          <br>     1、定义:Jquery是一个丰富的js库     <br>     2、JQuery对象就是通过Jquery包装DOM对象后产生的对象 <br> <br>         <script type="text/javascript" src="jquery- <br> <br> 1.11.0.js"></script> <br> <br>          <script type="text/javascript"> <br> <br>          <!--/*//第一种格式: <br> <br>           function f1(){ <br> <br>            alert('Hello World!'); <br> <br>           }; <br> <br>           $(document).ready(f1); <br> <br>          //第二种格式: <br> <br>           $(document).ready(function(){ <br> <br>            alert('Hello World!'); <br> <br>           });*/ <br> <br>          $(document).ready(function(){ <br> <br>            //$('#111').css('background-color','blue') <br> <br>            // .css('width','234') <br> <br>            // .css('height','333')//修改样式 <br> <br>            // .html('<hr/>hello')//修改值 <br> <br>            // .html();//取值 <br> <br>            //$('#111').css({'background- <br> <br> color':'blue','width':'120','height':'120'})//修改样式 <br> <br>            // .text('<hr/>hello');//修改值 <br> <br>            //$('.222,#111').html('<hr/>'); <br> <br>            //$('div:last').html('hehehhe'); <br> <br>            //$('div:first').html('hehehhe'); <br> <br>            //$('#111>p').html('<hr/>'); <br> <br>            //$('#111 p').html('<hr/>'); <br> <br>            //$('#111+.222').html('<hr/>'); <br> <br>            //$('#111 ~ p').html('<hr/>'); <br> <br>            //$('tr:odd').css({'background- <br> <br> color':'blue'}); <br> <br>            //$('tr:even').css('background- <br> <br> color','#eeffee'); <br> <br>            //$('tr:eq(0)').css({'background- <br> <br> color':'blue'}); <br> <br>            //$('tr:gt(1)').css({'background- <br> <br> color':'blue'}); <br> <br>            $('tr:lt(1)').css({'background- <br> <br> color':'blue'}); <br> <br>          }); <br> <br>          //--></script> </head> <br> <br>          <body> <br> <br>           <div id="111">sssssssssss <br> <br>           <p>sfdsf</p> <br> <br>           </div> <br> <br>           <p>sfdsf</p> <br> <br>           <div class="222">sssssssssss</div> <br> <br>           <div >sssssssssss</div> <br> <br>           <table border="1"><center> <br> <br>          <tr><td>1</td><td>1</td></tr> <br> <br>          <tr><td>22</td><td>22</td></tr> <br> <br>          <tr><td>333</td><td>333</td></tr> <br> <br>          <tr><td>4444</td><td>4444</td></tr> <br> <br>           </table></center></body> <br> <br>         例2: <br>         <script type="text/javascript" src="jquery- <br> <br> 1.11.0.js"></script> <br>            <script type="text/javascript"> <br>             $(function(){ <br>              alert(222); <br>              $('button').click(function(){ <br>               $('#list').load('index.jsp'); <br>              }); <br>             }); <br>            </script> <br>           </head> <br>           <br>           <body> <br>             <div id="list"></div> <br>             <button>获取服务器数据</button> <br>           </body> <br> <br> 六、SSH <br> <br>     Spring----------3.0 <br>             定义:是一个管理JavaBean生命周期的容器型的轻 <br> <br> 量型框架,包含六大模块DAO、ORM、Web、Core、JEE、AOP <br>     Hibernate------3.3 <br>             ORM持久型框架---映射---POJO的属性和表中的字段 <br> <br> ,对象和表,POJO的属性的类型与表中字段的属性的类型 <br>     Struts-----------1.3/2.1 <br>             MVC的web轻量型框架 <br> <br> <br> <br>     VO--------------------值对象 <br>     DTO------------------数据传输对象 <br>     BO--------------------业务对象 <br>     PO---------------------持久化对象 <br>     POJO-----------------简单无规则Java对象(JavaBean) <br>     DAO-------------------数据访问对象 <br> <br> <br> 七、泛型DAO <br>         1、设计通用DAO接口 <br> <br>           public interface IGenericDAO<T,ID extends <br> <br> Serializable>{ <br>              public abstract void save(T entity); <br>              public abstract void update(T entity); <br>              public abstract void delete(ID id); <br>              public abstract T findById(ID id); <br>              public abstract List<T> findAll(); <br>              public abstract List<T> findByExample(T <br> <br> entity); <br>              public abstract int count(T entity); <br>              public abstract pageVO<T> findByPage(T <br> <br> entity,int currentpage,int pageSize); <br>           } <br>       <br>     2、设计通用DAO的实现类 <br>          public class GenericDAOImpl<T,ID extends <br> <br> Serializable> extends HibernateDaoSupport implements <br> <br> IGenericDAO<T,ID>{ <br>              protected class<?> clazz; <br>             //初始化clazz <br>             public GenericDAOImpl(){ <br>      //1、得到我们的通用范型实现类的子类,例如:得到 <br> <br> EmpDAOImpl <br>          Class<?> cls=getClass(); <br>      //2、得到具体类【EmpDAOImpl】的父类,由于父类是范型 <br> <br> 类,所以,方法为: <br>          ParameterizedType ptype=(ParameterizedType) <br> <br> cls.getGenericSuperclass(); <br>      //3、得到具体的参数实际类型 <br>         clazz=(Class<?>)(ptype.getActualTypeArguments() <br> <br> [0]); <br>             } <br>       <br>              public void save(T entity){ <br>                  getHibernateTemplate().save(entity); <br>              } <br>              public void update(T entity){ <br>                  getHibernateTemplate().update(entity); <br>              } <br>              public void delete(ID id){ <br>                  getHibernateTemplate().delete(id); <br>              } <br>              public T findById(ID id){ <br>                    return T(getHibernateTemplate().get <br> <br> (clazz,id)); <br>              } <br>              public List<T> findAll(){ <br>        DetachedCriteria <br> <br> criteria=DetachedCriteria.forClass(entityClass); <br>       return getHibernateTemplate().findByCriteria <br> <br> (criteria);; <br>       } <br>              public List<T> findByExample(T entity){ <br>       return getHibernateTemplate().findByExample <br> <br> (instance); <br>       } <br>              public int count(T entity){} <br>              public pageVO<T> findByPage(T entity,int <br> <br> currentpage,int pageSize){} <br>           <br>     3、设计每个业务DAO接口,例如IEmpDAO <br>           public interface IEmpDAO extends <br> <br> IGenericDAO<Emp,Integer>{ <br>               //新增自己DAO的特有方法:例如登录 <br>               Emp login(String account,String password); <br>           } <br>     4、设计每个业务DAO的实现类,例如EmpDAOImpl <br>           public class EmpDAOImpl extends <br> <br> GenericDAOImpl<Emp,Integer> implements IEmpDAO{ <br>                   public Emp login(String account,String <br> <br> password){ <br>                       return null; <br>                   } <br>           } <br>         } <br> <br>     购物车 <br> <br> <br> <br> <br> <br>     链接: <br>     1、JAVA <br>     2、JDBC <br>     3、OA开发 <br>     4、Oracle <br>     5、WEB <br>     6、AJAX <br>     7、Hibernate <br>     8、Spring <br>     9、struts1 <br>     10、总结 <br> <br> </div> </div> </div> </div> </div> <!--PC和WAP自适应版--> <div id="SOHUCS" sid="1290153710747459584"></div> <script type="text/javascript" src="/views/front/js/chanyan.js"></script> <!-- 文章页-底部 动态广告位 --> <div class="youdao-fixed-ad" id="detail_ad_bottom"></div> </div> <div class="col-md-3"> <div class="row" id="ad"> <!-- 文章页-右侧1 动态广告位 --> <div id="right-1" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_1"> </div> </div> <!-- 文章页-右侧2 动态广告位 --> <div id="right-2" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_2"></div> </div> <!-- 文章页-右侧3 动态广告位 --> <div id="right-3" class="col-lg-12 col-md-12 col-sm-4 col-xs-4 ad"> <div class="youdao-fixed-ad" id="detail_ad_3"></div> </div> </div> </div> </div> </div> </div> <div class="container"> <h4 class="pt20 mb15 mt0 border-top">你可能感兴趣的:(JavaWeb开发)</h4> <div id="paradigm-article-related"> <div class="recommend-post mb30"> <ul class="widget-links"> <li><a href="/article/1835344485802930176.htm" title="基于JavaWeb开发的Java+SpringMvc+vue+element实现上海汽车博物馆平台" target="_blank">基于JavaWeb开发的Java+SpringMvc+vue+element实现上海汽车博物馆平台</a> <span class="text-muted">网顺技术团队</span> <a class="tag" taget="_blank" href="/search/%E6%88%90%E5%93%81%E7%A8%8B%E5%BA%8F%E9%A1%B9%E7%9B%AE/1.htm">成品程序项目</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/%E6%B1%BD%E8%BD%A6/1.htm">汽车</a><a class="tag" taget="_blank" href="/search/%E8%AF%BE%E7%A8%8B%E8%AE%BE%E8%AE%A1/1.htm">课程设计</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a> <div>基于JavaWeb开发的Java+SpringMvc+vue+element实现上海汽车博物馆平台作者主页网顺技术团队欢迎点赞收藏⭐留言文末获取源码联系方式查看下方微信号获取联系方式承接各种定制系统精彩系列推荐精彩专栏推荐订阅不然下次找不到哟Java毕设项目精品实战案例《1000套》感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多的人文章目录基</div> </li> <li><a href="/article/1834672973898936320.htm" title="Servlet 文件上传" target="_blank">Servlet 文件上传</a> <span class="text-muted">lly202406</span> <a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>Servlet文件上传在JavaWeb开发中,文件上传是一个常见的需求。Servlet作为一种服务器端的技术,可以轻松实现文件上传功能。本文将详细介绍如何在Servlet中处理文件上传,包括环境配置、代码实现以及常见问题的解决方案。环境配置1.添加依赖在项目的pom.xml文件中,添加ApacheCommonsFileUpload库的依赖。这个库提供了易于使用的API来处理文件上传。commons</div> </li> <li><a href="/article/1834328721507577856.htm" title="11- 【JavaWeb】Cookie 、Session、Filter、Listener" target="_blank">11- 【JavaWeb】Cookie 、Session、Filter、Listener</a> <span class="text-muted">weixin_44329069</span> <a class="tag" taget="_blank" href="/search/JavaWeb/1.htm">JavaWeb</a><a class="tag" taget="_blank" href="/search/hive/1.htm">hive</a><a class="tag" taget="_blank" href="/search/python/1.htm">python</a><a class="tag" taget="_blank" href="/search/hadoop/1.htm">hadoop</a> <div>了解Cookie、Session、Filter和Listener是JavaWeb开发中非常重要的部分。1.CookieCookie是服务器在客户端浏览器上存储的小数据片段,用于在不同请求之间保持状态。Cookie通常用于保存用户信息、跟踪会话、保存用户偏好等。示例:创建和读取Cookie设置Cookie(在Servlet中):@WebServlet("/setCookie")publicclass</div> </li> <li><a href="/article/1833514971900768256.htm" title="Java Web安全与Spring Config对象实战" target="_blank">Java Web安全与Spring Config对象实战</a> <span class="text-muted">福建低调</span> <div>本文还有配套的精品资源,点击获取简介:本课程深入探讨JavaWeb开发中的安全实践,包括认证与授权、输入验证、CSRF和XSS防护以及SQL注入防御等关键安全措施。同时,介绍SpringSecurity框架的应用,以及Config对象在Spring配置管理中的作用,包括依赖注入和外部化配置。课程还包括实战演练,通过设置安全环境和安全漏洞模拟,帮助开发者提升应用的安全性和故障排查能力。1.Web安全</div> </li> <li><a href="/article/1832913705701044224.htm" title="@Slf4j注解 - javaweb日志记录" target="_blank">@Slf4j注解 - javaweb日志记录</a> <span class="text-muted">需要重新演唱</span> <a class="tag" taget="_blank" href="/search/web/1.htm">web</a><a class="tag" taget="_blank" href="/search/web/1.htm">web</a><a class="tag" taget="_blank" href="/search/%E6%97%A5%E5%BF%97/1.htm">日志</a><a class="tag" taget="_blank" href="/search/%E6%B3%A8%E8%A7%A3/1.htm">注解</a> <div>1.引言在现代的JavaWeb开发中,日志记录是一个非常重要的组成部分。良好的日志记录可以帮助开发者快速定位问题、监控系统运行状态以及进行性能调优。@Slf4j注解是Lombok库提供的一个便捷工具,用于简化日志记录的代码编写。本文将详细讲解@Slf4j注解的相关内容,包括其概念、使用方法以及一些最佳实践。2.什么是Lombok?Lombok是一个Java库,它通过注解的方式帮助开发者减少样板代码</div> </li> <li><a href="/article/1832056702166462464.htm" title="过滤器与拦截器的区别与应用" target="_blank">过滤器与拦截器的区别与应用</a> <span class="text-muted">黄尚圈圈</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/tomcat/1.htm">tomcat</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a> <div>在JavaWeb开发中,过滤器(Filter)和拦截器(Interceptor)是两种常见的用于处理请求和响应的组件,它们在功能上有一定的重叠,但在使用场景、实现方式和作用范围上存在显著的差异。本文将深入探讨过滤器与拦截器的区别,以及它们在实际项目中的应用。1.定义与概念过滤器(Filter)过滤器是Servlet规范中的一部分,它允许你对请求(Request)和响应(Response)进行预处理</div> </li> <li><a href="/article/1831875775679262720.htm" title="基于JavaWeb开发的JavaSpringboot+Vue实现前后端分离房屋租赁系统" target="_blank">基于JavaWeb开发的JavaSpringboot+Vue实现前后端分离房屋租赁系统</a> <span class="text-muted">网顺技术团队</span> <a class="tag" taget="_blank" href="/search/%E6%88%90%E5%93%81%E7%A8%8B%E5%BA%8F%E9%A1%B9%E7%9B%AE/1.htm">成品程序项目</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a><a class="tag" taget="_blank" href="/search/%E8%AF%BE%E7%A8%8B%E8%AE%BE%E8%AE%A1/1.htm">课程设计</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF%E6%A1%86%E6%9E%B6/1.htm">前端框架</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a> <div>基于JavaWeb开发的JavaSpringboot+Vue实现前后端分离房屋租赁系统作者主页网顺技术团队欢迎点赞收藏⭐留言文末获取源码联系方式查看下方微信号获取联系方式承接各种定制系统精彩系列推荐精彩专栏推荐订阅不然下次找不到哟Java毕设项目精品实战案例《1000套》感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多的人文章目录基于JavaW</div> </li> <li><a href="/article/1831736871407939584.htm" title="java sql注入正则表达式_Java程序员从笨鸟到菜鸟之(一百零二)sql注入攻击详解(三)sql注入解决办法..." target="_blank">java sql注入正则表达式_Java程序员从笨鸟到菜鸟之(一百零二)sql注入攻击详解(三)sql注入解决办法...</a> <span class="text-muted">用看智障的眼神看</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/sql%E6%B3%A8%E5%85%A5%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F/1.htm">sql注入正则表达式</a> <div>我们了解了sql注入原理和sql注入过程,今天我们就来了解一下sql注入的解决办法。怎么来解决和防范sql注入,由于本人主要是搞javaweb开发的小程序员,所以这里我只讲一下有关于javaweb的防止办法。其实对于其他的,思路基本相似。下面我们先从web应用程序的角度来看一下如何避免sql注入:1、普通用户与系统管理员用户的权限要有严格的区分。如果一个普通用户在使用查询语句中嵌入另一个DropT</div> </li> <li><a href="/article/1831049729308454912.htm" title="JavaWeb开发知识总结(JSP,EL,JSTL)" target="_blank">JavaWeb开发知识总结(JSP,EL,JSTL)</a> <span class="text-muted">Sunmos</span> <a class="tag" taget="_blank" href="/search/JavaWeb/1.htm">JavaWeb</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/web/1.htm">web</a><a class="tag" taget="_blank" href="/search/jsp/1.htm">jsp</a><a class="tag" taget="_blank" href="/search/EL%E8%A1%A8%E8%BE%BE%E5%BC%8F/1.htm">EL表达式</a><a class="tag" taget="_blank" href="/search/JSTL%E6%A0%87%E7%AD%BE%E5%BA%93/1.htm">JSTL标签库</a> <div>JavaWeb开发知识总结(JSP,EL,JSTL)1.JSP概述JSP技术:Java服务器端页面(JavaServerPages),是一种动态网页开发技术。JSP的组成:HTML+Java代码+JSP自身元素。JSP自身元素包括JSP指令,JSP动作标签和JSP的内置对象。2.JSP执行流程JSP的本质是Servlet,tomcat服务器会将jsp文件进行编译生成一个servlet.java文件</div> </li> <li><a href="/article/1830892562437730304.htm" title="Java 快速入门 知识精简(1)" target="_blank">Java 快速入门 知识精简(1)</a> <span class="text-muted">Tangy范</span> <a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a> <div>语言特点特点一:面向对象俩个基本概念:类,对象三大特性:封装,继承,多态特点二:健壮性去掉了指针,内存的申请与释放提供了相对安全的内存管理和访问机制特点三:跨平台性由JVM负责Java程序在系统中的运行JVMforUNIXJVMforWindowsJVMforMac应用领域:JavaWeb开发后台开发大数据开发Android应用程序开发:客户端开发知识结构编程语言核心结构:主要知识点:变量、基本语</div> </li> <li><a href="/article/1830199940849168384.htm" title="【Rust】——采用发布配置自定义构建" target="_blank">【Rust】——采用发布配置自定义构建</a> <span class="text-muted">Y小夜</span> <a class="tag" taget="_blank" href="/search/Rust%EF%BC%88%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E9%87%8D%E7%82%B9%E6%80%BB%E7%BB%93%EF%BC%89/1.htm">Rust(官方文档重点总结)</a><a class="tag" taget="_blank" href="/search/rust/1.htm">rust</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/%E5%90%8E%E7%AB%AF/1.htm">后端</a> <div>博主现有专栏:C51单片机(STC89C516),c语言,c++,离散数学,算法设计与分析,数据结构,Python,Java基础,MySQL,linux,基于HTML5的网页设计及应用,Rust(官方文档重点总结),jQuery,前端vue.js,Javaweb开发,Python机器学习等主页链接:Y小夜-CSDN博客今日学习推荐:在当今这个飞速发展的信息时代,人工智能(AI)已经成为了一个不可或</div> </li> <li><a href="/article/1830194136423165952.htm" title="【Rust】——高级类型" target="_blank">【Rust】——高级类型</a> <span class="text-muted">Y小夜</span> <a class="tag" taget="_blank" href="/search/Rust%EF%BC%88%E5%AE%98%E6%96%B9%E6%96%87%E6%A1%A3%E9%87%8D%E7%82%B9%E6%80%BB%E7%BB%93%EF%BC%89/1.htm">Rust(官方文档重点总结)</a><a class="tag" taget="_blank" href="/search/rust/1.htm">rust</a><a class="tag" taget="_blank" href="/search/%E5%BC%80%E5%8F%91%E8%AF%AD%E8%A8%80/1.htm">开发语言</a><a class="tag" taget="_blank" href="/search/%E5%90%8E%E7%AB%AF/1.htm">后端</a> <div>博主现有专栏:C51单片机(STC89C516),c语言,c++,离散数学,算法设计与分析,数据结构,Python,Java基础,MySQL,linux,基于HTML5的网页设计及应用,Rust(官方文档重点总结),jQuery,前端vue.js,Javaweb开发,Python机器学习等主页链接:Y小夜-CSDN博客目录为了类型安全和抽象而使用的newtype模式类型别名用来创建类型同义词不返回</div> </li> <li><a href="/article/1830038450259193856.htm" title="基于Java+Springboot+Vue+elememt宠物用品商城系统设计实现" target="_blank">基于Java+Springboot+Vue+elememt宠物用品商城系统设计实现</a> <span class="text-muted">网顺技术团队</span> <a class="tag" taget="_blank" href="/search/%E6%88%90%E5%93%81%E7%A8%8B%E5%BA%8F%E9%A1%B9%E7%9B%AE/1.htm">成品程序项目</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a><a class="tag" taget="_blank" href="/search/vue.js/1.htm">vue.js</a><a class="tag" taget="_blank" href="/search/%E8%AF%BE%E7%A8%8B%E8%AE%BE%E8%AE%A1/1.htm">课程设计</a><a class="tag" taget="_blank" href="/search/%E5%90%8E%E7%AB%AF/1.htm">后端</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a> <div>基于JavaWeb开发的宠物用品商城系统作者主页网顺技术团队欢迎点赞收藏⭐留言文末获取源码联系方式查看下方微信号获取联系方式承接各种定制系统精彩系列推荐精彩专栏推荐订阅不然下次找不到哟Java毕设项目精品实战案例《1000套》感兴趣的可以先收藏起来,还有大家在毕设选题,项目以及论文编写等相关问题都可以给我留言咨询,希望帮助更多的人文章目录基于JavaWeb开发的宠物用品商城系统一、前言介绍:二、系</div> </li> <li><a href="/article/1829917462683021312.htm" title="DispatcherServlet vs 传统Servlet:优势解析" target="_blank">DispatcherServlet vs 传统Servlet:优势解析</a> <span class="text-muted">张某布响丸辣</span> <a class="tag" taget="_blank" href="/search/servlet/1.htm">servlet</a><a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/SpringMVC/1.htm">SpringMVC</a><a class="tag" taget="_blank" href="/search/Spring/1.htm">Spring</a><a class="tag" taget="_blank" href="/search/%E5%90%8E%E7%AB%AF/1.htm">后端</a> <div>在JavaWeb开发领域,DispatcherServlet与传统Servlet都是处理HTTP请求的关键组件。然而,随着SpringMVC等现代Web框架的兴起,DispatcherServlet逐渐成为了开发者的首选。本文将探讨DispatcherServlet相较于传统Servlet的优势,帮助读者更好地理解两者的区别与选择。一、引言在传统的JavaEE应用中,Servlet是处理HTTP请</div> </li> <li><a href="/article/1828995921984188416.htm" title="Embedded Servlet Container 是怎样启动的" target="_blank">Embedded Servlet Container 是怎样启动的</a> <span class="text-muted">Java弟中弟</span> <div>传统JavaWeb开发中,开发者需要独立部署Servlet容器,比如Tomcat,并将应用程序打成war包放入容器才能运行,这多多少少有点繁琐且不方便调试,嵌入式Servlet容器的出现改变了这个局面。当使用嵌入式Servlet容器,我们不再需要任何外部设施的支持,应用程序本身就是一个可以独立运行的个体。作为解放生产力的典型代表,SpringBoot默认采用EmbeddedTomcat来启动Web</div> </li> <li><a href="/article/1765990233331032064.htm" title="Android程序员的Java后台学习建议" target="_blank">Android程序员的Java后台学习建议</a> <span class="text-muted">Androidgiao</span> <div>作为一个原生Android开发,一路走来经历了Java、Kotlin的洗礼;在“原生要凉”的氛围下学习Cordova、ReactNative、Weex、Flutter等跨平台框架;之后又在“大前端”的口号下延伸到React、Vue等前端框架的学习;最终面对“全栈”的诱惑,又撸起了SpringBoot的Javaweb开发。image.pngAndroid开发作为“安身立命”的资本,在面对如今“移动要</div> </li> <li><a href="/article/1759890542428254208.htm" title="java web静态资源分离_JavaWeb静态资源分离思路" target="_blank">java web静态资源分离_JavaWeb静态资源分离思路</a> <span class="text-muted">Mjohfspjt</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/web%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90%E5%88%86%E7%A6%BB/1.htm">web静态资源分离</a> <div>JavaWeb开发过程中我们的静态资源img和css和js等都是放在项目中一起打包到war包里发布到Web服务器tomcat中运行的。如果用户要上传和下载文件的话一般上传文件也是放在tomcat目录或者Web服务器中。但是随着用户上传的文件增多,或者我们的静态资源增加,会消耗Web服务器的性能。所以遇到这种情况时,可以考虑进行静态资源分离。静态资源分离就是把静态资源放到另一台服务器上,web服务器</div> </li> <li><a href="/article/1759814263960072192.htm" title="零基础学JavaWeb开发(十八)之 spring框架(1)" target="_blank">零基础学JavaWeb开发(十八)之 spring框架(1)</a> <span class="text-muted">出世&入世</span> <a class="tag" taget="_blank" href="/search/Java/1.htm">Java</a><a class="tag" taget="_blank" href="/search/JavaWeb/1.htm">JavaWeb</a><a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E4%BB%A3%E7%90%86%E6%A8%A1%E5%BC%8F/1.htm">代理模式</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/web/1.htm">web</a> <div>spring框架1、Spring介绍1.1、Spring概念Spring是一个JavaEE开源的轻量级别的框架,可以解决我们企业开发中遇到的难题,能够让编码变的更加简单,核心组件IOC容器和Aop面向切面编程。1.IOC控制反转:把整个对象创建的过程,统一交给我们SpringIOC容器来实现管理,底层使用反射+工厂模式实现。2.Aop面向切面编程:对我们功能(方法)前后实现增强,比如打印日志、事务</div> </li> <li><a href="/article/1759713710768746496.htm" title="android开发之SQLite数据库 增、删、改、查" target="_blank">android开发之SQLite数据库 增、删、改、查</a> <span class="text-muted">自律给你自由</span> <a class="tag" taget="_blank" href="/search/android%E5%BC%80%E5%8F%91/1.htm">android开发</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E5%BA%93/1.htm">数据库</a><a class="tag" taget="_blank" href="/search/sqlite/1.htm">sqlite</a><a class="tag" taget="_blank" href="/search/android/1.htm">android</a><a class="tag" taget="_blank" href="/search/string/1.htm">string</a><a class="tag" taget="_blank" href="/search/null/1.htm">null</a><a class="tag" taget="_blank" href="/search/insert/1.htm">insert</a> <div>学习android开发不可避免的会涉及数据库的使用,android使用的是SQLite数据库。对于SQLite数据库的基本信息这里就不过多的介绍,我们主要看哈是怎么用的就是了。与以往数据库不一样的地方以前我们做javaWeb开发时用jdbc连接,现在变了,个人觉得变得简单了。在应用程序中直接就可以去创建数据库,然后对其进行操作。不用像以前写连接代码。操作数据库一,SQLiteOpenHelper类</div> </li> <li><a href="/article/1759616611599347712.htm" title="Day01 javaweb开发——tlias员工管理系统" target="_blank">Day01 javaweb开发——tlias员工管理系统</a> <span class="text-muted">临渊羡鱼的猫</span> <a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a><a class="tag" taget="_blank" href="/search/boot/1.htm">boot</a> <div>任务介绍完成部门管理和员工管理的增删改查功能环境搭建前端---->后端---->数据库准备数据库表创建springboot工程(web、mybatis、mysql驱动、lombok)application.properties中引入mybatis配置信息,准备对应的实体类准备三层架构标准代码(controller基础结构、service接口、实现类、mapper)restful开发规范通过URL定</div> </li> <li><a href="/article/1759433524378677248.htm" title="java web 前端开发框架和流程" target="_blank">java web 前端开发框架和流程</a> <span class="text-muted">韩大帅666</span> <a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>1通常JavaWeb开发框架举个例子,对于广告系统的来说,我们先不管一些job,CACHE,config...这些优化,些框架和分层可以是这样的,MVC的技术选型:V:FreeMarkervsJSP/VelocityC:SpringMVCvsStruts/WebworkM:SPRING/JPA/HibernatevsiBatis2前端V的架构前端开发刚兴起的阶段,前端开发人员的工作经常穿插在后端开</div> </li> <li><a href="/article/1756671413055406080.htm" title="Servlet 学习" target="_blank">Servlet 学习</a> <span class="text-muted">黄二的NPE</span> <div>Javaweb项目结构目录前言Javaweb是指用Java开发的web项目。Javaweb开发至今已有两年之久,期间项目都是在框架上开发,比如SpringMVC,对底层知之甚少。大学期间虽然已经走马观花似的学过了Servlet,但是那时候对web开发没有一个整体的概念,很多东西也没有彻底弄明白,而且到现在也遗忘的差不多了。重新开始学习Servlet,能够帮助我们了解web项目的基础,很好的回答“为</div> </li> <li><a href="/article/1755326396843966464.htm" title="Java 服务端参数校验 - JSR 303 介绍及实践" target="_blank">Java 服务端参数校验 - JSR 303 介绍及实践</a> <span class="text-muted">happyJared</span> <div>可以说几乎所有的应用场景中,参数验证都在编写业务逻辑前完成,严格确保进来的数据是合法且符合要求的。JavaWeb开发领域,也早有较为完善的BeanValidation为JavaBean验证定义了相应的元数据模型和API。首先,在项目中引入web模块的依赖:org.springframework.bootspring-boot-starter-webHibernateValidator是BeanVa</div> </li> <li><a href="/article/1755238143247794176.htm" title="19:Web开发模式与MVC设计模式-Java Web" target="_blank">19:Web开发模式与MVC设计模式-Java Web</a> <span class="text-muted">Yeats_Liao</span> <a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/mvc/1.htm">mvc</a><a class="tag" taget="_blank" href="/search/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">设计模式</a> <div>目录19.1JavaWeb开发模式19.2MVC设计模式详解19.3MVC与其他JavaWeb开发模式的区别总结19.4应用场景总结在JavaWeb应用程序开发领域,有效的架构模式和设计模式对提高代码可维护性、模块化以及团队协作至关重要。本文将探讨JavaWeb开发中的常见模式——模型-视图-控制器(Model-View-Controller,MVC)设计模式,并结合实际的前后端代码示例,深度剖析</div> </li> <li><a href="/article/1755014067845611520.htm" title="Maven详细配置整理" target="_blank">Maven详细配置整理</a> <span class="text-muted">kaixin_啊啊</span> <a class="tag" taget="_blank" href="/search/IDEA/1.htm">IDEA</a><a class="tag" taget="_blank" href="/search/%E5%AD%A6%E4%B9%A0/1.htm">学习</a><a class="tag" taget="_blank" href="/search/%E6%95%99%E7%A8%8B/1.htm">教程</a><a class="tag" taget="_blank" href="/search/maven/1.htm">maven</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a> <div>Maven的作用在Javaweb开发中,需要使用大量的jar包,需要手动去导入,Maven能够自动帮我们导入和配置这个jar包。对于新手Maven就是用来方便导入jar包的!Maven的核心思想:约定大于配置有约束,不要去违反。Maven会规定好你该如何去编写我们Java代码,必须要按照这个规范来;Maven的下载安装及环境配置官网:Maven下载对应的压缩包并解压。在我们的系统环境变量中配置如下</div> </li> <li><a href="/article/1754792071589281792.htm" title="18:JavaBean简介及其在表单处理与DAO设计模式中的应用-Java Web" target="_blank">18:JavaBean简介及其在表单处理与DAO设计模式中的应用-Java Web</a> <span class="text-muted">Yeats_Liao</span> <a class="tag" taget="_blank" href="/search/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/1.htm">设计模式</a><a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a> <div>目录18.1JavaBean简介18.2JavaBean与表单处理18.3JavaBean的保存范围18.4JavaBean在DAO设计模式中的应用18.5JavaBean与表单处理的完整代码示例18.6JavaBean在DAO设计模式中的应用示例在JavaWeb开发领域,JavaBean作为数据封装和交互的核心组件,在构建健壮且易于维护的Web应用程序中扮演着重要角色。本文将深入浅出地介绍Jav</div> </li> <li><a href="/article/1754342437242814464.htm" title="SpringBoot: Filter vs HandlerInterceptor ?" target="_blank">SpringBoot: Filter vs HandlerInterceptor ?</a> <span class="text-muted">北鱼扶摇</span> <div>欢迎关注公众号:逻魔代码我们知道,在JavaWeb开发时,若想对请求或响应做出统一的逻辑处理,可以使用过滤器或者拦截器。那么具体什么时候使用过滤器,什么时候使用拦截器呢?在探究这个问题之前,我们先搞清楚,什么是Servlet?Servlet现在我们通常做JavaWeb开发都会用SpringBoot,但要知道SpringBoot只是用来简化开发的,在此之前,Springframework只是一个粘合</div> </li> <li><a href="/article/1754311776951877632.htm" title="2-HTTP-Tomcat-Servlet" target="_blank">2-HTTP-Tomcat-Servlet</a> <span class="text-muted">我是真tm卷啊</span> <a class="tag" taget="_blank" href="/search/JavaWeb/1.htm">JavaWeb</a><a class="tag" taget="_blank" href="/search/servlet/1.htm">servlet</a><a class="tag" taget="_blank" href="/search/tomcat/1.htm">tomcat</a><a class="tag" taget="_blank" href="/search/http/1.htm">http</a> <div>HTTP&Tomcat&Servlet今日目标:了解JavaWeb开发的技术栈理解HTTP协议和HTTP请求与响应数据的格式掌握Tomcat的使用掌握在IDEA中使用Tomcat插件理解Servlet的执行流程和生命周期掌握Servlet的使用和相关配置1,Web概述1.1Web和JavaWeb的概念Web是全球广域网,也称为万维网(www),能够通过浏览器访问的网站。在我们日常的生活中,经常会使</div> </li> <li><a href="/article/1754242024996880384.htm" title="javaweb开发中,ajax有时失效的主要问题" target="_blank">javaweb开发中,ajax有时失效的主要问题</a> <span class="text-muted">yzl495</span> <a class="tag" taget="_blank" href="/search/ajax/1.htm">ajax</a><a class="tag" taget="_blank" href="/search/%E5%89%8D%E7%AB%AF/1.htm">前端</a><a class="tag" taget="_blank" href="/search/javascript/1.htm">javascript</a> <div>在开发中,发现ajax有时候失效,有时候正常返回值,这种情况很可能就是botton按钮执行了默认的submit事件,导致了整个网页刷新,也就是ajax部分刷新的值没有返回来之前,整个页面就刷新了,此时,ajax失败。解决办法:在botton的click事件中使用returnfalse,阻止submit事件,保障ajax的正常运行。$("#btn").click(function(){$.post(</div> </li> <li><a href="/article/1754009180756262912.htm" title="像SpringMVC一样在Android上做Web开发" target="_blank">像SpringMVC一样在Android上做Web开发</a> <span class="text-muted">Java黎先生</span> <div>一部分Android开发者看到这个标题时可能有点疑惑,SpringMVC不是用来做JavaWeb开发的吗?难道被移植到Android上来了?答案是否定的,因为SpringMVC是基于Servlet的,在Android上开发一个支持Servlet的容器(Tomcat、JBoss)可不简单,所以我们是在Android上开发了一套全新的WebServer+WebFramework。AndServer2.</div> </li> <li><a href="/article/48.htm" title="开发者关心的那些事" target="_blank">开发者关心的那些事</a> <span class="text-muted">圣子足道</span> <a class="tag" taget="_blank" href="/search/ios/1.htm">ios</a><a class="tag" taget="_blank" href="/search/%E6%B8%B8%E6%88%8F/1.htm">游戏</a><a class="tag" taget="_blank" href="/search/%E7%BC%96%E7%A8%8B/1.htm">编程</a><a class="tag" taget="_blank" href="/search/apple/1.htm">apple</a><a class="tag" taget="_blank" href="/search/%E6%94%AF%E4%BB%98/1.htm">支付</a> <div>我要在app里添加IAP,必须要注册自己的产品标识符(product identifiers)。产品标识符是什么? 产品标识符(Product Identifiers)是一串字符串,它用来识别你在应用内贩卖的每件商品。App Store用产品标识符来检索产品信息,标识符只能包含大小写字母(A-Z)、数字(0-9)、下划线(-)、以及圆点(.)。你可以任意排列这些元素,但我们建议你创建标识符时使用</div> </li> <li><a href="/article/175.htm" title="负载均衡器技术Nginx和F5的优缺点对比" target="_blank">负载均衡器技术Nginx和F5的优缺点对比</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/nginx/1.htm">nginx</a><a class="tag" taget="_blank" href="/search/F5/1.htm">F5</a> <div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于数据流量过大的网络中,往往单一设备无法承担,需要多台设备进行数据分流,而负载均衡器就是用来将数据分流到多台设备的一个转发器。 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 目前有许多不同的负载均衡技术用以满足不同的应用需求,如软/硬件负载均衡、本地/全局负载均衡、更高</div> </li> <li><a href="/article/302.htm" title="LeetCode[Math] - #9 Palindrome Number" target="_blank">LeetCode[Math] - #9 Palindrome Number</a> <span class="text-muted">Cwind</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/Algorithm/1.htm">Algorithm</a><a class="tag" taget="_blank" href="/search/%E9%A2%98%E8%A7%A3/1.htm">题解</a><a class="tag" taget="_blank" href="/search/LeetCode/1.htm">LeetCode</a><a class="tag" taget="_blank" href="/search/Math/1.htm">Math</a> <div>原题链接:#9 Palindrome Number &nbsp; 要求: 判断一个整数是否是回文数,不要使用额外的存储空间 &nbsp; 难度:简单 &nbsp; 分析: 题目限制不允许使用额外的存储空间应指不允许使用O(n)的内存空间,O(1)的内存用于存储中间结果是可以接受的。于是考虑将该整型数反转,然后与原数字进行比较。 注:没有看到有关负数是否可以是回文数的明确结论,例如</div> </li> <li><a href="/article/429.htm" title="画图板的基本实现" target="_blank">画图板的基本实现</a> <span class="text-muted">15700786134</span> <a class="tag" taget="_blank" href="/search/%E7%94%BB%E5%9B%BE%E6%9D%BF/1.htm">画图板</a> <div>&nbsp;要实现画图板的基本功能,除了在qq登陆界面中用到的组件和方法外,还需要添加鼠标监听器,和接口实现。 首先,需要显示一个JFrame界面: public class DrameFrame extends JFrame {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //显示</div> </li> <li><a href="/article/556.htm" title="linux的ps命令" target="_blank">linux的ps命令</a> <span class="text-muted">被触发</span> <a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a> <div>Linux中的ps命令是Process Status的缩写。ps命令用来列出系统中当前运行的那些进程。ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态的显示进程信息,就可以使用top命令。 要对进程进行监测和控制,首先必须要了解当前进程的情况,也就是需要查看当前进程,而 ps 命令就是最基本同时也是非常强大的进程查看命令。使用该命令可以确定有哪些进程正在运行</div> </li> <li><a href="/article/683.htm" title="Android 音乐播放器 下一曲 连续跳几首歌" target="_blank">Android 音乐播放器 下一曲 连续跳几首歌</a> <span class="text-muted">肆无忌惮_</span> <a class="tag" taget="_blank" href="/search/android/1.htm">android</a> <div>最近在写安卓音乐播放器的时候遇到个问题。在MediaPlayer播放结束时会回调 player.setOnCompletionListener(new OnCompletionListener() { @Override public void onCompletion(MediaPlayer mp) { mp.reset(); Log.i(&quot;H</div> </li> <li><a href="/article/810.htm" title="java导出txt文件的例子" target="_blank">java导出txt文件的例子</a> <span class="text-muted">知了ing</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/servlet/1.htm">servlet</a> <div>代码很简单就一个servlet,如下: package com.eastcom.servlet; import java.io.BufferedOutputStream; import java.io.IOException; import java.net.URLEncoder; import java.sql.Connection; import java.sql.Resu</div> </li> <li><a href="/article/937.htm" title="Scala stack试玩, 提高第三方依赖下载速度" target="_blank">Scala stack试玩, 提高第三方依赖下载速度</a> <span class="text-muted">矮蛋蛋</span> <a class="tag" taget="_blank" href="/search/scala/1.htm">scala</a><a class="tag" taget="_blank" href="/search/sbt/1.htm">sbt</a> <div>原文地址: http://segmentfault.com/a/1190000002894524 sbt下载速度实在是惨不忍睹, 需要做些配置优化 下载typesafe离线包, 保存为ivy本地库 wget http://downloads.typesafe.com/typesafe-activator/1.3.4/typesafe-activator-1.3.4.zip 解压r</div> </li> <li><a href="/article/1064.htm" title="phantomjs安装(linux,附带环境变量设置) ,以及casperjs安装。" target="_blank">phantomjs安装(linux,附带环境变量设置) ,以及casperjs安装。</a> <span class="text-muted">alleni123</span> <a class="tag" taget="_blank" href="/search/linux/1.htm">linux</a><a class="tag" taget="_blank" href="/search/spider/1.htm">spider</a> <div>1. 首先从官网 http://phantomjs.org/下载phantomjs压缩包,解压缩到/root/phantomjs文件夹。 2. 安装依赖 sudo yum install fontconfig freetype libfreetype.so.6 libfontconfig.so.1 libstdc++.so.6 3. 配置环境变量 vi /etc/profil</div> </li> <li><a href="/article/1191.htm" title="JAVA IO FileInputStream和FileOutputStream,字节流的打包输出" target="_blank">JAVA IO FileInputStream和FileOutputStream,字节流的打包输出</a> <span class="text-muted">百合不是茶</span> <a class="tag" taget="_blank" href="/search/java%E6%A0%B8%E5%BF%83%E6%80%9D%E6%83%B3/1.htm">java核心思想</a><a class="tag" taget="_blank" href="/search/JAVA+IO%E6%93%8D%E4%BD%9C/1.htm">JAVA IO操作</a><a class="tag" taget="_blank" href="/search/%E5%AD%97%E8%8A%82%E6%B5%81/1.htm">字节流</a> <div>在程序设计语言中,数据的保存是基本,如果某程序语言不能保存数据那么该语言是不可能存在的,JAVA是当今最流行的面向对象设计语言之一,在保存数据中也有自己独特的一面,字节流和字符流 1,字节流是由字节构成的,字符流是由字符构成的 字节流和字符流都是继承的InputStream和OutPutStream ,java中两种最基本的就是字节流和字符流 &nbsp; 类 FileInputStream</div> </li> <li><a href="/article/1318.htm" title="Spring基础实例(依赖注入和控制反转)" target="_blank">Spring基础实例(依赖注入和控制反转)</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/spring/1.htm">spring</a> <div>前提条件:在http://www.springsource.org/download网站上下载Spring框架,并将spring.jar、log4j-1.2.15.jar、commons-logging.jar加载至工程1.武器接口 package com.bijian.spring.base3; public interface Weapon { void kil</div> </li> <li><a href="/article/1445.htm" title="HR看重的十大技能" target="_blank">HR看重的十大技能</a> <span class="text-muted">bijian1013</span> <a class="tag" taget="_blank" href="/search/%E6%8F%90%E5%8D%87/1.htm">提升</a><a class="tag" taget="_blank" href="/search/%E8%83%BD%E5%8A%9B/1.htm">能力</a><a class="tag" taget="_blank" href="/search/HR/1.htm">HR</a><a class="tag" taget="_blank" href="/search/%E6%88%90%E9%95%BF/1.htm">成长</a> <div>&nbsp; &nbsp; 一个人掌握何种技能取决于他的兴趣、能力和聪明程度,也取决于他所能支配的资源以及制定的事业目标,拥有过硬技能的人有更多的工作机会。但是,由于经济发展前景不确定,掌握对你的事业有所帮助的技能显得尤为重要。以下是最受雇主欢迎的十种技能。&nbsp;  一、解决问题的能力&nbsp;  每天,我们都要在生活和工作中解决一些综合性的问题。那些能够发现问题、解决问题并迅速作出有效决</div> </li> <li><a href="/article/1572.htm" title="【Thrift一】Thrift编译安装" target="_blank">【Thrift一】Thrift编译安装</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/thrift/1.htm">thrift</a> <div>什么是Thrift The Apache Thrift software framework, for scalable cross-language services development, combines a software stack with a code generation engine to build services that work efficiently and s</div> </li> <li><a href="/article/1699.htm" title="【Avro三】Hadoop MapReduce读写Avro文件" target="_blank">【Avro三】Hadoop MapReduce读写Avro文件</a> <span class="text-muted">bit1129</span> <a class="tag" taget="_blank" href="/search/mapreduce/1.htm">mapreduce</a> <div>Avro是Doug Cutting(此人绝对是神一般的存在)牵头开发的。 开发之初就是围绕着完善Hadoop生态系统的数据处理而开展的(使用Avro作为Hadoop MapReduce需要处理数据序列化和反序列化的场景),因此Hadoop MapReduce集成Avro也就是自然而然的事情。 这个例子是一个简单的Hadoop MapReduce读取Avro格式的源文件进行计数统计,然后将计算结果</div> </li> <li><a href="/article/1826.htm" title="nginx定制500,502,503,504页面" target="_blank">nginx定制500,502,503,504页面</a> <span class="text-muted">ronin47</span> <a class="tag" taget="_blank" href="/search/nginx%E3%80%80%E9%94%99%E8%AF%AF%E6%98%BE%E7%A4%BA/1.htm">nginx 错误显示</a> <div>server { listen 80; error_page 500/500.html; error_page 502/502.html; error_page 503/503.html; error_page 504/504.html; location /test {return502;}} 配置很简单,和配</div> </li> <li><a href="/article/1953.htm" title="java-1.二叉查找树转为双向链表" target="_blank">java-1.二叉查找树转为双向链表</a> <span class="text-muted">bylijinnan</span> <a class="tag" taget="_blank" href="/search/%E4%BA%8C%E5%8F%89%E6%9F%A5%E6%89%BE%E6%A0%91/1.htm">二叉查找树</a> <div> import java.util.ArrayList; import java.util.List; public class BSTreeToLinkedList { /* 把二元查找树转变成排序的双向链表 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 要求不能创建任何新的结点,只调整指针的指向。 10 / \ 6 14 / \ </div> </li> <li><a href="/article/2080.htm" title="Netty源码学习-HTTP-tunnel" target="_blank">Netty源码学习-HTTP-tunnel</a> <span class="text-muted">bylijinnan</span> <a class="tag" taget="_blank" href="/search/java/1.htm">java</a><a class="tag" taget="_blank" href="/search/netty/1.htm">netty</a> <div>Netty关于HTTP tunnel的说明: http://docs.jboss.org/netty/3.2/api/org/jboss/netty/channel/socket/http/package-summary.html#package_description 这个说明有点太简略了 一个完整的例子在这里: https://github.com/bylijinnan</div> </li> <li><a href="/article/2207.htm" title="JSONUtil.serialize(map)和JSON.toJSONString(map)的区别" target="_blank">JSONUtil.serialize(map)和JSON.toJSONString(map)的区别</a> <span class="text-muted">coder_xpf</span> <a class="tag" taget="_blank" href="/search/jquery/1.htm">jquery</a><a class="tag" taget="_blank" href="/search/json/1.htm">json</a><a class="tag" taget="_blank" href="/search/map/1.htm">map</a><a class="tag" taget="_blank" href="/search/val%28%29/1.htm">val()</a> <div>&nbsp;JSONUtil.serialize(map)和JSON.toJSONString(map)的区别 &nbsp; 数据库查询出来的map有一个字段为空 &nbsp; 通过System.out.println()输出 JSONUtil.serialize(map): {&quot;one&quot;:&quot;1&quot;,&quot;two&quot;:&quot;nul</div> </li> <li><a href="/article/2334.htm" title="Hibernate缓存总结" target="_blank">Hibernate缓存总结</a> <span class="text-muted">cuishikuan</span> <a class="tag" taget="_blank" href="/search/%E5%BC%80%E6%BA%90/1.htm">开源</a><a class="tag" taget="_blank" href="/search/ssh/1.htm">ssh</a><a class="tag" taget="_blank" href="/search/javaweb/1.htm">javaweb</a><a class="tag" taget="_blank" href="/search/hibernate%E7%BC%93%E5%AD%98/1.htm">hibernate缓存</a><a class="tag" taget="_blank" href="/search/%E4%B8%89%E5%A4%A7%E6%A1%86%E6%9E%B6/1.htm">三大框架</a> <div>一、为什么要用Hibernate缓存? Hibernate是一个持久层框架,经常访问物理数据库。 为了降低应用程序对物理数据源访问的频次,从而提高应用程序的运行性能。 缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据。 &nbsp; 二、Hibernate缓存原理是怎样的? Hibernate缓存包括两大类:Hib</div> </li> <li><a href="/article/2461.htm" title="CentOs6" target="_blank">CentOs6</a> <span class="text-muted">dalan_123</span> <a class="tag" taget="_blank" href="/search/centos/1.htm">centos</a> <div>首先su - 切换到root下面1、首先要先安装GCC GCC-C++ Openssl等以来模块:yum -y install make gcc gcc-c++ kernel-devel m4 ncurses-devel openssl-devel2、再安装ncurses模块yum -y install ncurses-develyum install ncurses-devel3、下载Erang</div> </li> <li><a href="/article/2588.htm" title="10款用 jquery 实现滚动条至页面底端自动加载数据效果" target="_blank">10款用 jquery 实现滚动条至页面底端自动加载数据效果</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/JavaScript/1.htm">JavaScript</a> <div>&nbsp; 无限滚动自动翻页可以说是web2.0时代的一项堪称伟大的技术,它让我们在浏览页面的时候只需要把滚动条拉到网页底部就能自动显示下一页的结果,改变了一直以来只能通过点击下一页来翻页这种常规做法。 无限滚动自动翻页技术的鼻祖是微博的先驱:推特(twitter),后来必应图片搜索、谷歌图片搜索、google&nbsp;reader、箱包批发网等纷纷抄袭了这一项技术,于是靠滚动浏览器滚动条</div> </li> <li><a href="/article/2715.htm" title="ImageButton去边框&Button或者ImageButton的背景透明" target="_blank">ImageButton去边框&Button或者ImageButton的背景透明</a> <span class="text-muted">dcj3sjt126com</span> <a class="tag" taget="_blank" href="/search/imagebutton/1.htm">imagebutton</a> <div>在ImageButton中载入图片后,很多人会觉得有图片周围的白边会影响到美观,其实解决这个问题有两种方法 一种方法是将ImageButton的背景改为所需要的图片。如:android:background=&quot;@drawable/XXX&quot; 第二种方法就是将ImageButton背景改为透明,这个方法更常用 在XML里; &nbsp;&nbsp; &lt;ImageBut</div> </li> <li><a href="/article/2842.htm" title="JSP之c:foreach" target="_blank">JSP之c:foreach</a> <span class="text-muted">eksliang</span> <a class="tag" taget="_blank" href="/search/jsp/1.htm">jsp</a><a class="tag" taget="_blank" href="/search/forearch/1.htm">forearch</a> <div>原文出自:http://www.cnblogs.com/draem0507/archive/2012/09/24/2699745.html &lt;c:forEach&gt;标签用于通用数据循环,它有以下属性 属 性 描 述 是否必须 缺省值 items 进行循环的项目 否 无 begin 开始条件 否 0 end 结束条件 否 集合中的最后一个项目 step 步长 否 1</div> </li> <li><a href="/article/2969.htm" title="Android实现主动连接蓝牙耳机" target="_blank">Android实现主动连接蓝牙耳机</a> <span class="text-muted">gqdy365</span> <a class="tag" taget="_blank" href="/search/android/1.htm">android</a> <div>在Android程序中可以实现自动扫描蓝牙、配对蓝牙、建立数据通道。蓝牙分不同类型,这篇文字只讨论如何与蓝牙耳机连接。 大致可以分三步: 一、扫描蓝牙设备: 1、注册并监听广播: BluetoothAdapter.ACTION_DISCOVERY_STARTED BluetoothDevice.ACTION_FOUND BluetoothAdapter.ACTION_DIS</div> </li> <li><a href="/article/3096.htm" title="android学习轨迹之四:org.json.JSONException: No value for" target="_blank">android学习轨迹之四:org.json.JSONException: No value for</a> <span class="text-muted">hyz301</span> <a class="tag" taget="_blank" href="/search/json/1.htm">json</a> <div>org.json.JSONException: No value for items&nbsp; 在JSON解析中会遇到一种错误,很常见的错误 &nbsp; 06-21 12:19:08.714 2098-2127/com.jikexueyuan.secret I/System.out﹕ Result:{&quot;status&quot;:1,&quot;page&quot;:1,&</div> </li> <li><a href="/article/3223.htm" title="干货分享:从零开始学编程 系列汇总" target="_blank">干货分享:从零开始学编程 系列汇总</a> <span class="text-muted">justjavac</span> <a class="tag" taget="_blank" href="/search/%E7%BC%96%E7%A8%8B/1.htm">编程</a> <div>程序员总爱重新发明轮子,于是做了要给轮子汇总。 从零开始写个编译器吧系列&nbsp;(知乎专栏) 从零开始写一个简单的操作系统&nbsp;(伯乐在线) 从零开始写JavaScript框架&nbsp;(图灵社区) 从零开始写jQuery框架&nbsp;(蓝色理想 ) 从零开始nodejs系列文章&nbsp;(粉丝日志) 从零开始编写网络游戏&nbsp</div> </li> <li><a href="/article/3350.htm" title="jquery-autocomplete 使用手册" target="_blank">jquery-autocomplete 使用手册</a> <span class="text-muted">macroli</span> <a class="tag" taget="_blank" href="/search/jquery/1.htm">jquery</a><a class="tag" taget="_blank" href="/search/Ajax/1.htm">Ajax</a><a class="tag" taget="_blank" href="/search/%E8%84%9A%E6%9C%AC/1.htm">脚本</a> <div>jquery-autocomplete学习 一、用前必备 官方网站:http://bassistance.de/jquery-plugins/jquery-plugin-autocomplete/ 当前版本:1.1 需要JQuery版本:1.2.6 二、使用 &lt;script src=&quot;./jquery-1.3.2.js&quot; type=&quot;text/ja</div> </li> <li><a href="/article/3477.htm" title="PLSQL-Developer或者Navicat等工具连接远程oracle数据库的详细配置以及数据库编码的修改" target="_blank">PLSQL-Developer或者Navicat等工具连接远程oracle数据库的详细配置以及数据库编码的修改</a> <span class="text-muted">超声波</span> <a class="tag" taget="_blank" href="/search/oracle/1.htm">oracle</a><a class="tag" taget="_blank" href="/search/plsql/1.htm">plsql</a> <div>  在服务器上将Oracle安装好之后接下来要做的就是通过本地机器来远程连接服务器端的oracle数据库,常用的客户端连接工具就是PLSQL-Developer或者Navicat这些工具了。刚开始也是各种报错,什么TNS:no listener;TNS:lost connection;TNS:target hosts...花了一天的时间终于让PLSQL-Developer和Navicat等这些客户</div> </li> <li><a href="/article/3604.htm" title="数据仓库数据模型之:极限存储--历史拉链表" target="_blank">数据仓库数据模型之:极限存储--历史拉链表</a> <span class="text-muted">superlxw1234</span> <a class="tag" taget="_blank" href="/search/%E6%9E%81%E9%99%90%E5%AD%98%E5%82%A8/1.htm">极限存储</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E4%BB%93%E5%BA%93/1.htm">数据仓库</a><a class="tag" taget="_blank" href="/search/%E6%95%B0%E6%8D%AE%E6%A8%A1%E5%9E%8B/1.htm">数据模型</a><a class="tag" taget="_blank" href="/search/%E6%8B%89%E9%93%BE%E5%8E%86%E5%8F%B2%E8%A1%A8/1.htm">拉链历史表</a> <div>在数据仓库的数据模型设计过程中,经常会遇到这样的需求: 1. 数据量比较大; 2. 表中的部分字段会被update,如用户的地址,产品的描述信息,订单的状态等等; 3. 需要查看某一个时间点或者时间段的历史快照信息,比如,查看某一个订单在历史某一个时间点的状态, &nbsp;&nbsp; 比如,查看某一个用户在过去某一段时间内,更新过几次等等; 4. 变化的比例和频率不是很大,比如,总共有10</div> </li> <li><a href="/article/3731.htm" title="10点睛Spring MVC4.1-全局异常处理" target="_blank">10点睛Spring MVC4.1-全局异常处理</a> <span class="text-muted">wiselyman</span> <a class="tag" taget="_blank" href="/search/spring+mvc/1.htm">spring mvc</a> <div>10.1 全局异常处理 使用@ControllerAdvice注解来实现全局异常处理; 使用@ControllerAdvice的属性缩小处理范围 10.2 演示 演示控制器 package com.wisely.web; import org.springframework.stereotype.Controller; import org.spring</div> </li> </ul> </div> </div> </div> <div> <div class="container"> <div class="indexes"> <strong>按字母分类:</strong> <a href="/tags/A/1.htm" target="_blank">A</a><a href="/tags/B/1.htm" target="_blank">B</a><a href="/tags/C/1.htm" target="_blank">C</a><a href="/tags/D/1.htm" target="_blank">D</a><a href="/tags/E/1.htm" target="_blank">E</a><a href="/tags/F/1.htm" target="_blank">F</a><a href="/tags/G/1.htm" target="_blank">G</a><a href="/tags/H/1.htm" target="_blank">H</a><a href="/tags/I/1.htm" target="_blank">I</a><a href="/tags/J/1.htm" target="_blank">J</a><a href="/tags/K/1.htm" target="_blank">K</a><a href="/tags/L/1.htm" target="_blank">L</a><a href="/tags/M/1.htm" target="_blank">M</a><a href="/tags/N/1.htm" target="_blank">N</a><a href="/tags/O/1.htm" target="_blank">O</a><a href="/tags/P/1.htm" target="_blank">P</a><a href="/tags/Q/1.htm" target="_blank">Q</a><a href="/tags/R/1.htm" target="_blank">R</a><a href="/tags/S/1.htm" target="_blank">S</a><a href="/tags/T/1.htm" target="_blank">T</a><a href="/tags/U/1.htm" target="_blank">U</a><a href="/tags/V/1.htm" target="_blank">V</a><a href="/tags/W/1.htm" target="_blank">W</a><a href="/tags/X/1.htm" target="_blank">X</a><a href="/tags/Y/1.htm" target="_blank">Y</a><a href="/tags/Z/1.htm" target="_blank">Z</a><a href="/tags/0/1.htm" target="_blank">其他</a> </div> </div> </div> <footer id="footer" class="mb30 mt30"> <div class="container"> <div class="footBglm"> <a target="_blank" href="/">首页</a> - <a target="_blank" href="/custom/about.htm">关于我们</a> - <a target="_blank" href="/search/Java/1.htm">站内搜索</a> - <a target="_blank" href="/sitemap.txt">Sitemap</a> - <a target="_blank" href="/custom/delete.htm">侵权投诉</a> </div> <div class="copyright">版权所有 IT知识库 CopyRight © 2000-2050 E-COM-NET.COM , All Rights Reserved. <!-- <a href="https://beian.miit.gov.cn/" rel="nofollow" target="_blank">京ICP备09083238号</a><br>--> </div> </div> </footer> <!-- 代码高亮 --> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shCore.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shLegacy.js"></script> <script type="text/javascript" src="/static/syntaxhighlighter/scripts/shAutoloader.js"></script> <link type="text/css" rel="stylesheet" href="/static/syntaxhighlighter/styles/shCoreDefault.css"/> <script type="text/javascript" src="/static/syntaxhighlighter/src/my_start_1.js"></script> </body> </html>