精华内容
下载资源
问答
  • java知识总结

    2015-01-14 10:08:12
    通过对java的初步学习,对java知识总结
  • JAVA知识总结

    2018-03-29 20:41:33
    JAVA程序猿心得。。。。
    JAVA程序猿心得。。。。
    展开全文
  • Java知识总结

    千次阅读 2014-05-18 00:29:20
    一、 java开发工具Editplus:Editplus与jdk的连接配置,如: javac(编译)、java(运行)、javap(查看字节码) a) 配置内容: i. javac(编译):参数为 -d . $(FileName);初始目录 $(FileDir) ii. 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<s.length;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<toIndex; 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<E> extends Iterable

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

    List<E>  extends Collection<E>----------有序的Collection,

    可重复

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

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

    AbstractList<E> extends AbstractCollection<E> implements

    List<E>

    Set<E>
    无序的不可重复的Collection

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

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

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

    public class Demo{
    public static void main(String[] args) {
    List<Object> alist = new ArrayList<Object>();//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<alist.size();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<Integer> alist1 = new ArrayList<Integer>();
    int size = alist.size();
    System.out.println(" size="+size);
    boolean flag = alist.isEmpty();//判断是否为空
    System.out.println(" flag="+flag);
    System.out.println("------------------------------");
    //第三种:Iterable-----迭代器输出
    //Iterable Iterator<T>iterator();
    Iterator<Object> 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<alist.size();i++){//注意:size()是动态变化


    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<Integer> link = new LinkedList<Integer>();
    //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<Object> dl = new LinkedList<Object>();
    //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<T> 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<T>接口,并实现compareTo( T t){ ----重写

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

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

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

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

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

    ("--------------------------------------");
    */
    Set<Cat> set=new TreeSet<Cat>();
    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<Cat>{
    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 <A> {
      public int compareTo( A that);
    }
    final class NumericValue implements Comparable

    <NumericValue> {
      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 extends Comparable<A>>A max(Collection

    <A> xs) {
        Iterator <A> 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 <NumericValue> numberList = new LinkedList

    <NumericValue> ();
        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>擦除后 A被替换为最左边界Object

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

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

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

    Comparable<A>,然后去掉参数类型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<String> sl = new ArrayList<String>();
    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<files.length;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

    <!DOCTYPE>  定义文档类型。
    <html> 定义 HTML 文档。
    <body> 定义文档的主体。
    <h1> to <h6> 定义 HTML 标题。
    <p> 定义段落。
    <br> 定义简单的折行。
    <hr> 定义水平线。
    <!--...--> 定义注释。

    <b> 定义粗体文本。
    <font> 不赞成使用。定义文本的字体、尺寸和颜色
    <i> 定义斜体文本。
    <em> 定义强调文本。
    <big> 定义大号文本。
    <strong> 定义语气更为强烈的强调文本。
    <small> 定义小号文本。
    <sup> 定义上标文本。
    <sub> 定义下标文本。
    <bdo> 定义文本的方向。
    <u> 不赞成使用。定义下划线文本。

    <pre> 定义预格式文本
    <code> 定义计算机代码文本。
    <tt> 定义打字机文本。
    <kbd> 定义键盘文本。
    <var> 定义文本的变量部分。
    <dfn> 定义定义项目。
    <samp> 定义计算机代码样本。
    <xmp> 不赞成使用。定义预格式文本。  

    <acronym> 定义只取首字母的缩写。
    <abbr> 定义缩写。
    <address> 定义文档作者或拥有者的联系信息。
    <blockquote> 定义块引用。
    <center> 不赞成使用。定义居中文本。
    <q> 定义短的引用。
    <cite> 定义引用(citation)。
    <ins> 定义被插入文本。
    <del> 定义被删除文本。
    <s> 不赞成使用。定义加删除线的文本。
    <strike> 不赞成使用。定义加删除线的文本。

    <a> 定义锚。
    <link> 定义文档与外部资源的关系。

    <frame> 定义框架集的窗口或框架。
    <frameset> 定义框架集。
    <noframes> 定义针对不支持框架的用户的替代内容。
    <iframe> 定义内联框架。

    <form> 定义供用户输入的 HTML 表单。
    <input> 定义输入控件。
    <textarea> 定义多行的文本输入控件。
    <button> 定义按钮。
    <select> 定义选择列表(下拉列表)。
    <optgroup> 定义选择列表中相关选项的组合。
    <option> 定义选择列表中的选项。
    <label> 定义 input 元素的标注。
    <fieldset> 定义围绕表单中元素的边框。
    <legend> 定义 fieldset 元素的标题。
    <isindex> 不赞成使用。定义与文档相关的可搜索索引。

    <ul> 定义无序列表。
    <ol> 定义有序列表。
    <li> 定义列表的项目。
    <dir> 不赞成使用。定义目录列表。
    <dl> 定义定义列表。
    <dt> 定义定义列表中的项目。
    <dd> 定义定义列表中项目的描述。
    <menu> 不赞成使用。定义菜单列表。

    <img> 定义图像。
    <map> 定义图像映射。
    <area> 定义图像地图内部的区域。

    <table> 定义表格
    <caption> 定义表格标题。
    <th> 定义表格中的表头单元格。
    <tr> 定义表格中的行。
    <td> 定义表格中的单元。
    <thead> 定义表格中的表头内容。
    <tbody> 定义表格中的主体内容。
    <tfoot> 定义表格中的表注内容(脚注)。
    <col> 定义表格中一个或多个列的属性值。
    <colgroup> 定义表格中供格式化的列组。

    <style> 定义文档的样式信息。
    <div> 定义文档中的节。
    <span> 定义文档中的节。

    <head> 定义关于文档的信息。
    <title> 定义文档的标题。
    <meta> 定义关于 HTML 文档的元信息。
    <base> 定义页面中所有链接的默认地址或默认目标。
    <basefont> 不赞成使用。定义页面中文本的默认字体、颜色或尺

    寸。

    <script> 定义客户端脚本。
    <noscript> 定义针对不支持客户端脚本的用户的替代内容。
    <applet> 不赞成使用。定义嵌入的 applet。
    <object> 定义嵌入的对象。
    <param> 定义对象的参数。


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

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

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

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

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

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

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

                                                              

                                  
    六、CSS

    CSS 背景属性(Background)
    属性 描述 CSS
    background 在一个声明中设置所有的背景属性。 1
    background-attachment 设置背景图像是否固定或者随着页面的

    其余部分滚动。 1
    background-color 设置元素的背景颜色。 1
    background-image 设置元素的背景图像。 1
    background-position 设置背景图像的开始位置。 1
    background-repeat 设置是否及如何重复背景图像。 1

    CSS 边框属性(Border 和 Outline)
    属性 描述 CSS
    border 在一个声明中设置所有的边框属性。 1
    border-bottom 在一个声明中设置所有的下边框属性。 1
    border-bottom-color 设置下边框的颜色。 2
    border-bottom-style 设置下边框的样式。 2
    border-bottom-width 设置下边框的宽度。 1
    border-color 设置四条边框的颜色。 1
    border-left 在一个声明中设置所有的左边框属性。 1
    border-left-color 设置左边框的颜色。 2
    border-left-style 设置左边框的样式。 2
    border-left-width 设置左边框的宽度。 1
    border-right 在一个声明中设置所有的右边框属性。 1
    border-right-color 设置右边框的颜色。 2
    border-right-style 设置右边框的样式。 2
    border-right-width 设置右边框的宽度。 1
    border-style 设置四条边框的样式。 1
    border-top 在一个声明中设置所有的上边框属性。 1
    border-top-color 设置上边框的颜色。 2
    border-top-style 设置上边框的样式。 2
    border-top-width 设置上边框的宽度。 1
    border-width 设置四条边框的宽度。 1
    outline 在一个声明中设置所有的轮廓属性。 2
    outline-color 设置轮廓的颜色。 2
    outline-style 设置轮廓的样式。 2
    outline-width 设置轮廓的宽度。 2

    CSS 文本属性(Text)
    属性 描述 CSS
    color 设置文本的颜色。 1
    direction 规定文本的方向 / 书写方向。 2
    letter-spacing 设置字符间距。 1
    line-height 设置行高。 1
    text-align 规定文本的水平对齐方式。 1
    text-decoration 规定添加到文本的装饰效果。 1
    text-indent 规定文本块首行的缩进。 1
    text-shadow 规定添加到文本的阴影效果。 2
    text-transform 控制文本的大小写。 1
    unicode-bidi 设置文本方向。 2
    white-space 规定如何处理元素中的空白。 1
    word-spacing 设置单词间距。 1

    CSS 字体属性(Font)
    属性 描述 CSS
    font 在一个声明中设置所有字体属性。 1
    font-family 规定文本的字体系列。 1
    font-size 规定文本的字体尺寸。 1
    font-size-adjust 为元素规定 aspect 值。 2
    font-stretch 收缩或拉伸当前的字体系列。 2
    font-style 规定文本的字体样式。 1
    font-variant 规定是否以小型大写字母的字体显示文本。 1
    font-weight 规定字体的粗细。 1

    CSS 外边距属性(Margin)
    属性 描述 CSS
    margin 在一个声明中设置所有外边距属性。 1
    margin-bottom 设置元素的下外边距。 1
    margin-left 设置元素的左外边距。 1
    margin-right 设置元素的右外边距。 1
    margin-top 设置元素的上外边距。 1

    CSS 内边距属性(Padding)
    属性 描述 CSS
    padding 在一个声明中设置所有内边距属性。 1
    padding-bottom 设置元素的下内边距。 1
    padding-left 设置元素的左内边距。 1
    padding-right 设置元素的右内边距。 1
    padding-top 设置元素的上内边距。 1

    CSS 列表属性(List)
    属性 描述 CSS
    list-style 在一个声明中设置所有的列表属性。 1
    list-style-image 将图象设置为列表项标记。 1
    list-style-position 设置列表项标记的放置位置。 1
    list-style-type 设置列表项标记的类型。 1
    marker-offset   2

    内容生成(Generated Content)
    属性 描述 CSS
    content 与 :before 以及 :after 伪元素配合使用,来插入生成

    内容。 2
    counter-increment 递增或递减一个或多个计数器。 2
    counter-reset 创建或重置一个或多个计数器。 2
    quotes 设置嵌套引用的引号类型。 2
    CSS 尺寸属性(Dimension)

    属性 描述 CSS
    height 设置元素高度。 1
    max-height 设置元素的最大高度。 2
    max-width 设置元素的最大宽度。 2
    min-height 设置元素的最小高度。 2
    min-width 设置元素的最小宽度。 2
    width 设置元素的宽度。 1

    CSS 定位属性(Positioning)
    属性 描述 CSS
    bottom 设置定位元素下外边距边界与其包含块下边界之间的偏移

    。 2
    clear 规定元素的哪一侧不允许其他浮动元素。 1
    clip 剪裁绝对定位元素。 2
    cursor 规定要显示的光标的类型(形状)。 2
    display 规定元素应该生成的框的类型。 1
    float 规定框是否应该浮动。 1
    left 设置定位元素左外边距边界与其包含块左边界之间的偏移。

    2
    overflow 规定当内容溢出元素框时发生的事情。 2
    position 规定元素的定位类型。 2
    right 设置定位元素右外边距边界与其包含块右边界之间的偏移

    。 2
    top 设置定位元素的上外边距边界与其包含块上边界之间的偏移

    。 2
    vertical-align 设置元素的垂直对齐方式。 1
    visibility 规定元素是否可见。 2
    z-index 设置元素的堆叠顺序。 2

    CSS 打印属性(Print)
    属性 描述 CSS
    orphans 设置当元素内部发生分页时必须在页面底部保留的最少

    行数。 2
    page-break-after 设置元素后的分页行为。 2
    page-break-before 设置元素前的分页行为。 2
    page-break-inside 设置元素内部的分页行为。 2
    widows 设置当元素内部发生分页时必须在页面顶部保留的最少行

    数。 2

    CSS 表格属性(Table)
    属性 描述 CSS
    border-collapse 规定是否合并表格边框。 2
    border-spacing 规定相邻单元格边框之间的距离。 2
    caption-side 规定表格标题的位置。 2
    empty-cells 规定是否显示表格中的空单元格上的边框和背景。

    2
    table-layout 设置用于表格的布局算法。 2

    CSS 伪类(Pseudo-classes)
    属性 描述 CSS
    :active 向被激活的元素添加样式。 1
    :focus 向拥有键盘输入焦点的元素添加样式。 2
    :hover 当鼠标悬浮在元素上方时,向元素添加样式。 1
    :link 向未被访问的链接添加样式。 1
    :visited 向已被访问的链接添加样式。 1
    :first-child 向元素的第一个子元素添加样式。 2
    :lang 向带有指定 lang 属性的元素添加样式。 2

    CSS 伪元素(Pseudo elements)
    属性 描述 CSS
    :first-letter 向文本的第一个字母添加特殊样式。 1
    :first-line 向文本的首行添加特殊样式。 1
    :before 在元素之前添加内容。 2
    :after 在元素之后添加内容。 2


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

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

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

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

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

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

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

                                                              

                                  

    JDK1.5新特性:

    七、枚举
    枚举是一个类类型,是JDK1.5的新特性

    枚举的关键字是enum

    Java中所有的枚举类都是java.lang.Enum的子类

    注意:枚举类中可以包含成员有【字段(常量)、方法(构造方

    法、普通方法)】

    枚举中不能有number;不能赋值------------类

     只有顺序可以比较-----------

    语法:

    enum 枚举名{

             枚举体

    }

    例:

    enum Direction{//枚举体

             EAST,SOUTH,WEST,NORTH//后面可以有分号也可以没有

    }

    调用:枚举名.成员

    枚举名 name =枚举名.成员;

    Direction dir = Direction.EAST;

     

    Enum的方法使用:

    Javap---------------查看字节码文件


    代码:

    enum Direction{

    EAST('e'),SOUTH('s'),NORTH('n'),WEST('w');

        protected char a;

    private Direction(char a){

    this.a = a;

    }

    public String toString(){

    return a+"";

    }

    }

    字节码:


    ---------- javap ----------

    Compiled from "Direction.java"

    final class Direction extends java.lang.Enum<Direction>

    {//不能被实例化

      public static final Direction EAST;

      public static final Direction SOUTH;

      public static final Direction NORTH;

      public static final Direction WEST;

      protected char a;//默认是private,但可以使用4P

      public static Direction[] values();//默认方法,用来遍历

    打印枚举成员

      public static Direction valueOf(java.lang.String);

      public java.lang.String toString();

      static {};//静态初始化块

    }

    由上面可以知道枚举继承java.lang.Enum类,参数的默认修饰符

    public static final,在枚举中可以使用4p



    public enum A{BLUE,RED,BLACK};//声明并定义一个枚举,初始

    化为。。。

    在一个类中定义一个enum成员,enum默认是静态的-------------

    相当于类变量



    枚举的用法

    一、常量-----------枚举出来之前都是通过接口

    在JDK1.5 之前,我们定义常量都是: public static fianl,现

    在可以把相关的常量分组到一个枚举类型里,例:

    public enum Color {

      RED, GREEN, BLANK, YELLOW

    }

    二、Switch

    JDK1.5之后的switch语句支持Byte,short,int,char,enum类型

    ,使用枚举,能让我们的代码可读性更强,JDK1.7之后开始支持

    String类型,例:

    enum Signal {

             GREEN, YELLOW, RED

    }

    public class TrafficLight {

             Signal color = Signal.RED;

             public void change() {

                       switch (color) {

                       case RED:

                                color = Signal.GREEN;

                                break;

                       case YELLOW:

                                color = Signal.RED;

                                break;

                       case GREEN:

                                color = Signal.YELLOW;

                                break;

                       }

             }

    }

    三、向枚举中添加新方法

    要自定义方法,必须在enum实例序列的最后添加一个分号。而且

    Java 要求必须先定义 enum实例,例:

    public enum Color {

             RED("红色", 1), GREEN("绿色", 2), BLANK("白色",

    3), YELLO("黄色", 4);

             // 成员变量

             private String name;

             private int index;

             // 构造方法

             private Color(String name, int index) {

                       this.name = name;

                       this.index = index;

             }

             // 普通方法

             public static String getName(int index) {

                       for (Color c : Color.values()) {

                                if (c.getIndex() == index) {

                                         return c.name;

                                }

                       }

                       return null;

             }

             // get set 方法

             public String getName() {

                       return name;

             }

             public void setName(String name) {

                       this.name = name;

             }

             public int getIndex() {

                       return index;

             }

             public void setIndex(int index) {

                       this.index = index;

             }

    }

    四、覆盖枚举的方法

    例如覆盖toString()

    public enum Color {

             RED("红色", 1), GREEN("绿色", 2), BLANK("白色",

    3), YELLO("黄色", 4);

             // 成员变量

             private String name;

             private int index;

             // 构造方法

             private Color(String name, int index) {

                       this.name = name;

                       this.index = index;

             }

             //覆盖方法

             @Override

             public String toString() {

                       return this.index+"_"+this.name;

             }

    }

    五、实现接口------所有的枚举都继承自java.lang.Enum类。由

    于Java 不支持多继承,所以枚举对象不能再继承其他类,例:

    public interface Behaviour {

             void print();

             String getInfo();

    }

    public enum Color implements Behaviour{

             RED("红色", 1), GREEN("绿色", 2), BLANK("白色",

    3), YELLO("黄色", 4);

             // 成员变量

             private String name;

             private int index;

             // 构造方法

             private Color(String name, int index) {

                       this.name = name;

                       this.index = index;

             }

    //接口方法

             @Override

             public String getInfo() {

                       return this.name;

             }

             //接口方法

             @Override

             public void print() {

                       System.out.println(this.index

    +":"+this.name);

             }

    }

    六、使用接口组织枚举

    public interface Food {

             enum Coffee implements Food{

                       

    BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO

             }

             enum Dessert implements Food{

                       FRUIT, CAKE, GELATO

             }

    }

    七、枚举集合

    java.util.EnumSet和java.util.EnumMap是两个枚举集合。

    EnumSet保证集合中的元素不重复;EnumMap中的key是enum类型,

    而value则可以是任意类型。



    枚举和普通类的区别与联系;

    1、枚举与类都可以实现多接口;访问控制符都可以使用(4p),

    但枚举中默认的是private,类中默认的是package;

    2、枚举直接继承java.lang.Enum类,普通类是继承

    java.lang.Object;其中java.long.Enum类实现了

    java.long.Serializable和java.long.Comparable两个接口。

    3、使用enum定义、非抽象的枚举默认修饰符为public final,因

    此枚举不能派生子类。
    4、枚举的构造器只能使用private访问控制符,如果省略了枚举

    的访问修饰符其默认为private修饰;因为枚举的字段不能初始化

    ,对象类型的必须调用构造方法,所有有多少个成员构造方法就

    会运行多少次;
    5、枚举的所有实例必须在枚举的第一行显示列出,否则这个枚举

    永远都不能生产实例,列出这些实例时系统会自动添加public

    static final修饰,无需程序员显式添加

    6、所有的枚举类都提供了一个values方法,该方法可以很方便的

    遍历所有的枚举值

    7、关键字:枚举是enum,类是class

    8、枚举是类类型,类是引用类型


    instanceof关键字:
    public class FX {
    public static void main(String[] args) {
    boolean b = ("1" instanceof String);//判断某个对象是不是

    某个类的实例    Result = Object instanceof

    Class/interface
    //Result:布尔类型。
       //Object:必选项。任意对象表达式。
    //Class:必选项。任意已定义的对象类。
    System.out.println(b);
    }
    }


    注解---JDK1.5的新特性
    使用位置:类上、方法上、语句上

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

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

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

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

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

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

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


    八、协变与泛型
    协变-------可以用在数组、重写,不可以用在枚举中

    可变参数:

    int… a-------------代表一个没有长度限制的数组----------

    JDK1.5之后有的

    输入的必须是数组

    Java1.5增加了新特性:可变参数:适用于参数个数不确定,类型

    确定的情况,java把可变参数当做数组处理。注意:可变参数必

    须位于最后一项。只支持有一个可变参数。因为参数个数不定,

    所以当其后边还有相同类型参数时,java无法区分传入的参数属

    于前一个可变参数还是后边的参数,所以只能让可变参数位于最

    后一项。

    可变参数的特点:

    (1)、只能出现在参数列表的最后;

    (2)、... 位于变量类型和变量名之间,前后有无空格都可以;

    (3)、调用可变参数的方法时,编译器为该可变参数隐含创建一

    个数组,在方法体中以数组的形式访问可变参数。例:

    public class Varable {
         public static void main(String [] args){
             System.out.println(add(2,3));
             System.out.println(add(2,3,5));
         }
         public static int add(int x,int ...args){
             int sum=x;
             for(int i=0;i<args.length;i++){
                 sum+=args[i];
             }
             return sum;
         }
    }

     协变的作用范围

    1、数组:如果 A 是 B 的超类,则 A[] 也是 B[] 的超类,所有

    需要 A[] 的地方都可以用 B[] 代替,例:

    public class Test2 {

        public static void main(String[] args){

            Integer[] ints=new Integer[1];

            ints[0]=99;

            show(ints);

        }

        static void show(Number[] ns){

            System.out.println(Arrays.toString(ns));

        }

    }

     

    2、重写

    public class Test2 {

        public static void main(String[] args){

            P p=new C();

            System.out.println(p.get());

        }

    }

    class P{

        public Number get(){

            return new Integer(0);

        }

    }

    class C extends P{

        public Integer get(){

            return new Integer(1);

        }

    }

    3、泛型不能协变:如果 A 是 B 的超类,则 List<A> 和

    List<B> 无关,需要 List<A> 的地方不可以用 List<B> 代替,

    例:

    public class Test2 {

        public static void main(String[] args) {

            List<Integer> ints = new ArrayList<Integer>();

            //incompatible type--类型不兼容

            show(ints);

        }

     

        static void show(List<Number> ns) {

            System.out.println(ns);

        }

    }


    泛型(Generic)的本质是类型参数化

    -------------是JDK1.5提供的新技术,它的本质是类型参数化,

    类似C++中的模板,它根据应用主要分为泛型方法,泛型接口,泛

    型类,协变不适用于泛型

     

    泛型-------------泛型类class Demo<T>{},泛型接口interface

    Inter<T>{},泛型方法public<T> T show(T a) {}

    泛型的好处是在编译的时候检查类型安全,并且所有的强制转换

    都是自动和隐式的,提高代码的重用率

     

    例1:

    public class  GenericDemo{

           public static void main(String[] args) {

                  C c1 = new C(new A("aaa"));

                  C c2 = new C(new B(3.4));//包装成double---

    自动装箱

                  Object obj = c1.getObj();

                  A obj = (A)(c1.getObj());//强制转换

                  System.out.println(obj);

           }

    }

    class A{

           private String x;

           public A(String x){

                  this.x=x;

           }

           public String getX(){

                  return x;

           }

    }

    class B{

           private Double d;

           public B(Double d){

                  this.d=d ;

           }

           public Double getD(){

                  return d;

           }

    }

    class C{

           private Object obj;

           public C(Object obj){

                  this.obj=obj ;

           }

           public Object  getObj(){

                  return obj;

           }

    }

     

    泛型的使用:

    一、泛型类:

    public class Demo1 {

           public static void main(String[] args) {

                  Generic<String> c = new Generic<String>

    ("asad");

                  System.out.println(c.getA());

     

                  //Generic<int> c1 = new Generic<int>(12);必

    须要是包装类

           }

    }

    class Generic<T>{//泛型类

           private T a;

           public Generic(T a){

                  this.a = a;

           }

           public T getA(){

                  return a;

           }

    }

     

    二、泛型方法

           public static <T> T getX(T t){//泛型方

    法----------<  >--表声明

                  return t;

           }

          

    public static <T,K> T getX(K t){//泛型方法

                  return t;

           }

     

    三、泛型接口

    public class GenericDemo3{

    public static void main(String[] args) {

    D<int[][]> d = new D<int[][]>();

    d.show(new int[][]{{1,4},{2,3}});

    }

    }

    interface IA<T>{

    void show(T t);

    }



    class D<T> implements IA<T>{

    public void show(T t){

    System.out.println(t.getClass().getName());

    }

    }

     

     

    有界类型:

    上界:extends 默认上界为Object

    Class G <T extends Number,K extends Object,H super

    Integer>{}

    下界:super----------只有通配符有下限

    extends关键字声明了类型的上界,表示参数化的类型可能是所指

    定的类型,或者是此类型的子类

    super关键字声明了类型的下界,表示参数化的类型可能是所指定

    的类型,或者是此类型的父类型,直至Object

     

    规则和限制

    1、泛型的类型参数只能是类类型(包括自定义类),不能是简单

    类型。

    2、同一种泛型可以对应多个版本(因为参数类型是不确定的),

    不同版本的泛型类实例是不兼容的。

    3、泛型的类型参数可以有多个。<T,K>

    4、泛型的参数类型可以使用extends关键字,例如<T extends

    superclass>。习惯上称为“有界类型”。

    5、泛型的参数类型还可以是通配符类型。例如Class<?>

    classType = Class.forName("java.lang.String")

    6、如果只指定了<?>,而没有extends,则默认是允许Object及其

    下的任何Java类了。也就是任意类。

    7、通配符泛型不但可以向下限制,如<? extends Collection>,

    还可以向上限制,如<? super Double>,表示类型只能接受

    Double及其上层父类类型,如Number、Object类型的实例。

    8、泛型类定义可以有多个泛型参数,中间用逗号隔开,还可以定

    义泛型接口,泛型方法。这些都与泛型类中泛型的使用规则类似



    一个普通static方法,无法访问泛型类的类型参数,所以,若普

    通static方法需要使用泛型参数,必须使其成为泛型方法。

     

     

    java 泛型详解

    普通泛型

    Java代码

    1.  class Point<T>{       // 此处可以随便写标识符号  

    2.      private T var ; // var的类型由T指定,即:由外部指

    定  

    3.      public T getVar(){  // 返回值的类型由外部决定  

    4.          return var ;  

    5.      }  

    6.      public void setVar(T var){  // 设置的类型也由外部

    决定  

    7.          this.var = var ;  

    8.      }  

    9.  }  

    10. public class GenericsDemo06{  

    11.     public static void main(String[] args){

    12.         Point<String> p = new Point<String>() ; // 里

    面的var类型为String类型  --------指定数据类型—必须是引用

    数据类型

    13.         p.setVar("it") ;        // 设置字符串  

    14.         System.out.println(p.getVar().length()) ;   

    // 取得字符串的长度  

    15.     }  

    16. }

    17. //2

    18.

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

    -  

    19. class Notepad<K,V>{       // 此处指定了两个泛型类

    型-----再类上进行声明泛型类型  

    20.     private K key ;     // 此变量的类型由外部决定  

    21.     private V value ;   // 此变量的类型由外部决定  

    22.     public K getKey(){  

    23.         return this.key ;  

    24.     }  

    25.     public V getValue(){  

    26.         return this.value ;  

    27.     }  

    28.     public void setKey(K key){  

    29.         this.key = key ;  

    30.     }  

    31.     public void setValue(V value){  

    32.         this.value = value ;  

    33.     }  

    34. }  

    35. public class GenericsDemo09{  

    36.     public static void main(String args[]){  

    37.         Notepad<String,Integer> t = null ;        //

    定义两个泛型类型的对象  

    38.         t = new Notepad<String,Integer>() ;       //

    里面的key为String,value为Integer  

    39.         t.setKey("汤姆") ;        // 设置第一个内容  

    40.         t.setValue(20) ;            // 设置第二个内容

     

    41.         System.out.print("姓名;" + t.getKey()) ;     

     // 取得信息  

    42.         System.out.print(",年龄;" + t.getValue()) ;

          // 取得信息  

    43.       }  

    44. }  //汤姆

    45.       20

     通配符

    Java代码

    1.  class Info<T>{  

    2.      private T var ;     // 定义泛型变量  

    3.      public void setVar(T var){  

    4.          this.var = var ;  

    5.      }  

    6.      public T getVar(){  

    7.          return this.var ;  

    8.      }  

    9.      public String toString(){   // 直接打印  

    10.         return this.var.toString() ;  

    11.     }  

    12. }

    13. public class GenericsDemo14{  

    14.     public static void main(String args[]){  

    15.         Info<String> i = new Info<String>() ;       

    // 使用String为泛型类型  

    16.         i.setVar("it") ;                            

    // 设置内容  

    17.         fun(i) ;  

    18.     }  

    19.     public static void fun(Info<?> temp){     // 可以

    接收任意的泛型对象  

    20.         System.out.println("内容:" + temp) ;  

    21.     }  

    22. }//  内容:it

     受限泛型

    Java代码

    1.  class Info<T>{  

    2.      private T var ;     // 定义泛型变量  

    3.      public void setVar(T var){  

    4.          this.var = var ;  

    5.      }  

    6.      public T getVar(){  

    7.          return this.var ;  

    8.      }  

    9.      public String toString(){   // 直接打印  

    10.         return this.var.toString() ;  

    11.     }  

    12. }  

    13. public class GenericsDemo17{  

    14.     public static void main(String args[]){  

    15.         Info<Integer> i1 = new Info<Integer>() ;   //

    声明Integer的泛型对象  

    16.         Info<Float> i2 = new Info<Float>() ;         

    // 声明Float的泛型对象  

    17.         i1.setVar(30) ;                              

    // 设置整数,自动装箱  

    18.         i2.setVar(30.1f) ;                           

    // 设置小数,自动装箱  

    19.         fun(i1) ;  

    20.         fun(i2) ;  

    21.     }  

    22.     public static void fun(Info<? extends Number>

    temp){ // 只能接收Number及其Number的子类  

    23.         System.out.print(temp + "、") ;  

    24.     }  

    25. }//  30、30.1、

    26.

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

    -  

    27. class Info<T>{  

    28.     private T var ;     // 定义泛型变量  

    29.     public void setVar(T var){  

    30.         this.var = var ;  

    31.     }  

    32.     public T getVar(){  

    33.         return this.var ;  

    34.     }  

    35.     public String toString(){   // 直接打印  

    36.         return this.var.toString() ;  

    37.     }  

    38. }  

    39. public class GenericsDemo21{  

    40.     public static void main(String args[]){  

    41.         Info<String> i1 = new Info<String>() ;      

    // 声明String的泛型对象  

    42.         Info<Object> i2 = new Info<Object>() ;      

    // 声明Object的泛型对象  

    43.         i1.setVar("hello") ;  

    44.         i2.setVar(new Object()) ;  

    45.         fun(i1) ;  

    46.         fun(i2) ;  

    47.     }  

    48.     public static void fun(Info<? super String>

    temp){   // 只能接收String或Object类型的泛型  ----上限为

    String

    49.         System.out.print(temp + "、") ;  

    50.     }  

    51. }//  hello、java.lang.Object@1ffc686、

     泛型无法向上转型

    Java代码

    1.  class Info<T>{  

    2.      private T var ;     // 定义泛型变量  

    3.      public void setVar(T var){  

    4.          this.var = var ;  

    5.      }  

    6.      public T getVar(){  

    7.          return this.var ;  

    8.      }  

    9.      public String toString(){   // 直接打印  

    10.         return this.var.toString() ;  

    11.     }  

    12. }  

    13. public class GenericsDemo23{  

    14.     public static void main(String args[]){  

    15.         Info<String> i1 = new Info<String>() ;      

    // 泛型类型为String  

    16.         Info<Object> i2 = null ;  

    17.         i2 = i1 ;                           //这句会

    出错 incompatible types  

    18.     }  

    19. }//  编译失败

     泛型接口

    Java代码

    1.  interface Info<T>{        // 在接口上定义泛型  

    2.      public T getVar() ; // 定义抽象方法,抽象方法的返

    回值就是泛型类型  

    3.  }  

    4.  class InfoImpl<T> implements Info<T>{   // 定义泛型接

    口的子类  

    5.      private T var ;             // 定义属性  

    6.      public InfoImpl(T var){     // 通过构造方法设置属

    性内容  

    7.          this.setVar(var) ;    

    8.      }  

    9.      public void setVar(T var){  

    10.         this.var = var ;  

    11.     }  

    12.     public T getVar(){  

    13.         return this.var ;  

    14.     }  

    15. }  

    16. public class GenericsDemo24{  

    17.     public static void main(String arsg[]){  

    18.         Info<String> i = null;        // 声明接口对象

     

    19.         i = new InfoImpl<String>("汤姆") ;  // 通过子

    类实例化对象  

    20.         System.out.println("内容:" + i.getVar()) ;  

    21.     }  

    22. }//  内容:汤姆

     泛型方法

    Java代码

    1.  class Demo{  

    2.      public <T> T fun(T t){            // 可以接收任意

    类型的数据  

    3.          return t ;                  // 直接把参数返回

     

    4.      }  

    5.  }  

    6.  public class GenericsDemo26{  

    7.      public static void main(String args[]){  

    8.          Demo d = new Demo() ;   // 实例化Demo对象  

    9.          String str = d.fun("汤姆") ; //   传递字符串  

    10.         int i = d.fun(30) ;     // 传递数字,自动装箱

     

    11.         System.out.println(str) ;   // 输出内容  

    12.         System.out.println(i) ;     // 输出内容  

    13.     }  

    14. }//  汤姆  30

     通过泛型方法返回泛型类型实例

    Java代码

    1.  class Info<T extends Number>{ // 指定上限,只能是数字

    类型  

    2.      private T var ;     // 此类型由外部决定  

    3.      public T getVar(){  

    4.          return this.var ;     

    5.      }  

    6.      public void setVar(T var){  

    7.          this.var = var ;  

    8.      }  

    9.      public String toString(){       // 覆写Object类中

    的toString()方法  

    10.         return this.var.toString() ;      

    11.     }  

    12. }  

    13. public class GenericsDemo27{  

    14.     public static void main(String args[]){  

    15.         Info<Integer> i = fun(30) ;  

    16.         System.out.println(i.getVar()) ;  

    17.     }  

    18.     public static <T extends Number> Info<T> fun(T

    param){//方法中传入或返回的泛型类型由调用方法时所设置的参

    数类型决定  

    19.         Info<T> temp = new Info<T>() ;      // 根据传

    入的数据类型实例化Info  

    20.         temp.setVar(param) ;     // 将传递的内容设置

    到Info对象的var属性之中  

    21.         return temp ;   // 返回实例化对象  

    22.     }  

    23. }//  30

     使用泛型统一传入的参数类型

    Java代码

    1.  class Info<T>{    // 指定上限,只能是数字类型  

    2.      private T var ;     // 此类型由外部决定  

    3.      public T getVar(){  

    4.          return this.var ;     

    5.      }  

    6.      public void setVar(T var){  

    7.          this.var = var ;  

    8.      }  

    9.      public String toString(){       // 覆写Object类中

    的toString()方法  

    10.         return this.var.toString() ;      

    11.     }  

    12. }

    13. public class GenericsDemo28{  

    14.     public static void main(String args[]){  

    15.         Info<String> i1 = new Info<String>() ;  

    16.         Info<String> i2 = new Info<String>() ;  

    17.         i1.setVar("HELLO") ;        // 设置内容  

    18.         i2.setVar("汤姆") ;       // 设置内容  

    19.         add(i1,i2) ;  

    20.     }  

    21.     public static <T> void add(Info<T> i1,Info<T>

    i2){  

    22.         System.out.println(i1.getVar() + " " +

    i2.getVar()) ;  

    23.     }  

    24. }// HELLO 汤姆

     泛型数组

    Java代码

    1.  public class GenericsDemo30{  

    2.      public static void main(String args[]){  

    3.          Integer i[] = fun1(1,2,3,4,5,6) ;   // 返回泛

    型数组  

    4.          fun2(i) ;  

    5.      }  

    6.      public static <T> T[] fun1(T...arg){  // 接收可变

    参数  

    7.          return arg ;            // 返回泛型数组  

    8.      }  

    9.      public static <T> void fun2(T param[]){   // 输出

     

    10.         System.out.print("接收泛型数组:") ;  

    11.         for(T t:param){  

    12.             System.out.print(t + "、") ;  

    13.         }  

    14.     }  

    15. }//  接收泛型数组:1、2、3、4、5、6、

     泛型的嵌套设置

    Java代码

    1.  class Info<T,V>{      // 接收两个泛型类型  

    2.      private T var ;  

    3.      private V value ;  

    4.      public Info(T var,V value){  

    5.          this.setVar(var) ;  

    6.          this.setValue(value) ;  

    7.      }  

    8.      public void setVar(T var){  

    9.          this.var = var ;  

    10.     }  

    11.     public void setValue(V value){  

    12.         this.value = value ;  

    13.     }  

    14.     public T getVar(){  

    15.         return this.var ;  

    16.     }  

    17.     public V getValue(){  

    18.         return this.value ;  

    19.     }  

    20. }  

    21. class Demo<S>{  

    22.     private S info ;  

    23.     public Demo(S info){  

    24.         this.setInfo(info) ;  

    25.     }  

    26.     public void setInfo(S info){  

    27.         this.info = info ;  

    28.     }  

    29.     public S getInfo(){  

    30.         return this.info ;  

    31.     }  

    32. }

    33. public class GenericsDemo31{  

    34.     public static void main(String args[]){  

    35.         Demo<Info<String,Integer>> d = null ;  // 将

    Info作为Demo的泛型类型  

    36.         Info<String,Integer> i = null ;   // Info指定

    两个泛型类型  

    37.         i = new Info<String,Integer>("汤姆",30) ;    

    // 实例化Info对象  

    38.         d = new Demo<Info<String,Integer>>(i);//在

    Demo类中设置Info类的对象  

    39.         System.out.println("内容一:" + d.getInfo

    ().getVar()) ;  

    40.         System.out.println("内容二:" + d.getInfo

    ().getValue()) ;  

    41.     }  

    42. } // 内容一:汤姆 内容二:30

      泛型方法不一定要通过参数来确定泛型准确类型,可以只通过

    返回值,比如:

     public static <E> ArrayList<E> newArrayList() {
             return new ArrayList<E>();
     }

     public List<PrepaidHistory> queryHistories(Long

    skyid,PrepaidHistoryType type, Date from, Date end) { 

             return Lists.newArrayList();

    }

     这样Lists.newArrayList();
    智能的知道返回类型为PrepaidHistory
    一、内部类(局部内部类、成员内部类、匿名内部类)

    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<s.length;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<toIndex; 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<E> extends Iterable

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

    List<E>  extends Collection<E>----------有序的Collection,

    可重复

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

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

    AbstractList<E> extends AbstractCollection<E> implements

    List<E>

    Set<E>
    无序的不可重复的Collection

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

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

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

    public class Demo{
    public static void main(String[] args) {
    List<Object> alist = new ArrayList<Object>();//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<alist.size();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<Integer> alist1 = new ArrayList<Integer>();
    int size = alist.size();
    System.out.println(" size="+size);
    boolean flag = alist.isEmpty();//判断是否为空
    System.out.println(" flag="+flag);
    System.out.println("------------------------------");
    //第三种:Iterable-----迭代器输出
    //Iterable Iterator<T>iterator();
    Iterator<Object> 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<alist.size();i++){//注意:size()是动态变化


    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<Integer> link = new LinkedList<Integer>();
    //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<Object> dl = new LinkedList<Object>();
    //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<T> 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<T>接口,并实现compareTo( T t){ ----重写

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

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

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

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

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

    ("--------------------------------------");
    */
    Set<Cat> set=new TreeSet<Cat>();
    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<Cat>{
    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 <A> {
      public int compareTo( A that);
    }
    final class NumericValue implements Comparable

    <NumericValue> {
      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 extends Comparable<A>>A max(Collection

    <A> xs) {
        Iterator <A> 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 <NumericValue> numberList = new LinkedList

    <NumericValue> ();
        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>擦除后 A被替换为最左边界Object

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

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

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

    Comparable<A>,然后去掉参数类型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<String> sl = new ArrayList<String>();
    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<files.length;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)

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

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

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

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

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

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

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

                                                              

                                  

    JDK1.5新特性:

    七、枚举
    枚举是一个类类型,是JDK1.5的新特性

    枚举的关键字是enum

    Java中所有的枚举类都是java.lang.Enum的子类

    注意:枚举类中可以包含成员有【字段(常量)、方法(构造方

    法、普通方法)】

    枚举中不能有number;不能赋值------------类

     只有顺序可以比较-----------

    语法:

    enum 枚举名{

             枚举体

    }

    例:

    enum Direction{//枚举体

             EAST,SOUTH,WEST,NORTH//后面可以有分号也可以没有

    }

    调用:枚举名.成员

    枚举名 name =枚举名.成员;

    Direction dir = Direction.EAST;

     

    Enum的方法使用:

    Javap---------------查看字节码文件


    代码:

    enum Direction{

    EAST('e'),SOUTH('s'),NORTH('n'),WEST('w');

        protected char a;

    private Direction(char a){

    this.a = a;

    }

    public String toString(){

    return a+"";

    }

    }

    字节码:


    ---------- javap ----------

    Compiled from "Direction.java"

    final class Direction extends java.lang.Enum<Direction>

    {//不能被实例化

      public static final Direction EAST;

      public static final Direction SOUTH;

      public static final Direction NORTH;

      public static final Direction WEST;

      protected char a;//默认是private,但可以使用4P

      public static Direction[] values();//默认方法,用来遍历

    打印枚举成员

      public static Direction valueOf(java.lang.String);

      public java.lang.String toString();

      static {};//静态初始化块

    }

    由上面可以知道枚举继承java.lang.Enum类,参数的默认修饰符

    public static final,在枚举中可以使用4p



    public enum A{BLUE,RED,BLACK};//声明并定义一个枚举,初始

    化为。。。

    在一个类中定义一个enum成员,enum默认是静态的-------------

    相当于类变量



    枚举的用法

    一、常量-----------枚举出来之前都是通过接口

    在JDK1.5 之前,我们定义常量都是: public static fianl,现

    在可以把相关的常量分组到一个枚举类型里,例:

    public enum Color {

      RED, GREEN, BLANK, YELLOW

    }

    二、Switch

    JDK1.5之后的switch语句支持Byte,short,int,char,enum类型

    ,使用枚举,能让我们的代码可读性更强,JDK1.7之后开始支持

    String类型,例:

    enum Signal {

             GREEN, YELLOW, RED

    }

    public class TrafficLight {

             Signal color = Signal.RED;

             public void change() {

                       switch (color) {

                       case RED:

                                color = Signal.GREEN;

                                break;

                       case YELLOW:

                                color = Signal.RED;

                                break;

                       case GREEN:

                                color = Signal.YELLOW;

                                break;

                       }

             }

    }

    三、向枚举中添加新方法

    要自定义方法,必须在enum实例序列的最后添加一个分号。而且

    Java 要求必须先定义 enum实例,例:

    public enum Color {

             RED("红色", 1), GREEN("绿色", 2), BLANK("白色",

    3), YELLO("黄色", 4);

             // 成员变量

             private String name;

             private int index;

             // 构造方法

             private Color(String name, int index) {

                       this.name = name;

                       this.index = index;

             }

             // 普通方法

             public static String getName(int index) {

                       for (Color c : Color.values()) {

                                if (c.getIndex() == index) {

                                         return c.name;

                                }

                       }

                       return null;

             }

             // get set 方法

             public String getName() {

                       return name;

             }

             public void setName(String name) {

                       this.name = name;

             }

             public int getIndex() {

                       return index;

             }

             public void setIndex(int index) {

                       this.index = index;

             }

    }

    四、覆盖枚举的方法

    例如覆盖toString()

    public enum Color {

             RED("红色", 1), GREEN("绿色", 2), BLANK("白色",

    3), YELLO("黄色", 4);

             // 成员变量

             private String name;

             private int index;

             // 构造方法

             private Color(String name, int index) {

                       this.name = name;

                       this.index = index;

             }

             //覆盖方法

             @Override

             public String toString() {

                       return this.index+"_"+this.name;

             }

    }

    五、实现接口------所有的枚举都继承自java.lang.Enum类。由

    于Java 不支持多继承,所以枚举对象不能再继承其他类,例:

    public interface Behaviour {

             void print();

             String getInfo();

    }

    public enum Color implements Behaviour{

             RED("红色", 1), GREEN("绿色", 2), BLANK("白色",

    3), YELLO("黄色", 4);

             // 成员变量

             private String name;

             private int index;

             // 构造方法

             private Color(String name, int index) {

                       this.name = name;

                       this.index = index;

             }

    //接口方法

             @Override

             public String getInfo() {

                       return this.name;

             }

             //接口方法

             @Override

             public void print() {

                       System.out.println(this.index

    +":"+this.name);

             }

    }

    六、使用接口组织枚举

    public interface Food {

             enum Coffee implements Food{

                       

    BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO

             }

             enum Dessert implements Food{

                       FRUIT, CAKE, GELATO

             }

    }

    七、枚举集合

    java.util.EnumSet和java.util.EnumMap是两个枚举集合。

    EnumSet保证集合中的元素不重复;EnumMap中的key是enum类型,

    而value则可以是任意类型。



    枚举和普通类的区别与联系;

    1、枚举与类都可以实现多接口;访问控制符都可以使用(4p),

    但枚举中默认的是private,类中默认的是package;

    2、枚举直接继承java.lang.Enum类,普通类是继承

    java.lang.Object;其中java.long.Enum类实现了

    java.long.Serializable和java.long.Comparable两个接口。

    3、使用enum定义、非抽象的枚举默认修饰符为public final,因

    此枚举不能派生子类。
    4、枚举的构造器只能使用private访问控制符,如果省略了枚举

    的访问修饰符其默认为private修饰;因为枚举的字段不能初始化

    ,对象类型的必须调用构造方法,所有有多少个成员构造方法就

    会运行多少次;
    5、枚举的所有实例必须在枚举的第一行显示列出,否则这个枚举

    永远都不能生产实例,列出这些实例时系统会自动添加public

    static final修饰,无需程序员显式添加

    6、所有的枚举类都提供了一个values方法,该方法可以很方便的

    遍历所有的枚举值

    7、关键字:枚举是enum,类是class

    8、枚举是类类型,类是引用类型


    instanceof关键字:
    public class FX {
    public static void main(String[] args) {
    boolean b = ("1" instanceof String);//判断某个对象是不是

    某个类的实例    Result = Object instanceof

    Class/interface
    //Result:布尔类型。
       //Object:必选项。任意对象表达式。
    //Class:必选项。任意已定义的对象类。
    System.out.println(b);
    }
    }


    注解---JDK1.5的新特性
    使用位置:类上、方法上、语句上

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

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

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

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

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

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

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


    八、协变与泛型
    协变-------可以用在数组、重写,不可以用在枚举中

    可变参数:

    int… a-------------代表一个没有长度限制的数组----------

    JDK1.5之后有的

    输入的必须是数组

    Java1.5增加了新特性:可变参数:适用于参数个数不确定,类型

    确定的情况,java把可变参数当做数组处理。注意:可变参数必

    须位于最后一项。只支持有一个可变参数。因为参数个数不定,

    所以当其后边还有相同类型参数时,java无法区分传入的参数属

    于前一个可变参数还是后边的参数,所以只能让可变参数位于最

    后一项。

    可变参数的特点:

    (1)、只能出现在参数列表的最后;

    (2)、... 位于变量类型和变量名之间,前后有无空格都可以;

    (3)、调用可变参数的方法时,编译器为该可变参数隐含创建一

    个数组,在方法体中以数组的形式访问可变参数。例:

    public class Varable {
         public static void main(String [] args){
             System.out.println(add(2,3));
             System.out.println(add(2,3,5));
         }
         public static int add(int x,int ...args){
             int sum=x;
             for(int i=0;i<args.length;i++){
                 sum+=args[i];
             }
             return sum;
         }
    }

     协变的作用范围

    1、数组:如果 A 是 B 的超类,则 A[] 也是 B[] 的超类,所有

    需要 A[] 的地方都可以用 B[] 代替,例:

    public class Test2 {

        public static void main(String[] args){

            Integer[] ints=new Integer[1];

            ints[0]=99;

            show(ints);

        }

        static void show(Number[] ns){

            System.out.println(Arrays.toString(ns));

        }

    }

     

    2、重写

    public class Test2 {

        public static void main(String[] args){

            P p=new C();

            System.out.println(p.get());

        }

    }

    class P{

        public Number get(){

            return new Integer(0);

        }

    }

    class C extends P{

        public Integer get(){

            return new Integer(1);

        }

    }

    3、泛型不能协变:如果 A 是 B 的超类,则 List<A> 和

    List<B> 无关,需要 List<A> 的地方不可以用 List<B> 代替,

    例:

    public class Test2 {

        public static void main(String[] args) {

            List<Integer> ints = new ArrayList<Integer>();

            //incompatible type--类型不兼容

            show(ints);

        }

     

        static void show(List<Number> ns) {

            System.out.println(ns);

        }

    }


    泛型(Generic)的本质是类型参数化

    -------------是JDK1.5提供的新技术,它的本质是类型参数化,

    类似C++中的模板,它根据应用主要分为泛型方法,泛型接口,泛

    型类,协变不适用于泛型

     

    泛型-------------泛型类class Demo<T>{},泛型接口interface

    Inter<T>{},泛型方法public<T> T show(T a) {}

    泛型的好处是在编译的时候检查类型安全,并且所有的强制转换

    都是自动和隐式的,提高代码的重用率

     

    例1:

    public class  GenericDemo{

           public static void main(String[] args) {

                  C c1 = new C(new A("aaa"));

                  C c2 = new C(new B(3.4));//包装成double---

    自动装箱

                  Object obj = c1.getObj();

                  A obj = (A)(c1.getObj());//强制转换

                  System.out.println(obj);

           }

    }

    class A{

           private String x;

           public A(String x){

                  this.x=x;

           }

           public String getX(){

                  return x;

           }

    }

    class B{

           private Double d;

           public B(Double d){

                  this.d=d ;

           }

           public Double getD(){

                  return d;

           }

    }

    class C{

           private Object obj;

           public C(Object obj){

                  this.obj=obj ;

           }

           public Object  getObj(){

                  return obj;

           }

    }

     

    泛型的使用:

    一、泛型类:

    public class Demo1 {

           public static void main(String[] args) {

                  Generic<String> c = new Generic<String>

    ("asad");

                  System.out.println(c.getA());

     

                  //Generic<int> c1 = new Generic<int>(12);必

    须要是包装类

           }

    }

    class Generic<T>{//泛型类

           private T a;

           public Generic(T a){

                  this.a = a;

           }

           public T getA(){

                  return a;

           }

    }

     

    二、泛型方法

           public static <T> T getX(T t){//泛型方

    法----------<  >--表声明

                  return t;

           }

          

    public static <T,K> T getX(K t){//泛型方法

                  return t;

           }

     

    三、泛型接口

    public class GenericDemo3{

    public static void main(String[] args) {

    D<int[][]> d = new D<int[][]>();

    d.show(new int[][]{{1,4},{2,3}});

    }

    }

    interface IA<T>{

    void show(T t);

    }



    class D<T> implements IA<T>{

    public void show(T t){

    System.out.println(t.getClass().getName());

    }

    }

     

     

    有界类型:

    上界:extends 默认上界为Object

    Class G <T extends Number,K extends Object,H super

    Integer>{}

    下界:super----------只有通配符有下限

    extends关键字声明了类型的上界,表示参数化的类型可能是所指

    定的类型,或者是此类型的子类

    super关键字声明了类型的下界,表示参数化的类型可能是所指定

    的类型,或者是此类型的父类型,直至Object

     

    规则和限制

    1、泛型的类型参数只能是类类型(包括自定义类),不能是简单

    类型。

    2、同一种泛型可以对应多个版本(因为参数类型是不确定的),

    不同版本的泛型类实例是不兼容的。

    3、泛型的类型参数可以有多个。<T,K>

    4、泛型的参数类型可以使用extends关键字,例如<T extends

    superclass>。习惯上称为“有界类型”。

    5、泛型的参数类型还可以是通配符类型。例如Class<?>

    classType = Class.forName("java.lang.String")

    6、如果只指定了<?>,而没有extends,则默认是允许Object及其

    下的任何Java类了。也就是任意类。

    7、通配符泛型不但可以向下限制,如<? extends Collection>,

    还可以向上限制,如<? super Double>,表示类型只能接受

    Double及其上层父类类型,如Number、Object类型的实例。

    8、泛型类定义可以有多个泛型参数,中间用逗号隔开,还可以定

    义泛型接口,泛型方法。这些都与泛型类中泛型的使用规则类似



    一个普通static方法,无法访问泛型类的类型参数,所以,若普

    通static方法需要使用泛型参数,必须使其成为泛型方法。

     

     

    java 泛型详解

    普通泛型

    Java代码

    1.  class Point<T>{       // 此处可以随便写标识符号  

    2.      private T var ; // var的类型由T指定,即:由外部指

    定  

    3.      public T getVar(){  // 返回值的类型由外部决定  

    4.          return var ;  

    5.      }  

    6.      public void setVar(T var){  // 设置的类型也由外部

    决定  

    7.          this.var = var ;  

    8.      }  

    9.  }  

    10. public class GenericsDemo06{  

    11.     public static void main(String[] args){

    12.         Point<String> p = new Point<String>() ; // 里

    面的var类型为String类型  --------指定数据类型—必须是引用

    数据类型

    13.         p.setVar("it") ;        // 设置字符串  

    14.         System.out.println(p.getVar().length()) ;   

    // 取得字符串的长度  

    15.     }  

    16. }

    17. //2

    18.

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

    -  

    19. class Notepad<K,V>{       // 此处指定了两个泛型类

    型-----再类上进行声明泛型类型  

    20.     private K key ;     // 此变量的类型由外部决定  

    21.     private V value ;   // 此变量的类型由外部决定  

    22.     public K getKey(){  

    23.         return this.key ;  

    24.     }  

    25.     public V getValue(){  

    26.         return this.value ;  

    27.     }  

    28.     public void setKey(K key){  

    29.         this.key = key ;  

    30.     }  

    31.     public void setValue(V value){  

    32.         this.value = value ;  

    33.     }  

    34. }  

    35. public class GenericsDemo09{  

    36.     public static void main(String args[]){  

    37.         Notepad<String,Integer> t = null ;        //

    定义两个泛型类型的对象  

    38.         t = new Notepad<String,Integer>() ;       //

    里面的key为String,value为Integer  

    39.         t.setKey("汤姆") ;        // 设置第一个内容  

    40.         t.setValue(20) ;            // 设置第二个内容

     

    41.         System.out.print("姓名;" + t.getKey()) ;     

     // 取得信息  

    42.         System.out.print(",年龄;" + t.getValue()) ;

          // 取得信息  

    43.       }  

    44. }  //汤姆

    45.       20

     通配符

    Java代码

    1.  class Info<T>{  

    2.      private T var ;     // 定义泛型变量  

    3.      public void setVar(T var){  

    4.          this.var = var ;  

    5.      }  

    6.      public T getVar(){  

    7.          return this.var ;  

    8.      }  

    9.      public String toString(){   // 直接打印  

    10.         return this.var.toString() ;  

    11.     }  

    12. }

    13. public class GenericsDemo14{  

    14.     public static void main(String args[]){  

    15.         Info<String> i = new Info<String>() ;       

    // 使用String为泛型类型  

    16.         i.setVar("it") ;                            

    // 设置内容  

    17.         fun(i) ;  

    18.     }  

    19.     public static void fun(Info<?> temp){     // 可以

    接收任意的泛型对象  

    20.         System.out.println("内容:" + temp) ;  

    21.     }  

    22. }//  内容:it

     受限泛型

    Java代码

    1.  class Info<T>{  

    2.      private T var ;     // 定义泛型变量  

    3.      public void setVar(T var){  

    4.          this.var = var ;  

    5.      }  

    6.      public T getVar(){  

    7.          return this.var ;  

    8.      }  

    9.      public String toString(){   // 直接打印  

    10.         return this.var.toString() ;  

    11.     }  

    12. }  

    13. public class GenericsDemo17{  

    14.     public static void main(String args[]){  

    15.         Info<Integer> i1 = new Info<Integer>() ;   //

    声明Integer的泛型对象  

    16.         Info<Float> i2 = new Info<Float>() ;         

    // 声明Float的泛型对象  

    17.         i1.setVar(30) ;                              

    // 设置整数,自动装箱  

    18.         i2.setVar(30.1f) ;                           

    // 设置小数,自动装箱  

    19.         fun(i1) ;  

    20.         fun(i2) ;  

    21.     }  

    22.     public static void fun(Info<? extends Number>

    temp){ // 只能接收Number及其Number的子类  

    23.         System.out.print(temp + "、") ;  

    24.     }  

    25. }//  30、30.1、

    26.

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

    -  

    27. class Info<T>{  

    28.     private T var ;     // 定义泛型变量  

    29.     public void setVar(T var){  

    30.         this.var = var ;  

    31.     }  

    32.     public T getVar(){  

    33.         return this.var ;  

    34.     }  

    35.     public String toString(){   // 直接打印  

    36.         return this.var.toString() ;  

    37.     }  

    38. }  

    39. public class GenericsDemo21{  

    40.     public static void main(String args[]){  

    41.         Info<String> i1 = new Info<String>() ;      

    // 声明String的泛型对象  

    42.         Info<Object> i2 = new Info<Object>() ;      

    // 声明Object的泛型对象  

    43.         i1.setVar("hello") ;  

    44.         i2.setVar(new Object()) ;  

    45.         fun(i1) ;  

    46.         fun(i2) ;  

    47.     }  

    48.     public static void fun(Info<? super String>

    temp){   // 只能接收String或Object类型的泛型  ----上限为

    String

    49.         System.out.print(temp + "、") ;  

    50.     }  

    51. }//  hello、java.lang.Object@1ffc686、

     泛型无法向上转型

    Java代码

    1.  class Info<T>{  

    2.      private T var ;     // 定义泛型变量  

    3.      public void setVar(T var){  

    4.          this.var = var ;  

    5.      }  

    6.      public T getVar(){  

    7.          return this.var ;  

    8.      }  

    9.      public String toString(){   // 直接打印  

    10.         return this.var.toString() ;  

    11.     }  

    12. }  

    13. public class GenericsDemo23{  

    14.     public static void main(String args[]){  

    15.         Info<String> i1 = new Info<String>() ;      

    // 泛型类型为String  

    16.         Info<Object> i2 = null ;  

    17.         i2 = i1 ;                           //这句会

    出错 incompatible types  

    18.     }  

    19. }//  编译失败

     泛型接口

    Java代码

    1.  interface Info<T>{        // 在接口上定义泛型  

    2.      public T getVar() ; // 定义抽象方法,抽象方法的返

    回值就是泛型类型  

    3.  }  

    4.  class InfoImpl<T> implements Info<T>{   // 定义泛型接

    口的子类  

    5.      private T var ;             // 定义属性  

    6.      public InfoImpl(T var){     // 通过构造方法设置属

    性内容  

    7.          this.setVar(var) ;    

    8.      }  

    9.      public void setVar(T var){  

    10.         this.var = var ;  

    11.     }  

    12.     public T getVar(){  

    13.         return this.var ;  

    14.     }  

    15. }  

    16. public class GenericsDemo24{  

    17.     public static void main(String arsg[]){  

    18.         Info<String> i = null;        // 声明接口对象

     

    19.         i = new InfoImpl<String>("汤姆") ;  // 通过子

    类实例化对象  

    20.         System.out.println("内容:" + i.getVar()) ;  

    21.     }  

    22. }//  内容:汤姆

     泛型方法

    Java代码

    1.  class Demo{  

    2.      public <T> T fun(T t){            // 可以接收任意

    类型的数据  

    3.          return t ;                  // 直接把参数返回

     

    4.      }  

    5.  }  

    6.  public class GenericsDemo26{  

    7.      public static void main(String args[]){  

    8.          Demo d = new Demo() ;   // 实例化Demo对象  

    9.          String str = d.fun("汤姆") ; //   传递字符串  

    10.         int i = d.fun(30) ;     // 传递数字,自动装箱

     

    11.         System.out.println(str) ;   // 输出内容  

    12.         System.out.println(i) ;     // 输出内容  

    13.     }  

    14. }//  汤姆  30

     通过泛型方法返回泛型类型实例

    Java代码

    1.  class Info<T extends Number>{ // 指定上限,只能是数字

    类型  

    2.      private T var ;     // 此类型由外部决定  

    3.      public T getVar(){  

    4.          return this.var ;     

    5.      }  

    6.      public void setVar(T var){  

    7.          this.var = var ;  

    8.      }  

    9.      public String toString(){       // 覆写Object类中

    的toString()方法  

    10.         return this.var.toString() ;      

    11.     }  

    12. }  

    13. public class GenericsDemo27{  

    14.     public static void main(String args[]){  

    15.         Info<Integer> i = fun(30) ;  

    16.         System.out.println(i.getVar()) ;  

    17.     }  

    18.     public static <T extends Number> Info<T> fun(T

    param){//方法中传入或返回的泛型类型由调用方法时所设置的参

    数类型决定  

    19.         Info<T> temp = new Info<T>() ;      // 根据传

    入的数据类型实例化Info  

    20.         temp.setVar(param) ;     // 将传递的内容设置

    到Info对象的var属性之中  

    21.         return temp ;   // 返回实例化对象  

    22.     }  

    23. }//  30

     使用泛型统一传入的参数类型

    Java代码

    1.  class Info<T>{    // 指定上限,只能是数字类型  

    2.      private T var ;     // 此类型由外部决定  

    3.      public T getVar(){  

    4.          return this.var ;     

    5.      }  

    6.      public void setVar(T var){  

    7.          this.var = var ;  

    8.      }  

    9.      public String toString(){       // 覆写Object类中

    的toString()方法  

    10.         return this.var.toString() ;      

    11.     }  

    12. }

    13. public class GenericsDemo28{  

    14.     public static void main(String args[]){  

    15.         Info<String> i1 = new Info<String>() ;  

    16.         Info<String> i2 = new Info<String>() ;  

    17.         i1.setVar("HELLO") ;        // 设置内容  

    18.         i2.setVar("汤姆") ;       // 设置内容  

    19.         add(i1,i2) ;  

    20.     }  

    21.     public static <T> void add(Info<T> i1,Info<T>

    i2){  

    22.         System.out.println(i1.getVar() + " " +

    i2.getVar()) ;  

    23.     }  

    24. }// HELLO 汤姆

     泛型数组

    Java代码

    1.  public class GenericsDemo30{  

    2.      public static void main(String args[]){  

    3.          Integer i[] = fun1(1,2,3,4,5,6) ;   // 返回泛

    型数组  

    4.          fun2(i) ;  

    5.      }  

    6.      public static <T> T[] fun1(T...arg){  // 接收可变

    参数  

    7.          return arg ;            // 返回泛型数组  

    8.      }  

    9.      public static <T> void fun2(T param[]){   // 输出

     

    10.         System.out.print("接收泛型数组:") ;  

    11.         for(T t:param){  

    12.             System.out.print(t + "、") ;  

    13.         }  

    14.     }  

    15. }//  接收泛型数组:1、2、3、4、5、6、

     泛型的嵌套设置

    Java代码

    1.  class Info<T,V>{      // 接收两个泛型类型  

    2.      private T var ;  

    3.      private V value ;  

    4.      public Info(T var,V value){  

    5.          this.setVar(var) ;  

    6.          this.setValue(value) ;  

    7.      }  

    8.      public void setVar(T var){  

    9.          this.var = var ;  

    10.     }  

    11.     public void setValue(V value){  

    12.         this.value = value ;  

    13.     }  

    14.     public T getVar(){  

    15.         return this.var ;  

    16.     }  

    17.     public V getValue(){  

    18.         return this.value ;  

    19.     }  

    20. }  

    21. class Demo<S>{  

    22.     private S info ;  

    23.     public Demo(S info){  

    24.         this.setInfo(info) ;  

    25.     }  

    26.     public void setInfo(S info){  

    27.         this.info = info ;  

    28.     }  

    29.     public S getInfo(){  

    30.         return this.info ;  

    31.     }  

    32. }

    33. public class GenericsDemo31{  

    34.     public static void main(String args[]){  

    35.         Demo<Info<String,Integer>> d = null ;  // 将

    Info作为Demo的泛型类型  

    36.         Info<String,Integer> i = null ;   // Info指定

    两个泛型类型  

    37.         i = new Info<String,Integer>("汤姆",30) ;    

    // 实例化Info对象  

    38.         d = new Demo<Info<String,Integer>>(i);//在

    Demo类中设置Info类的对象  

    39.         System.out.println("内容一:" + d.getInfo

    ().getVar()) ;  

    40.         System.out.println("内容二:" + d.getInfo

    ().getValue()) ;  

    41.     }  

    42. } // 内容一:汤姆 内容二:30

      泛型方法不一定要通过参数来确定泛型准确类型,可以只通过

    返回值,比如:

     public static <E> ArrayList<E> newArrayList() {
             return new ArrayList<E>();
     }

     public List<PrepaidHistory> queryHistories(Long

    skyid,PrepaidHistoryType type, Date from, Date end) { 

             return Lists.newArrayList();

    }

     这样Lists.newArrayList();
    智能的知道返回类型为PrepaidHistory

    一、 Oracle的安装(windowXP、win7、Linux)和卸载
      1.1 Oracle的安装
        1.1.1 在WindowsXP、Win7下安装
          第一:解压win32_11gR2_database_1of2、

    win32_11gR2_database_2of2,生成detabase目录
          第二:安装oracle
               A、点击setup图标即可,注意:安装目录不要含有中


               B、在弹出的第一个界面中取消更新选择项,点击下

    一步
               C、在弹出的警告框中选择是
               D、选择创建和配置数据库选项,下一步
               E、选择桌面类安装,点击下一步
               F、弹出的窗口中输入全局数据库名:orcl
                     输入管理口令:bluedot
                     默认的管理员是:sys和system
               G、点完成,开始安装数据库,出现进度条
               H、口令管理
               I、设置口令
               J、完成安装
      1.2 Oracle的卸载:
        1、 开始->设置->控制面板->管理工具->服务 停止

    所有Oracle服务。
        2、 开始->程序->Oracle - OraHome81->Oracle

    Installation Products-> Universal Installer,单击“卸载

    产品”-“全部展开”,选中除“OraDb11g_home1”外的全部目录

    ,删除。
        3、 运行regedit,选择HKEY_LOCAL_MACHINE\SOFTWARE

    \ORACLE,按del键删除这个入口。
        4、 运行regedit,选择HKEY_LOCAL_MACHINE\SYSTEM

    \CurrentControlSet\Services,滚动这个列表,删除所有Oracle

    入口(以oracle或OraWeb开头的键)。
        5、 运行refedit,HKEY_LOCAL_MACHINE\SYSTEM

    \CurrentControlSet\Services\Eventlog\Application,删除所

    有Oracle入口。e
        6、 删除HKEY_CLASSES_ROOT目录下所有以Ora、Oracle、

    Orcl或EnumOra为前缀的键。
        7、 删除HKEY_CURRENT_USER\Software\Microsoft\Windows

    \CurrentVersion\Explorer\MenuOrder\Start Menu\Programs中

    所有以oracle开头的键。
        8、删除HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI

    中除Microsoft ODBC for Oracle注册表键以外的所有含有Oracle

    的键。
        9、我的电脑-->属性-->高级-->环境变量,删除环境变量

    CLASSPATH和PATH中有关Oracle的设定。
        10、从桌面上、STARTUP(启动)组、程序菜单中,删除所有

    有关Oracle的组和图标。
        11、删除所有与Oracle相关的目录(如果删不掉,重启计算机

    后再删就可以了)包括:
             1.C:\Program file\Oracle目录。
             2.ORACLE_BASE目录(oracle的安装目录)。
             3.C:\WINDOWS\system32\config\systemprofile

    \Oracle目录。
             4.C:\Users\Administrator\Oracle或C:\Documents

    and Settings\Administrator\Oracle目录。
             5.C:\WINDOWS下删除以下文件ORACLE.INI、

    oradim73.INI、oradim80.INI、oraodbc.ini等等。
             6.C:\WINDOWS下的WIN.INI文件中若有[ORACLE]的标记

    段,删除该段。
        12、如有必要,删除所有Oracle相关的ODBC的DSN
        13、到事件查看器中,删除Oracle相关的日志 说明: 如果

    有个别DLL文件无法删除的情况,则不用理会,重新启动,开始新

    的安装,安装时,选择一个新的目录,则,安装完毕并重新启动

    后,老的目录及文件就可以删除掉了。
     
    二、 用户管理
       2.1 创建用户
           注:创建用户只能在管理员下完成
           CREATE USER 用户名 IDENTIFIED BY 密码。
           |-CREATE USER demo IDENTIFIED BY 123456;
       2.2 用户分类
         |-管理员和普通用户
            |-管理员
              |-超级管理员:sys/bluedot
              |-管理员:system/bluedot
            |-普通用户:scott/tiger
                           hr/hr
         |--常见角色:sysdba、sysoper
       2.3 用户登录
         2.3.1 在命令行窗口登录[c/s]
            步骤:
               运行 sqlplus /nolog
               conn demo/123456
          2.3.2 另外的一种登录方式【B/S】
               输入网址----https://localhost:1158/em
      输入用户名密码进入主界面
       2.4 修改用户密码
          注:修改密码必须要在级别高的用户下进行修改
         ALTER USER 用户名 IDENTIFIED BY 密码;
         
         conn sys/bluedot as sysdba
         ALTER USER demo IDENTIFIED BY 654321;
       2.5 查询用户
           2.5.1查看用户信息
             1、SELECT * FROM DBA_USERS;--------查看所有用户

    的详细信息
             2、SELECT * FROM ALL_USERS;-------查看所有用户简

    要信息
             3、SELECT * FROM USER_USERS;------------查看当前

    用户的所用信息
          2.5.2 查看用户或角色系统权限(直接赋值给用户或角色

    的系统权限)
             SELECT * FROM DBA_SYS_PRIVS;----------全部
             SELECT * FROM USER_SYS_PRIVS; ---------当前用户
          2.5.3 查看角色(登录用户拥有的角色)所包含的的权限
             SELECT * FROM ROLE_SYS_PRIVS;
          2.5.4 查看用户对象权限
             SELECT * FROM DBA_TAB_PRIVS;
             SELECT * FROM ALL_TAB_PRIVS;
             SELECT * FROM USER_TAB_PRIVS;
          2.5.5 查看所有角色
             SELECT * FROM DBA_ROLES;
             SELECT * FROM DBA_ROLE_PRIVS;
             SELECT * FROM USER_ROLE_PRIVS;
     
          2.5.6 查看哪些用户有sysdba或sysoper系统权限(查询时

    需要相应权限)
             SELECT * FROM V$PWFILE_USERS;
     
          2.5.7 查看Oracle提供的系统权限
             SELECT name FROM SYS.SYSTEM_PRIVSILEGE_MAP;
       2.6 密码失效
          提示用户第一次连接的时候需要修改密码,让用户的密码

    到期
            |- ALTER USER 用户名 PASSWORD expire ;
       2.7 授权
           GRANT 权限/角色 TO 用户
           给 demo 用户以创建 session 的权限:GRANT create

    session TO demo;
           角色:-------------角色就是一堆权限的集合
           Create role myrole;
           Grant create table to myrole;
           Drop role myrole; 删除角色
          1.CONNECT, RESOURCE, DBA
          这些预定义角色主要是为了向后兼容。其主要是用于数据

    库管理。oracle建议用户自己设计数据库管理和安全的权限规划

    ,而不要简单的使用这些预定角色。将来的版本中这些角色可能

    不会作为预定义角色。
          2.DELETE_CATALOG_ROLE, EXECUTE_CATALOG_ROLE,

    SELECT_CATALOG_ROLE 这些角色主要用于访问数据字典视图和包


          3.EXP_FULL_DATABASE, IMP_FULL_DATABASE 这两个角

    色用于数据导入导出工具的使用。
            GRANT 权限(select、update、insert、delete) ON

    schema.table TO 用户
              |- GRANT select ON scott.emp TO test ;
              |- Grant all on scott.emp to test; --将表相关的

    所有权限付给 test
              |- Grant update(ename) on emp to test; 可以控制

    到列(还有 insert)
       2.8 收权
          REVOKE 权限/角色 ON schema.table FROM 用户
           |- REVOKE select ON scott.emp FROM test ;
       2.9 锁住一个用户
           ALTER USER 用户名 ACCOUNT LOCK|UNLOCK
             |- ALTER USER test ACCOUNT LOCK ;
             |- ALTER USER test ACCOUNT UNLOCK ;
        2.10 删除用户
                |-DROP USER 用户名;
                      |-Drop user demo;
               如果该用户下面已经存在表等一些数据库对象。则必

    须用级联删除
               |-DROP USER 用户名 CASCADE;
                       |-Drop user demo cascade;
        备注:帮助
            help index
            help conn --------显示具体的
            eidt---------------进入编辑文档
    三、 Oracle的体系结构
       3.1 Oracle数据库的整体架构 (DBA)
                     ┌───────────────────

    ───────────┐
    ┌────┐ │ Instance │
    │ User │ │ ┌────────────────────

    ──────┐ │
    │ process│ │ │ ┌────────┐ SGA │ │
    └────┘ │ │ │ Shared Pool │ │ │
        ↓ │ │ │ ┌─────┐ │ ┌────┐ ┌────

    ┐ │ │
        ↓ │ │ │ │Library │ │ │Database│ │ Redo │

    │ │
    ┌────┐ │ │ │ │ Cache │ │ │Buffer │ │ Log

    │ │ │
    │ Server │ │ │ │ └─────┘ │ │Cache │ │

    Buffer │ │ │
    │process │ │ │ │ ┌─────┐ │ │ │ │ │ │ │
    └────┘ │ │ │ │Data Dict │ │ └────┘ └─

    ───┘ │ │
         ↓ │ │ │ │ Cache │ │ │ │
         →→→→→→│ │ │ └─────┘ │ │ │
                     │ │ └────────┘ │ │
                     │ └─────────────────

    ─────────┘ │
                     │ ┌──┐ ┌──┐ ┌──┐ ┌──┐

    ┌──┐ ┌───┐│
       │ │PMON│ │SNON│ │DBWR│ │LGWR│ │CHPT│

    │OTHERS││
                     │ └──┘ └──┘ └──┘ └──┘

    └──┘ └───┘│
                     └───────────────────

    ───────────┘
                                                     ↑ ↓
                   ┌─────┐ ┌────────────

    ───────┐
                   │Parameter │ │┌───┐ ┌────┐

    ┌────┐│
                   │ file │ ││Data │ │control │ │Redo

    Log││ ┌─────┐
                   └─────┘ ││files │ │ files │ │

    files ││ │Archived │
                   ┌─────┐ │└───┘ └────┘

    └────┘│ │Log files │
                   │ Password │ │ Database │ └─────


            │ file │ │ │
                   └─────┘ └────────────

    ───────┘
    由上图可知,Oracle数据库由实例和数据库组成。
       3.2 数据库存储结构
          3.2.1 数据库存储结构
          Oracle数据库有物理结构和逻辑结构。数据库的物理结构

    是数据库中的操作系统文件的集合。数据库的物理结构由数据文

    件、控制文件和重做日志文件组成。
          1、数据文件:数据文件是数据的存储仓库。
          2、重做日志文件:重做日志文件包含对数据库所做的更改

    记录,在发生故障时能够恢复数据。重做日志按时间顺序存储应

    用于数据库的一连串的变更向量。其中仅包含重建(重做)所有

    已完成工作的最少限度信息。如果数据文件受损,则可以将这些

    变更向量应用于数据文件备份来重做工作,将它恢复到发生故障

    的那一刻前的状态。重做日志文件包含联机重做日志文件(对于

    连续的数据库操作时必须的)和归档日志文件(对于数据库操作

    是可选的,但对于时间点恢复是必须的)。
          3、控制文件:控制文件包含维护和验证数据库完整性的必

    要的信息。控制文件虽小,但作用非常大。它包含指向数据库其

    余部分的指针:联机重做日志文件和数据文件的位置,以及更新

    的归档日志文件的位置。它还存储着维护数据库完整性所需的信

    息。控制文件不过数MB,却起着至关重要的作用。
          除了三个必须的文件外数据库还能有其它非必须的文件如

    :参数文件、口令文件及归档日志文件。
              1、实例参数文件:当启动oracle实例时,SGA结构会

    根据此参数文件的设置内置到内存,后台进程会据此启动。
              2、口令文件:用户通过提交用户名和口令来建立会话

    。Oracle根据存储在数据字典的用户定义对用户名和口令进行验

    证。
              3、归档重做日志文件:当重做日志文件满时将重做日

    志文件进行归档以便还原数据文件备份。
          3.2.2 Oracle数据库结构的16个要点(表空间-->段-->

    区-->块)
       1、一个数据文件只能归到某一个表空间上,每个表空间可

    以含一个或多个数据文件。包括系统数据和用户数据。
       2、表空间是包括一个或多个数据文件的逻辑结构。用于存

    放数据库表、索引、回滚段等对象的磁盘逻辑空间
       3、数据库文件是存放实际数据的物理文件。包括实例和数

    据库。
       4、数据文件可以在创建表空间时创建,也可以以增加的方

    式创建。
       5、数据文件的大小一般与操作系统限制有关。
       6、控制文件是Oracle的重要文件,主要存放数据文件、日

    志文件和数据库的基本信息,一般在数据打开时访问。
       7、日志文件在数据库活动时使用。
       8、临时表空间是用于存放排序段的磁间;临时表空间由一

    个或多个临时文件组成。
       9、归档日志文件由归档进程将联机日志文件读出并写到一

    个路径上的文件。
       10、Oracle实例由一组后台进程和内存结构组成。
       11、Oracle实例的内存结构常叫系统全局区,简称SGA。
       12、DBA_开头的数据字典存放的字符信息都是大写,而V$_

    开头的视图存放的都是小写。
       13、后台进程是一组完成不同功能的程序,主要包括DBWR、

    LGMR、CKPT等。
       14、数据字典是Oracle的重要部分,也就是用于系统内部的

    一组表。
       15、数据字典分为动态和静态两部分,静态主要是DBA_开头

    的数据字典,而动态则是以V$_开头的视图。
       16、SGA分为数据缓冲区、共享池和日志缓冲区。
         3.2.3 Oracle逻辑结构及表空间
            1.ORACLE逻辑结构
                 ORACLE将数据逻辑地存放在表空间,物理地存放在

    数据文件中。
                 一个表空间任何一个时刻只能属于一个数据库。
     
                 数据库——表空间——段——区——ORACLE块
                 每个数据库由一个或多个表空间组成,至少一个。
                 每个表空间基于一个或多个操作系统的数据文件,

    至少一个,一个操作系统的数据文件只能属于一个表空间。一个

    表空间可以存放一个或多个段 segment。
                 每个段由一个或多个区段extent组成。
                 每个区段由一个或多个连续的ORACLE数据库块组成


                 每个ORACLE数据块由一个或多个连续的操作系统数

    据块组成。
                 每个操作系统数据文件由一个或多个区段组成,由

    一个或多个操作系统数据块组成。
         
             ⑴、表空间(tablespace)
                 表空间是数据库中最大的逻辑单位,每一个表空间

    由一个或多个数据文件组成,一个数据文件只能与一个表空间相

    联系。每一个数据库都有一个SYSTEM表空间,该表空间是在数据

    库创建或数据库安装时自动创建的,用于存储系统的数据字典表

    ,程序系统单元,过程函数,包和触发器等,也可用于存储用户

    数据表,索引对象。表空间具有在线(online)和离线(offline

    )属性,可以将除SYSTME以外的其他任何表空间置为离线。
             ⑵、段(segment)
                 数据库的段可以分为四类:数据段、索引段、回退

    段和临时段。
             ⑶、区
                 区是磁盘空间分配的最小单位。磁盘按区划分,每

    次至少分配一个区。区存储与段中,它由连续的数据块组成。
             ⑷、数据块
                 数据块是数据库中最小的数据组织单位与管理单位

    ,是数据文件磁盘存储空间单位,也是数据库I/O的最小单位,数

    据块大小由DB_BLOCK_SIZE参数决定,不同的Oracle版本

    DB_BLOCK_SIZE的默认值是不同的。
             ⑸、模式对象
                 模式对象是一种应用,包括:表、聚簇、视图、索

    引序列生成器、同义词、哈希、程序单元、数据库链等。
                 最后,在来说一下Oracle的用户、表空间和数据文

    件的关系:
                 一个用户可以使用一个或多个表空间,一个表空间

    也可以供多个用户使用。用户和表空间没有隶属关系,表空间是

    一个用来管理数据存储的逻辑概念,表空间只是和数据文件发生

    关系,数据文件是物理的,一个表空间可以包含多个数据文件,

    而一个数据文件只能隶属一个表空间。
                 总结:解释数据库、表空间、数据文件、表、数据

    的最好办法就是想象一个装满东西的柜子。数据库其实就是柜子

    ,柜中的抽屉是表空间,抽屉中的文件夹是数据文件,文件夹中

    的纸是表,写在纸上的信息就是数据。
          2.两类表空间:
               系统SYSTEM表空间 非系统表空间 NON-SYSTEM表空间
               系统SYSTEM表空间与数据库一起建立,在系统表空间

    中有数据字典,系统还原段。可以存放用户数据但是不建议。
               非系统表空间NON-SYSTEM表空间 由管理员创建。可

    以方便管理。
       3.3 实例的整体架构
           实例整体架构图:
                     ┌───────────────────

    ───────────┐
                     │ Instance │
                     │ ┌─────────────────

    ─────────┐ │
                     │ │ ┌────────┐ SGA │ │
                     │ │ │ Shared Pool │ │ │
                     │ │ │ ┌─────┐ │ ┌────┐

    ┌────┐ │ │
                     │ │ │ │Library │ │ │Database│ │

    Redo │ │ │
                     │ │ │ │ Cache │ │ │Buffer │ │

    Log │ │ │
                     │ │ │ └─────┘ │ │Cache │ │

    Buffer │ │ │
                     │ │ │ ┌─────┐ │ │ │ │ │

    │ │
                     │ │ │ │Data Dict │ │ └────┘

    └────┘ │ │
                     │ │ │ │ Cache │ │ │ │
                     │ │ │ └─────┘ │ │ │
                     │ │ └────────┘ │ │
                     │ └─────────────────

    ─────────┘ │
                     │ ┌──┐ ┌──┐ ┌──┐ ┌──┐

    ┌──┐ ┌───┐│
       │ │PMON│ │SNON│ │DBWR│ │LGWR│ │CHPT│

    │OTHERS││
                     │ └──┘ └──┘ └──┘ └──┘

    └──┘ └───┘│
                     └───────────────────

    ───────────┘
           实例由内存和后台进程组成,它暂时存在于RAM和CPU中。

    当关闭运行的实例时,实例将随即消失。数据库由磁盘上的物理

    文件组成,不管在运行状态还是停止状态,这些文件就一直存在

    。因此,实例的生命周期就是其在内存中存在的时间,可以启动

    和停止。一旦创建数据库,数据库将永久存在。通俗的讲数据库

    就相当于平时安装某个程序所生成的安装目录,而实例就是运行

    某个程序时所需要的进程及消耗的内存。
           Oracle的内存架构包含两部分系统全局区(SGA)和程序

    全局区(PGA)。
           3.3.1 程序全局区
           3.3.2 系统全局区
               在操作系统提供的共享内存段实现的内存结构称为系

    统全局区(SGA)。SGA在实例启动时分配,在关闭时释放。在一

    定范围内,可以在实例运行时通过自动方式或响应DBA的指令,重

    新调整11g实例中的SGA及其中的组件的大小。
               由上图可知SGA至少包含三种数据结构:数据库缓冲

    区缓存、日志缓冲区及共享池。还可能包括:大池、JAVA池。可

    以使用show sga,查看sga的状态。
               1、共享池
                    a.库缓存是内存区域,按其已分析的格式存储

    最近执行的代码。分析就是将编程人员编写的代码转换为可执行

    的代码,这是oracle根据需要执行的一个过程。通过将代码缓存

    在共享池,可以在不重新分析的情况下重用,极大地提高性能。
                    b.数据字典缓存有时称为“行缓存”,它存储

    最近使用的对象定义:表、索引、用户和其他元数据定义的描述


                    c.PL/SQL区:存储的PL/SQL对象是过程、函数

    、打包的过程、打包的函数、对象类型定义和触发器。
               2、数据库缓冲区
                    数据库缓冲区是oracle用来执行SQL的工作区域


               3、日志缓冲区
                    日志缓冲区是小型的、用于短期存储将写入到

    磁盘上的重做日志的变更向量的临时区域。日志缓冲区在启动实

    例时分配,如果不重新启动实例,就不能在随后调整其大小。
     后台进程有:
      1、PMON-----程序监控器
      2、SMON-----系统监控区
      3、DBWR-----数据写进程
      4、LGWR-----日志写进程
      5、CKPT-----检查点进程
      6、Others---归档进程
    四、SQL语法基础(DDL、DCL、TCL、DML)
      SQL 全名是结构化查询语言(Structured Query Language),

    是用于数据库中的标准数据查询语言,IBM 公司最早使用在其开

    发的数据库系统中。1986 年 10 月,美国 ANSI 对 SQL 进行规

    范后,以此作为关系式数据库管理系统的标准语言 (ANSI X3.

    135-1986),1987 年得到国际标准组织的支持下成为国际标准。

    不过各种通行的数据库系统在其实践过程中都对 SQL 规范作了某

    些编改和扩充。所以,实际上不同数据库系统之间的 SQL 语言不

    能完全相互通用
            DML 语句(数据操作语言)Insert、Update、 Delete、

    Select
            DDL 语句(数据定义语言)Create、Alter、 Drop
            DCL 语句(数据控制语言)Grant、Revoke
            TCL 事务控制语句 Commit 、Rollback、Savepoint
      4.1 入门语句
          普通用户连接: Conn scott/tiger
          超级管理员连接: Conn “sys/bluesot as sysdba”
          Disconnect; 断开连接-------------disc
          Save c:\1.txt 把 SQL 存到文件
          Ed c:\1.txt 编辑 SQL 语句
          @ c:\1.txt 运行 SQL 语句
          Desc emp; 描述 Emp 结构
          Select * from tab; 查看该用户下的所有对象
          Show user; 显示当前用户
          如果在 sys 用户下: 查询 Select * from emp; 会报错

    ,原因:emp 是属于 scott,所以此时必须使用:select * from

    scott.emp; / 运行上一条语句
      4.2 DDL(数据定义语言)----改变表结构
         4.2.1 创建表
            CREATE TABLE name (
              tid VARCHAR2(5),
              tname VARCHAR2(20),
              tdate DATE,
              as VARCHAR(7,2)
            );
         4.2.2 添加一列
             ALTER TABLE 表名 ADD 列名 属性;
             ALTER TABLE student ADD age number(5);
         4.2.4 删除一列
             ALTER TABLE table_name DROP COLUMN column_name;
             ALTER TABLE student DROP COLUMN age;
         4.2.5 修改一列的属性
             ALTER TABLE table_name MODIFY column_name type;
             修改列名
             ALTER TABLE table_name RENAME COLUMN columnname

    TO newname;
             修改表名
             ALTER TABLE table_name RENAME TO newname;
         4.2.6 查看表中数据
             DESC table_name;
         4.2.7 删除表
             DROP TABLE table_name;
       4.3 DCL(数据控制语言)
         4.3.1 授权
            GRANT 权限/角色 TO 用户
            给 demo 用户以创建 session 的权限:GRANT create

    session TO demo;
            角色:-------------角色就是一堆权限的集合Create

    role myrole;
            Grant create table to myrole;
            Drop role myrole; 删除角色
             1.CONNECT, RESOURCE, DBA
             这些预定义角色主要是为了向后兼容。其主要是用于数

    据库管理。oracle建议用户自己设计数据库管理和安全的权限规

    划,而不要简单的使用这些预定角色。将来的版本中这些角色可

    能不会作为预定义角色。
             2.DELETE_CATALOG_ROLE, EXECUTE_CATALOG_ROLE,

    SELECT_CATALOG_ROLE 这些角色主要用于访问数据字典视图和包


             3.EXP_FULL_DATABASE, IMP_FULL_DATABASE 这两个

    角色用于数据导入导出工具的使用。
              GRANT 权限(select、update、insert、delete) ON

    schema.table TO 用户
               |- GRANT select ON scott.emp TO test ;
               |- Grant all on scott.emp to test; --将表相关

    的所有权限付给 test
               |- Grant update(ename) on emp to test; 可以控

    制到列(还有 insert)
         4.3.2 收权
              REVOKE 权限/角色 ON schema.table FROM 用户
                |- REVOKE select ON scott.emp FROM test ;
        4.4 TCL(事务控制语言)
           事务的概念:事务是一系列对数据库操作命令的集合,它

    有边界(commit---commit)
           事务的特征:A ------原子性-----不可分割性-------要

    么执行要么不执行
                       C------一致性-----rollback
                       I-------隔离性-----锁的机制来保证的,

    锁有粒度【表、行】---------只读、修改锁
                                 上锁---SELECT * FROM DEMO1

    FOR UPDATE;
                                 释放------commit、rollback
                       D -----持久性-------commit
              系统时间-----sysdate
                            to_date

    (‘2013/11/09’,‘yyyy/mm/dd’)--------修改日期格式
            转换函数
                  1、To_char
                          select to_char(sysdate,'yyyy') from

    dual;
                          select to_char(sysdate,'fmyyyy-mm-

    dd') from dual;
                          select to_char(sal,'L999,999,999')

    from emp;
                          select to_char(sysdate,’D’) from

    dual;//返回星期
                  2、To_number
                          select to_number('13')+to_number

    ('14') from dual;
                  3、To_date
                          Select to_date

    (‘20090210’,‘yyyyMMdd’) from dual;
            4.4.1 ROLLBACK
      回滚------回滚到它上面的离它最近的commit
     4.4.2 COMMIT
      提交-----------将数据缓冲区的数据提交到文件中去
     4.4.3 SAVEPOINT------保存点
      回滚点例子:
      INSERT INTO DEMO1(TID,TNAME) VALUES(11,'AS');
      SAVEPOINT P1;
      INSERT INTO DEMO1(TID,TNAME) VALUES(22,'AS');
      INSERT INTO DEMO1(TID,TNAME) VALUES(33,'AS');
      SAVEPOINT P2;
      INSERT INTO DEMO1(TID,TNAME) VALUES(44,'AS');
      ROLLBACK TO P2;
      COMMIT;
      INSERT INTO DEMO1(TID,TNAME) VALUES(55,'AS');
      ROLLBACK TO P1;----------无法回滚
        ------------查询结果:11,22,33 由于55没有提交所以没有

    写入文件
        4.5 DML(数据操作语言)---------改变数据结构
     4.5.1 insert 语句
      INSERT INTO table_name() VALUES();
      INSERT INTO table_name VALUES();
          插入空值时,用三种格式
      1、INSERT INTO demo VALUES('');
      2、INSERT INTO demo VALUES(' ');
      3、INSERT INTO demo VALUES(NULL);
      INSERT INTO demo(tid,tname,tdate) VALUES

    (1,null,sysdate);
      INSERT INTO demo(tid,tname,tdate) VALUES(1,'',to_date

    (sysdate,'yyyy-mm-dd'));
      INSERT INTO demo VALUES(1,'',to_date

    ('2013/11/11','yyyy/mm/dd'));
     
      注意:
      1、字符串类型的字段值必须用单引号括起来,如:‘rain’;
      2、如果字段值里包含单引号需要进行字符串转换,把它替换成

    两个单引号‘’,如:‘''c''' 数据库中将插入‘c’;
      3、字符串类型的字段值超过定义长度会报错,最好在插入前进

    行长度校验;
      4、日期字段的字段值可以使用当前数据库的系统时间sysdate

    ,精确到秒;
      5、INSERT时如果要用到从1开始自动增长的序列号,应该先建

    立一个序列号。
     
     4.5.2 update 语句
      UPDATE table_name SET column_name=值 WHERE 查询条件
      UPDATE demo SET tname='张三' WHERE tid=1;
      COMMIT;------是更新生效
     4.5.3 delete 语句-----不能回退
      DELETE TABLE table_name;--------------只能删除数据,不

    能释放空间
      TRUNCATE TABLE table_name;---------------删除数据并释

    放空间
      DELETE TABLE demo;
      TRUNCATE TABLE demo;
      4.5.4 select 语句
      A 、简单的 Select 语句
      SELECT * FROM table_name;
      SELECT * FROM demo;
      B、空值 is null
      SELECT * FROM demo where tname is null;

    第五章 Select查询
    结构: 执行顺序
    SELECT * 5
           FROM table_name 1
                WHERE -----分组前的条件 2
       GROUP BY 3
    HAVING -----分组后的条件 4
                               ORDER BY column_name ASC/DESC;

    6
    -----------------------------
    子句、聚合函数、友好列 列名 AS 别名
    -----------------------------
    5.1 简单查询
    5.1.1 查看表结构
    DESC table_name;
    DESC emp;
     
    5.1.2查看所有的列
    SELECT * FROM table_name;
    SELECT * FROM emp;
     
    5.1.3 查看指定列
    SELECT 列名 FROM table_name;
    SELECT empno FROM emp;
    5.1.4 查看指定行
    SELECT * FROM table_name WHERE column_name=值;
    SELECT * FROM emp WHERE empno=7369;
    5.1.5 使用算术表达式 + 、- 、/ 、*
    SELECT ename,sal+1 FROM EMP;
    ENAME SAL+1
    ---------- ----------
    SMITH 801
    ALLEN 1601
    WARD 1251
    SELECT ename,sal-2 FROM EMP;
    ENAME SAL-1
    ---------- ----------
    SMITH 799
    ALLEN 1599
    WARD 1249
    SELECT ename,sal*2 FROM EMP;
    ENAME SAL*2
    ---------- ----------
    SMITH 1600
    ALLEN 3200
    WARD 2500
    SELECT ename,sal/2 FROM EMP;
    ENAME SAL/2
    ---------- ----------
    SMITH 400
    ALLEN 800
    WARD 625
    nvl(comm,0)的意思是,如果comm中有值,则nvl(comm,0)=comm;

    comm中无值,则nvl(comm,0)=0
    5.1.3 连接运算符 ||
    SELECT 'how'||'do' ||sno;
    5.1.4 使用字段别名 AS
    SELECT * FROM DEMO1 "Asd";-------带引号可以保证输入的结果

    有大小写
    SELECT * FROM DEMO1 asd;
    5.1.5 空值 IS NULL、 IS NOT NULL
    SQL>SELECT * FROM EMP WHERE COMM IS NOT NULL AND SAL IN

    (SELECT ENAME,sal FROM emp WHERE ENAME LIKE '_O%') ;
    5.1.6 去除重复行 DISTINCT
    SQL>SELECT DISTINCT DEPTNO FROM EMP ORDER BY DEPTNO
    SQL>SELECT DEPTNO FROM EMP GROUP BY DEPTNO ORDER BY

    DEPTNO
    5.1.7 查询结果排序 ORDER BY ASC/DESC
    逆序:
    SQL> SELECT * FROM emp WHERE job='CLERK' OR

    ename='MILLER' ORDER BY SAL DESC;
    顺序:
    SQL> SELECT * FROM emp WHERE job='CLERK' OR

    ename='MILLER' ORDER BY SAL ASC;
    SQL> SELECT * FROM emp WHERE job='CLERK' OR

    ename='MILLER' ORDER BY SAL ;
    5.1.8 关系运算符 >、 < 、=、(!= or <>) MOD(模,类似于%)、

    BETWEEN AND、 NOT BETWEEN AND
    SQL> SELECT DISTINCT MGR FROM emp WHERE MGR<>7788;
    SQL>SELECT DISTINCT MGR FROM emp WHERE MGR BETWEEN 7788

    AND 7902;
    SQL>SELECT * FROM emp WHERE MOD(DEPTNO,100)=2;
    SQL>SELECT * FROM EMP1 WHERE EMPNO NOT BETWEEN 7369 AND

    7521;
    SQL>SELECT * FROM EMP1 WHERE EMPNO>=7369 AND EMPNO<=7521;
    5.1.9 操作 IN、NOT IN
    SQL> SELECT ENAME,SAL FROM EMP WHERE SAL IN(SELECT MAX

    (SAL) FROM EMP1 GROUP BY DEPTNO);
    5.1.10 模糊查询 LIKE、NOT LIKE----只针对字符型
    % 表示零或多个字符
    _ 表示一个字符
    对于特殊符号可使用ESCAPE 标识符来查找
    select * from emp where ename like '%*_%' escape '*'
    上面的escape表示*后面的那个符号不当成特殊字符处理,就是查

    找普通的_符号
    5.1.11 逻辑运算符 AND、OR、NOT
    SQL> select * from emp where job='CLERK' OR

    ename='MILLER';
    SQL> select * from emp where job='CLERK' AND

    ename='MILLER';
    5.1.12 ANY、ALL
    SQL>SELECT * FROM EMP WHERE EMPNO IN(7369,7521,7782);
    SQL>SELECT * FROM EMP WHERE EMPNO>ANY(7369,7521,7782);--

    大于min
    SQL>SELECT * FROM EMP WHERE EMPNO>ALL(7369,7521,7782);--

    大于max
    SQL>SELECT * FROM EMP WHERE EMPNO<ANY(7369,7521,7782);--

    小于max
    SQL>SELECT * FROM EMP WHERE EMPNO<ALL(7369,7521,7782);--

    小于min
    5.1.13 练习
    1、选择在部门30中员工的所有信息
    Select * from emp where deptno=30;
    2、列出职位为(MANAGER)的员工的编号,姓名
    Select empno,ename from emp where job ="Manager";
    3、找出奖金高于工资的员工
    Select * from emp where comm>sal;
    4、找出每个员工奖金和工资的总和
    Select sal+comm,ename from emp;
    5、找出部门10中的经理(MANAGER)和部门20中的普通员工(CLERK)
    Select * from emp where (deptno=10 and job=?MANAGER?) or

    (deptno=20 and job=?CLERK?);
    6、找出部门10中既不是经理也不是普通员工,而且工资大于等于

    2000的员工
    Select * from emp where deptno=10 and job not in

    ('MANAGER') and sal>=2000;
    7、找出有奖金的员工的不同工作
    Select distinct job from emp where comm is not null and

    comm>0;
    8、找出没有奖金或者奖金低于500的员工
    Select * from emp where comm<500 or comm is null;
    9、显示雇员姓名,根据其服务年限,将最老的雇员排在最前面
    select ename from emp order by hiredate ;
    10、SQL>SELECT DEPTNO,MAX(SAL) AS tot,
                   MIN(COMM) AS MCOMM,
                   SUM(COMM) SUMC,
                   TRUNC(AVG(SAL+NVL(COMM,0)))TAVG,
                   ROUND(AVG(SAL+NVL(COMM,0)),2)RAVG,
                   COUNT(*)
           FROM EMP
                HAVING COUNT(*)>3
                      GROUP BY DEPTNO
                            ORDER BY DEPTNO
               
                11、SQL>SELECT ENAME,SAL
                    FROM EMP
                             WHERE SAL IN(SELECT MAX(SAL)
                                   FROM EMP1
                                                GROUP BY

    DEPTNO);
    5.2 多表查询
    INNER JOIN:内连接
    JOIN: 如果表中有至少一个匹配,则返回行
    LEFT JOIN: 即使右表中没有匹配,也从左表返回所有的行
    RIGHT JOIN: 即使左表中没有匹配,也从右表返回所有的行
    FULL JOIN: 只要其中一个表中存在匹配,就返回行
    5.2.1、笛卡尔集(Cross Join)------------列相加,行相乘
    Select * from emp,dept;
    5.2.2、等值连接(Equijoin)(Natural join..on)---------隐式

    内联
    select empno, ename, sal, emp.deptno, dname from emp,

    dept where emp.deptno = dept.deptno;
    5.2.3、非等值连接(Non-Equijoin)
    select ename,empno,grade from emp,salgrade where sal

    between losal and hisal;
    5.2.4、自联接(Self join)
    select column_name from table_name1,table_name2 where 条

    件;
    select e.empno,e.ename,m.empno,m.ename from emp e,emp m

    where m.mgr = e.empno;
    5.2.5、内联接(Inner Join)----------显式外联
    SELECT column_name(s)
    FROM table_name1
    INNER JOIN table_name2
    ON table_name1.column_name=table_name2.column_name
    5.2.6、 左外联接(Left Outer Join )
    左外连接:在内联接的基础上,增加左表中没有匹配的行,也就

    是说,左表中的记录总会出现在最终结果集中
    SELECT column_name(s)
    FROM table_name1
    LEFT JOIN table_name2
    ON table_name1.column_name=table_name2.column_name
    select s.sid,s.sname,s1.sid,s1.sname from student

    s,student1 s1 where s.sid=s1.sid(+);
    1、先通过from自句判断左表和右表;
    2、接着看加号作用在那个表别名上;
    3、如果作用在右表上,则为左外连接,否则为右外连接
    select empno,ename,dname from emp left outer join dept on

    emp.deptno = dept.deptno;
    5.2.7、右外联接(Right Outer Join)
    右外连接:在内联接的基础上,增加右表中没有匹配的行,也就

    是说,右表中的记录总会出现在最终结果集中
    SELECT column_name(s)
    FROM table_name1
    RIGHT JOIN table_name2
    ON table_name1.column_name=table_name2.column_name
    右外联接转换为内联接
    SELECT column_name(s)
    FROM table_name1
    RIGHT JOIN table_name2
    ON table_name1.column_name=table_name2.column_name WHERE

    table_name1.column_name is not null;
    select s.sid,s.sname,s1.sid,s1.sname from student

    s,student1 s1 where s.sid(+)=s1.sid;
    select empno,ename,dname from emp right outer join dept

    on emp.deptno= dept.deptno;
    select * from emp1 e right join dept d on

    e.deptno=d.deptno where e.deptno is not null;
    5.2.8、全外联接(Full Outer Join)
    SELECT column_name(s)
    FROM table_name1
    FULL JOIN table_name2
    ON table_name1.column_name=table_name2.column_name
    select empno,ename,dname from emp full outer join dept on

    emp.deptno = dept.deptno;
    5.2.9、集合操作
     · UNION:并集,所有的内容都查询,重复的显示一次
      ·UNION ALL:并集,所有的内容都显示,包括重复的
     · INTERSECT:交集:只显示重复的
     · MINUS:差集:只显示对方没有的(跟顺序是有关系的)
    SELECT column_name(s) FROM table_name1
    UNION/INTERSECT/MINUS
    SELECT column_name(s) FROM table_name2
    首先建立一张只包含 20 部门员工信息的表:
     CREATE TABLE emp20 AS SELECT * FROM emp WHERE deptno=20

    ;
    1、验证 UNION 及 UNION ALL
     UNION:SELECT * FROM emp UNION SELECT * FROM emp20 ;
     使用此语句重复的内容不再显示了
     UNION ALL:SELECT * FROM emp UNION ALL SELECT * FROM

    emp20 ;
     重复的内容依然显示
    2、验证 INTERSECT
     SELECT * FROM emp INTERSECT SELECT * FROM emp20 ; 只显示

    了两个表中彼此重复的记录。
     
    MINUS:返回差异的记录
     SELECT * FROM emp MINUS SELECT * FROM emp20 ; 只显示了两

    张表中的不同记录满链接也可以用以下的方式来表示:
    select t1.id,t2.id from table1 t1,table t2 where

    t1.id=t2.id(+) union
    select t1.id,t2.id from table1 t1,table t2 where t1.id

    (+)=t2.id
    5.3 子查询
    5.3.1、单行子查询
    select * from emp
    where sal > (select sal from emp where empno = 7566);
    5.3.2、 子查询空值/多值问题
    如果子查询未返回任何行,则主查询也不会返回任何结果
    (空值)select * from emp where sal > (select sal from emp

    where empno = 8888);
    如果子查询返回单行结果,则为单行子查询,可以在主查询中对

    其使用相应的单行记录比较运算符
    (正常)select * from emp where sal > (select sal from emp

    where empno = 7566);
    如果子查询返回多行结果,则为多行子查询,此时不允许对其使

    用单行记录比较运算符
    (多值)select * from emp where sal > (select avg(sal) from

    emp group by deptno);//非法----错误的
     
    5.3.3、 多行子查询
    select * from emp where sal > any(select avg(sal) from

    emp group by deptno);
    select * from emp where sal > all(select avg(sal) from

    emp group by deptno);
    select * from emp where job in (select job from emp where

    ename = 'MARTIN' or ename = 'SMITH');
    5.3.4、 分页查询
    Oracle分页
    ①采用rownum关键字(三层嵌套)
    SELECT * FROM(
      SELECT A.*,ROWNUM num FROM (
    SELECT * FROM t_order)A
    WHERE ROWNUM<=15)
    WHERE num>=5; --返回第5-15行数据
    ②采用row_number解析函数进行分页(效率更高)
    SELECT xx.* FROM(
    SELECT t.*,row_number() over(ORDER BY o_id)AS num
    FROM t_order t
    )xx
    WHERE num BETWEEN 5 AND 15;
    ROWID和ROWNUM的区别
    1、ROWID是物理地址,用于定位ORACLE中具体数据的物理存储位

    置是唯一的18位物理编号,而ROWNUM则是根据sql查询后得到的结

    果自动加上去的
    2、ROWNUM是暂时的并且总是从1开始排起,而ROWID是永久的。
    解析函数能用格式
    函数() over(pertion by 字段 order by 字段);
    ROW_NUMBER(): Row_number函数返回一个唯一的值,当碰到相同

    数据时,排名按照记录集中记录的顺序依次递增。 row_number()

    和rownum差不多,功能更强一点(可以在各个分组内从1开时排序

    ),因为row_number()是分析函数而rownum是伪列所以

    row_number()一定要over而rownum不能over。
    RANK():Rank函数返回一个唯一的值,除非遇到相同的数据,此

    时所有相同数据的排名是一样的,同时会在最后一条相同记录和

    下一条不同记录的排名之间空出排名。rank()是跳跃排序,有两

    个第二名时接下来就是第四名(同样是在各个分组内)。
    DENSE_RANK():Dense_rank函数返回一个唯一的值,除非当碰到

    相同数据,此时所有相同数据的排名都是一样的。
    dense_rank()是连续排序,有两个第二名时仍然跟着第三名。他

    和row_number的区别在于row_number是没有重复值的。
    dense_rank()是连续排序,有两个第二名时仍然跟着第三名。他

    和row_number的区别在于row_number是没有重复值的。
     下面举个例子:
    SQL> select * from user_order order by customer_sales;
     REGION_ID CUSTOMER_ID CUSTOMER_SALES
    ---------- ----------- --------------
            10 30 1216858
             5 2 1224992
             9 24 1224992
             9 23 1224992
             8 18 1253840
    【3】row_number()、rank()、dense_rank()这三个分析函数的区

    别实例
    SQL>SELECT empno, deptno, SUM(sal) total,
               RANK() OVER(ORDER BY SUM(sal) DESC) RANK,
               dense_rank() OVER(ORDER BY SUM(sal) DESC)

    dense_rank,
               row_number() OVER(ORDER BY SUM(sal) DESC)

    row_number
    FROM emp1 GROUP BY empno, deptno;
    --------------------------------------------------
    1 7839 10 5000 1 1 1
    2 7902 20 3000 2 2 2
    3 7788 20 3000 2 2 3
    4 7566 20 2975 4 3 4
    5 7698 30 2850 5 4 5
    6 7782 10 2450 6 5 6
    7 7499 30 1600 7 6 7
    比较上面3种不同的策略,我们在选择的时候就要根据客户的需求

    来定夺了:
    ①假如客户就只需要指定数目的记录,那么采用row_number是最

    简单的,但有漏掉的记录的危险
    ②假如客户需要所有达到排名水平的记录,那么采用rank或

    dense_rank是不错的选择。至于选择哪一种则看客户的需要,选

    择dense_rank或得到最大的记录
    Mysql分页采用limt关键字
    select * from t_order limit 5,10; #返回第6-15行数据
    select * from t_order limit 5; #返回前5行
    select * from t_order limit 0,5; #返回前5行
    Mssql 2000分页采用top关键字(20005以上版本也支持关键字

    rownum)
    Select top 10 * from t_order where id not in (select id

    from t_order where id>5 ); //返回第6到15行数据其中10表示

    取10记录 5表示从第5条记录开始取
    sql server 分页采用top关键字
    5.3.5、 in 、exists
    EXISTS 的执行流程
    select * from t1 where exists ( select null from t2 where

    y = x )
    可以理解为:
      for x in ( select * from t1 ) loop
     if ( exists ( select null from t2 where y = x.x ) then
            OUTPUT THE RECORD
     end if;
     end loop;
    对于 in 和 exists 的性能区别:
      如果子查询得出的结果集记录较少,主查询中的表较大且又有

    索引时应该用 in,反之如果外层的主查询记录较少,子查询中的

    表大,又有索引时使用 exists。
      其实我们区分 in 和 exists 主要是造成了驱动顺序的改变(

    这是性能变化的关键),如果是 exists,那么以外层表为驱动表

    ,先被访问,如果是 IN,那么先执行子查询,所以我们会以驱动

    表的快速返回为目标,那么就会考虑到索引及结果集的关系了 另

    外 IN 是不对 NULL 进行处理
    如:
    select 1 from dual where not in (0,1,2,null) 为空
    第六章 约束
    约束就是指对插入数据的各种限制,例如:人员的姓名不能为空

    ,人的年龄只能在0~150 岁之间。约束可以对数据库中的数据进

    行保护。 约束可以在建表的时候直接声明,也可以为已建好的表

    添加约束。
     
    6.1、NOT NULL:非空约束 例如:姓名不能为空
    CREATE TABLE person(
    pid NUMBER ,
    name VARCHAR2(30) NOT NULL
    ) ;
     
    alter table emp
    -- 插入数据
    INSERT INTO person(pid,name) VALUES (11,'张三');
    -- 错误的数据,会受到约束限制,无法插入
    INSERT INTO person(pid) VALUES (12);
     
    6.2、 PRIMARY KEY:主键约束
     · 不能重复,不能为空 · 例如:身份证号不能为空。 现在假

    设pid字段不能为空,且不能重复。
    DROP TABLE person ;
    CREATE TABLE person
    (
     pid NUMBER PRIMARY KEY , name VARCHAR(30) NOT NULL
    ) ;
    -- 插入数据
    INSERT INTO person(pid,name) VALUES (11,'张三');
    -- 主键重复了
    INSERT INTO person(pid,name) VALUES (11,'李四');
     
    6.3、UNIQUE:唯一约束,值不能重复(空值除外) 人员中有电

    话号码,电话号码不能重复。
    DROP TABLE person ;
    CREATE TABLE person
    (
     pid NUMBER PRIMARY KEY NOT NULL , name VARCHAR(30) NOT

    NULL , tel VARCHAR(50) UNIQUE
    ) ;
    -- 插入数据
    INSERT INTO person(pid,name,tel) VALUES (11,'张

    三','1234567');
    -- 电话重复了
    INSERT INTO person(pid,name,tel) VALUES (12,'李

    四','1234567');
     
    6.4、CHECK:条件约束,插入的数据必须满足某些条件
     例如:人员有年龄,年龄的取值只能是 0~150 岁之间
    DROP TABLE person ;
    CREATE TABLE person(
       pid NUMBER PRIMARY KEY NOT NULL ,
     name VARCHAR2(30) NOT NULL ,
    tel VARCHAR2(50) NOT NULL UNIQUE ,
    age NUMBER CHECK(age BETWEEN 0 AND 150)
    ) ;
    -- 插入数据
    INSERT INTO person(pid,name,tel,age) VALUES (11,'张

    三','1234567',30);
    -- 年龄的输入错误
    INSERT INTO person(pid,name,tel,age) VALUES (12,'李

    四','2345678',-100);
     alter table product
    add constriant chk_product_unitprice check(unitprice>0);
    6.5、Foreign Key:外键
     例如:有以下一种情况:
     · 一个人有很多本书:
      |- Person 表
      |- Book 表:而且book 中的每一条记录表示一本书的信息,一

    本书的信息属于一个人
    CREATE TABLE book(
     bid NUMBER PRIMARY KEY NOT NULL ,
     name VARCHAR(50) ,
     -- 书应该属于一个人 pid NUMBER
    ) ;
     如果使用了以上的表直接创建,则插入下面的记录有效:
    INSERT INTO book(bid,name,pid) VALUES(1001,'JAVA',12) ;
     以上的代码没有任何错误,但是没有任何意义,因为一本书应该

    属于一个人,所以在此处的pid的取值应该与person 表中的pid一

    致。
     此时就需要外键的支持。修改book 的表结构
    DROP TABLE book ;
    CREATE TABLE book
    (
     bid NUMBER PRIMARY KEY NOT NULL , name VARCHAR(50) ,
     -- 书应该属于一个人 pid NUMBER REFERENCES person(pid) ON

    DELETE CASCADE
     -- 建立约束:book_pid_fk,与person中的pid 为主-外键关系
     --CONSTRAINT book_pid_fk FOREIGN KEY(pid) REFERENCES

    person(pid)
    ) ;
     
    INSERT INTO book(bid,name,pid) VALUES(1001,'JAVA',12) ;
    6.6、级联删除
     此时如果想完成删除person 表的数据同时自动删除掉book 表的

    数据操作,则必须使用级联删除。
     在建立外键的时候必须指定级联删除(ON DELETE CASCADE)。
    CREATE TABLE book
    (
     bid NUMBER PRIMARY KEY NOT NULL , name VARCHAR(50) ,
     -- 书应该属于一个人
     pid NUMBER ,
     -- 建立约束:book_pid_fk,与person中的pid 为主-外键关系
     CONSTRAINT book_pid_fk FOREIGN KEY(pid) REFERENCES

    person(pid) ON DELETE CASCADE
    ) ;
    DROP TABLE book ;
    DROP TABLE person ;
    CREATE TABLE person(
          pid NUMBER ,
          name VARCHAR(30) NOT NULL ,
          tel VARCHAR(50) ,
          age NUMBER
    ) ;
    CREATE TABLE book(
          bid NUMBER ,
          name VARCHAR2(50) ,
          pid NUMBER
    ) ;
     
     以上两张表中没有任何约束,下面使用 alter 命令为表添加约


    ALTER TABLE table_name ADD CONSTRAINT column_name 约束;
    1、 为两个表添加主键:
      · person 表 pid 为主键:
       ALTER TABLE person ADD CONSTRAINT person_pid_pk

    PRIMARY KEY(pid) ;
      · book 表 bid 为主键:
       ALTER TABLE book ADD CONSTRAINT book_bid_pk PRIMARY

    KEY(bid) ;
    2、 为 person 表中的 tel 添加唯一约束:
      ALTER TABLE person ADD CONSTRAINT person_tel_uk UNIQUE

    (tel) ;
    3、 为 person 表中的 age 添加检查约束:
      ALTER TABLE person ADD CONSTRAINT person_age_ck CHECK

    (age BETWEEN 0 AND
    150) ;
     4、 为 book 表中的 pid 添加与 person 的主-外键约束,要求

    带级联删除
      ALTER TABLE book ADD CONSTRAINT person_book_pid_fk

    FOREIGN KEY (pid)
    REFERENCES person(pid) ON DELETE CASCADE ;
     
    Q:如何用alter添加非空约束
    A:用 check约束
    6.7、删除约束:
     ALTER TABLE book DROP CONSTRAINT person_book_pid_fk ;
    alter table student drop unique(tel);
    6.8、 启用约束
    ALTER TABLE book enable CONSTRAINT person_book_pid_fk ;
    6.9、 禁用约束
    ALTER TABLE book disable CONSTRAINT person_book_pid_fk ;
    第七章 SQL函数
    7.1 单行函数
    1、字符函数
    Upper -------大写
    SELECT Upper ('abcde') FROM dual ;
    SELECT * FROM emp WHERE ename=UPPER('smith') ;
    Lower --------小写
    SELECT lower('ABCDE') FROM dual ;
    Initcap--------首字母大写
    Select initcap(ename) from emp;
    Concat----联接
    Select concat('a','b') from dual;
    Select 'a'||'b' from dual;
    Substr------截取
    Select substr('abcde',length('abcde')-2) from dual;
    Select substr('abcde',-3,3) from dual;
    Length------长度
    Select length(ename) from emp;
    Replace------替代
    Select replace(ename,'a','A') from emp;
    Instr---------- indexof
    Select instr('Hello World','or') from dual;
    Lpad------------左侧填充 lpad() *****Smith
    lpad('Smith',10,'*')
    Rpad-------------右侧填充 rpad()Smith*****
    rpad('Smith',10,'*')
    Trim-------------过滤首尾空格 trim() Mr Smith
    trim(' Mr Smith ')
    2、数值函数
    Round
    select round(412,-2) from dual; --400
    select round(412.313,2) from dual;
    Mod
    select MOD(412,3) from dual;
    Trunc
    select trunc(412.13,-2) from dual;
    3、日期函数
    Months_between()
    select months_between(sysdate,hiredate) from emp;
    Add_months()
    select add_months(sysdate,1) from dual;
    Next_day()
    select next_day(sysdate,'星期一') from dual;
    Last_day
    select last_day(sysdate) from dual;
    4.4、转换函数
    To_char
    select to_char(sysdate,'yyyy') from dual; select to_char

    (sysdate,'fmyyyy-mm-dd') from dual; select to_char

    (sal,'L999,999,999') from emp; select to_char(sysdate,’D

    ’) from dual;//返回星期
    To_number
    select to_number('13')+to_number('14') from dual;
    To_date
    Select to_date(?20090210?,?yyyyMMdd?) from dual;
    5、通用函数
    NVL()函数
    select nvl(comm,0) from emp;
    NULLIF()函数
    如果表达式 exp1 与 exp2 的值相等则返回 null,否则返回

    exp1 的值
    NVL2()函数 select empno, ename, sal, comm, nvl2(comm,

    sal+comm, sal) total from emp;
    COALESCE()函数
    依次考察各参数表达式,遇到非 null 值即停止并返回该值。
    select empno, ename, sal, comm, coalesce(sal+comm, sal,

    0)总收入 from emp;
    CASE 表达式------区间
    SQL>select empno,
              ename,
              sal,
              case deptno
    when 10 then '财务部'
    when 20 then '研发部'
    when 30 then '销售部'
    else '未知部门'
    end 部门
    from emp;
    SQL>SELECT e.*,
        CASE
            WHEN sal>=3000 THEN '高'
            WHEN sal>=2000 AND sal<3000 THEN '中'
            WHEN sal<2000 AND sal>0 THEN '高'
            ELSE 'un'
         END ca
    FROM emp1 e;
    DECODE()函数------------离散的值
    SQL>select empno, ename, sal,
        decode(deptno,
                                    10, '财务部',
                                    20, '研发部',
                                    30, '销售部',
                                    '未知部门') 部门
    from emp;
     
    单行函数嵌套
    select empno, lpad(initcap(trim(ename)),10,' ') name,

    job, sal from emp;
    7.2 分组函数
    1、COUNT
    如果数据库表的没有数据,count(*)返回的不是 null,而是 0
    2、Avg,max,min,sum
    3、nvl----分组函数与空值
    分组函数省略列中的空值
    select avg(comm) from emp; select sum(comm) from emp;
    可使用 NVL()函数强制分组函数处理空值 select avg(nvl(comm,

    0)) from emp;
    4、GROUP BY 子句
    出现在 SELECT 列表中的字段或者出现在 order by 后面的字段

    ,如果不是包含在分组函数中,那么该字段必须同时在 GROUP BY

    子句中出现。包含在 GROUP BY 子句中的字段则不必须出现在

    SELECT 列表中。
    可使用 where 字句限定查询条件,可使用 Order by 子句指定排

    序方式
    如果没有 GROUP BY 子句,SELECT 列表中不允许出现字段(单行

    函数)与分组函数混用的情况。
    select empno, sal from emp; //合法 select avg(sal) from

    emp; //合法 select empno, initcap(ename), avg(sal) from

    emp; //非法
     不允许在 WHERE 子句中使用分组函数。 select deptno, avg

    (sal) from emp where avg(sal) > 2000; group by deptno;
    5、HAVING 子句
    select deptno, job, avg(sal)
    from emp
    where hiredate >= to_date('1981-05-01','yyyy-mm-dd')

    group by deptno,job having avg(sal) > 1200 order by

    deptno,job;
    6、分组函数嵌套
    select max(avg(sal)) from emp group by deptno;
     
    第八章 PLSQL变量与常量
    1、声明变量
      变量一般都在PL/SQL块的声明部分声明,引用变量前必须首

    先声明,要在执行或异常处理部分使用变量,那么变量必须首先

    在声明部分进行声明。
      声明变量的语法如下:
    Variable_name [CONSTANT] databyte [NOT NULL][:=|DEFAULT

    expression]
         注意:可以在声明变量的同时给变量强制性的加上NOT NULL

    约束条件,此时变量在初始化时必须赋值。
    2、给变量赋值
      给变量赋值有两种方式:
      . 直接给变量赋值
       X:=200;
       Y=Y+(X*20);
      . 通过SQL SELECT INTO 或FETCH INTO给变量赋值
    SELECT SUM(SALARY),SUM(SALARY*0.1)
    INTO TOTAL_SALARY,TATAL_COMMISSION
    FROM EMPLOYEE
    WHERE DEPT=10;
    3、常量
      常量与变量相似,但常量的值在程序内部不能改变,常量的

    值在定义时赋予,,他的声明方式与变量相似,但必须包括关键

    字CONSTANT。常量和变量都可被定义为SQL和用户定义的数据类型


    ZERO_VALUE CONSTANT NUMBER:=0;
    4、标量(scalar)数据类型
      标量(scalar)数据类型没有内部组件,他们大致可分为以下

    四类:
       . number
    . char
    . date/time
    . boolean
      表1 Numer
    Datatype Range Subtypes description
    BINARY_INTEGER -214748-2147483647 NATURAL
    NATURAL
    NPOSITIVE
    POSITIVEN
    SIGNTYPE
    用于存储单字节整数。
    要求存储长度低于NUMBER值。
    用于限制范围的子类型(SUBTYPE):
     NATURAL:用于非负数
     POSITIVE:只用于正数
     NATURALN:只用于非负数和非NULL值
     POSITIVEN:只用于正数,不能用于NULL值
     SIGNTYPE:只有值:-1、0或1.
    NUMBER 1.0E-130-9.99E125 DEC
    DECIMAL
    DOUBLE
    PRECISION
    FLOAT
    INTEGERIC
    INT
    NUMERIC
    REAL
    SMALLINT 存储数字值,包括整数和浮点数。可以选择精度和刻度

    方式,语法:
    number[([,])]。
    缺省的精度是38,scale是0.
    PLS_INTEGER -2147483647-2147483647 与BINARY_INTEGER基本相

    同,但采用机器运算时,PLS_INTEGER提供更好的性能 。
      表2 字符数据类型
    datatype rang subtype description
    CHAR 最大长度32767字节 CHARACTER 存储定长字符串,如果长度

    没有确定,缺省是1
    LONG 最大长度2147483647字节 存储可变长度字符串
    RAW 最大长度32767字节 用于存储二进制数据和字节字符串,当

    在两个数据库之间进行传递时,RAW数据不在字符集之间进行转换


    LONGRAW 最大长度2147483647 与LONG数据类型相似,同样他也不

    能在字符集之间进行转换。
    ROWID 18个字节 与数据库ROWID伪列类型相同,能够存储一个行

    标示符,可以将行标示符看作数据库中每一行的唯一键值。
    VARCHAR2 最大长度32767字节 STRINGVARCHAR 与VARCHAR数据类

    型相似,存储可变长度的字符串。声明方法与VARCHAR相同
      表3 DATE和BOOLEAN
    datatype range description
    BOOLEAN TRUE/FALSE 存储逻辑值TRUE或FALSE,无参数
    DATE 01/01/4712 BC 存储固定长的日期和时间值,日期值中包含

    时间
    LOB数据类型
      LOB(大对象,Large object) 数据类型用于存储类似图像,声

    音这样的大型数据对象,LOB数据对象可以是二进制数据也可以是

    字符数据,其最大长度不超过4G。LOB数据类型支持任意访问方式

    ,LONG只支持顺序访问方式。LOB存储在一个单独的位置上,同时

    一个"LOB定位符"(LOB locator)存储在原始的表中,该定位符是

    一个指向实际数据的指针。在PL/SQL中操作LOB数据对象使用

    ORACLE提供的包DBMS_LOB.LOB数据类型可分为以下四类:
      . BFILE----------------二进制文件
      . BLOB--------------二进制对象
      . CLOB---------------字符型对象
      . NCLOB-------------nchar类型对象
    操作符
      PL/SQL有一系列操作符。操作符分为下面几类:
      . 算术操作符
      . 关系操作符
      . 比较操作符
      . 逻辑操作符
      算术操作符如表4所示
    operator operation
    + 加
    - 减
    / 除
    * 乘
    ** 乘方
      关系操作符主要用于条件判断语句或用于where子串中,关系

    操作符检查条件和结果是否为true或false,
    表5PL/SQL中的关系操作符
    operator operation
    < 小于操作符
    <= 小于或等于操作符
    > 大于操作符
    >= 大于或等于操作符
    = 等于操作符
    != 不等于操作符
    <> 不等于操作符
    := 赋值操作符
      表6 显示的是比较操作符
    operator operation
    IS NULL 如果操作数为NULL返回TRUE
    LIKE 比较字符串值
    BETWEEN 验证值是否在范围之内
    IN 验证操作数在设定的一系列值中
      表7显示的是逻辑操作符
    operator operation
    AND 两个条件都必须满足
    OR 只要满足两个条件中的一个
    NOT 取反
    第九章 PL/SQL--------动态SQL
    PL/SQL动态SQL(原创)
    概念:动态SQL,编译阶段无法明确SQL命令,只有在运行阶段才

    能被识别
    动态SQL和静态SQL两者的异同
    静态SQL为直接嵌入到PL/SQL中的代码,而动态SQL在运行时,根

    据不同的情况产生不同的SQL语句。
    静态SQL在执行前编译,一次编译,多次运行。动态SQL同样在执

    行前编译,但每次执行需要重新编译。
    静态SQL可以使用相同的执行计划,对于确定的任务而言,静态

    SQL更具有高效性,但缺乏灵活性;动态SQL使用了不同的执行计

    划,效率不如静态SQL,但能够解决复杂的问题。
    动态SQL容易产生SQL注入,为数据库安全带来隐患。
    动态SQL语句的几种方法
    a.使用EXECUTE IMMEDIATE语句
    包括DDL语句,DCL语句,DML语句以及单行的SELECT 语句。该方

    法不能用于处理多行查询语句。
    b.使用OPEN-FOR,FETCH和CLOSE语句
    对于处理动态多行的查询操作,可以使用OPEN-FOR语句打开游标

    ,使用FETCH语句循环提取数据,最终使用CLOSE语句关闭游标。
    c.使用批量动态SQL
    即在动态SQL中使用BULK子句,或使用游标变量时在fetch中使用

    BULK ,或在FORALL语句中使用BULK子句来实现。
    d.使用系统提供的PL/SQL包DBMS_SQL来实现动态SQL
     
    动态SQL的语法
    下面是动态SQL常用的语法之一
    EXECUTE IMMEDIATE dynamic_SQL_string
    [INTO defined_variable1, defined_variable2, ...]
    [USING [IN | OUT | IN OUT] bind_argument1,

    bind_argument2,...]
    [{RETURNING | RETURN} field1, field2, ... INTO

    bind_argument1,
    bind_argument2, ...]
    语法描述
    dynamic_SQL_string:存放指定的SQL语句或PL/SQL块的字符串变


    defined_variable1:用于存放单行查询结果,使用时必须使用

    INTO关键字,类似于使用
    SELECT ename INTO v_name FROM scott.emp;
    只不过在动态SQL时,将INTO defined_variable1移出到

    dynamic_SQL_string语句之外。
    bind_argument1:用于给动态SQL语句传入或传出参数,使用时必

    须使用USING关键字,IN表示传入的参数,OUT表示传出的参数,

    IN OUT则既可以传入,也可传出。
    RETURNING | RETURN 子句也是存放SQL动态返回值的变量。
    使用要点
    a.EXECUTE IMMEDIATE执行DML时,不会提交该DML事务,需要使用

    显示提交(COMMIT)或作为EXECUTE IMMEDIATE自身的一部分。
    b.EXECUTE IMMEDIATE执行DDL,DCL时会自动提交其执行的事务。
    c.对于多行结果集的查询,需要使用游标变量或批量动态SQL,或

    者使用临时表来实现。
    d.当执行SQL时,其尾部不需要使用分号,当执行PL/SQL 代码时

    ,其尾部需要使用分号。
    f.动态SQL中的占位符以冒号开头,紧跟任意字母或数字表示。
    动态SQL的使用(DDL,DCL,DML以及单行结果集)
    DECLARE
      v_table VARCHAR2(30):='emp1';
      v_sql LONG:='SELECT ename FROM emp1 WHERE empno=:1';--

    占位符\可以用任何符号(数字或字母)
      --v_no emp1.empno%TYPE:='&请输入号码';--&是变量绑定符

    绑定的数据是字符串类型时必须要加引号
      --v_no emp1.empno%TYPE:=&请输入号码;
      v_name emp1.ename%TYPE;
    BEGIN
      --EXECUTE IMMEDIATE v_sql INTO v_name USING IN v_no;
      dbms_output.put_line('ename='||v_name);
      --EXECUTE IMMEDIATE 'create table emp2 as select * from

    emp';
      --EXECUTE IMMEDIATE 'drop table '||v_table;
      --EXECUTE IMMEDIATE 'alter table emp enable row

    movement';
    END;
    BULK子句和动态SQL的使用
    动态SQL中使用BULK子句的语法
    EXECUTE IMMEDIATE dynamic_string --dynamic_string用于存放

    动态SQL字符串
    [BULK COLLECT INTO define_variable[,define_variable...]]

    --存放查询结果的集合变量
    [USING bind_argument[,argument...]] --使用参数传递给动态

    SQL
    [{RETURNING | RETURN} --返回子句
    BULK COLLECT INTO return_variable[,return_variable...]];

    --存放返回结果的集合变量
    使用bulk collect into子句处理动态SQL中T的多行查询可以加快

    处理速度,从而提高应用程序的性能。当使用bulk子句时,集合

    类型可以是PL/SQL所支持的索引表、嵌套表和VARRY,但集合元

    素必须使用SQL数据类型。常用的三种语句支持BULK子句,分别为

    EXECUTE IMMEDIATE,FETCH 和FORALL。
    使用EXECUTE IMMEDIATE 结合BULK子句处理多行查询。使用了

    BULK COLLECT INTO来传递结果。
    SQL>declare
      type ename_table_type is table of emp1.ename%type index

    by binary_integer;
      type sal_table_type is table OF emp1.sal%type index by

    binary_integer;
         ename_table ename_table_type;
         sal_table sal_table_type;
         sql_stat varchar2(100);
         v_dno number := 7369;
    begin
        sql_stat := 'select ename,sal from emp1 where deptno

    = :v_dno'; --动态DQL语句,未使用RETURNING子句
        execute immediate sql_stat
        bulk collect into ename_table,sal_table using v_dno;
        for i in 1..ename_table.count loop
            dbms_output.put_line('Employee ' || ename_table

    (i) || ' Salary is: ' || sal_table(i));
        end loop;
    end;
    使用FETCH子句结合BULK子句处理多行结果集
    下面的示例中首先定义了游标类型,游标变量以及复合类型,复

    合变量,接下来从动态SQL中OPEN游标,然后使用FETCH将结果存

    放到复合变量中。即使用OPEN,FETCH代替了EXECUTE IMMEDIATE

    来完成动态SQL的执行。
    SQL> declare
      2 type empcurtype is ref cursor;
      3 emp_cv empcurtype;
      4 type ename_table_type is table of tb2.ename%type

    index by binary_integer;
      5 ename_table ename_table_type;
      6 sql_stat varchar2(120);
      7 begin
      8 sql_stat := 'select ename from tb2 where deptno =

    :dno';
      9 open emp_cv for sql_stat using &dno;
     10 fetch emp_cv bulk collect into ename_table;
     11 for i in 1..ename_table.count loop
     12 dbms_output.put_line('Employee Name: ' ||

    ename_table(i));
     13 end loop;
     14 close emp_cv;
     15* end;
    在FORALL语句中使用BULK子句
    下面是FORALL子句的语法
    FORALL index IN lower bound..upper bound --FORALL循环计数
    EXECUTE IMMEDIATE dynamic_string --结合EXECUTE IMMEDIATE

    来执行动态SQL语句
    USING bind_argument | bind_argument(index) --绑定输入参数
    [bind_argument | bind_argument(index)]...
    [{RETURNING | RETURN} BULK COLLECT INTO bind_argument

    [,bind_argument...]]; --绑定返回结果集
    FORALL子句允许为动态SQL输入变量,但FORALL子句仅支持的DML

    (INSERT,DELETE,UPDATE)语句,不支持动态的SELECT语句。
    下面的示例中,首先声明了两个复合类型以及复合变量,接下来

    为复合变量ename_table赋值,以形成动态SQL语句。紧接着使用

    FORALL子句结合EXECUTE IMMEDIATE 来提取结果集。
    SQL> declare
      2 type ename_table_type is table of tb2.ename%type;
      3 type sal_table_type is table of tb2.sal%type;
      4 ename_table ename_table_type;
      5 sal_table sal_table_type;
      6 sql_stat varchar2(100);
      7 begin
      8 ename_table := ename_table_type

    ('BLAKE','FORD','MILLER');
      9 sql_stat := 'update tb2 set sal = sal * 1.1 where

    ename = :1'
     10 || ' returning sal into :2';
     11 forall i in 1..ename_table.count
     12 execute immediate sql_stat using ename_table(i)

    returning bulk collect into sal_table;
     13 for j in 1..sal_table.count loop
     14 dbms_output.put_line('The ' || ename_table(j) || ''''

    || 's new salalry is ' || sal_table(j));
     15 end loop;
     16* end;
    常见错误
    1、使用动态DDL时,不能使用绑定变量。
    EXECUTE IMMEDIATE 'CREATE TABLE dsa '||'as select * from

    :1' USING IN v_table;
    解决办法,将绑定变量直接拼接,如下:
    EXECUTE IMMEDIATE 'CREATE TABLE dsa '||'as select * from

    '|| v_table;
    2、不能使用schema对象作为绑定参数,下面的示例中,动态SQL

    语句查询需要传递表名,因此收到了错误提示。
    EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM:tb_name ' into

    v_count;
    解决办法,将绑定变量直接拼接,如下:
    EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM ' || tb_name into

    v_count;
    3、动态SQL块不能使用分号结束(;)
      execute immediate 'select count(*) from emp;' --此处多

    出了分号,应该去掉
     
    4、动态PL/SQL块不能使用正斜杠来结束块,但是块结尾处必须要

    使用分号(;)
    SQL> declare
      2 plsql_block varchar2(300);
      3 begin
      4 plsql_block := 'Declare ' ||
      5 ' v_date date; ' ||
      6 ' begin ' ||
      7 ' select sysdate into v_date from dual; ' ||
      8 ' dbms_output.put_line(to_char(v_date,''yyyy-mm-

    dd'')); ' ||
      9 ' end;
     10 /'; --此处多出了/,应该将其去掉
     11 execute immediate plsql_block;
     12* end;
    4、空值传递的问题
    下面的示例中对表tb_emp更新,并将空值更新到sal列,直接使用

    USING NULL收到错误提示。
      execute immediate sql_stat using null,v_empno;
    正确的处理方法
        v_sal tb2.sal%type; --声明一个新变量,但不赋值
        execute immediate sql_stat using v_sal,v_empno;
    5、日期和字符型必须要使用引号来处理
    DECLARE
      sql_stat VARCHAR2(100);
      v_date DATE :=TO_DATE('2013-11-21','yyyy-mm-dd');
      v_empno NUMBER :=7900;
      v_ename emp.ename%TYPE;
      v_sal emp.sal%TYPE;
    BEGIN
      sql_stat := 'SELECT ename,sal FROM emp WHERE

    hiredate=:v_date';
      EXECUTE IMMEDIATE sql_stat
      INTO v_ename,v_sal
      USING v_date;
      DBMS_OUTPUT.PUT_LINE('Employee Name '||v_ename||', sal

    is '||v_sal);
    END;
    6、单行SELECT 查询不能使用RETURNING INTO返回
    下面的示例中,使用了动态的单行SELECT查询,并且使用了

    RETURNING子句来返回值。事实上,RETURNING coloumn_name

    INTO 子句仅仅支持对DML结果集的返回,因此,收到了错误提示


    SQL>declare
    v_empno emp.empno%type := &empno;
     v_ename emp.ename%type;
    begin
     execute immediate 'select ename from emp where empno =

    :eno' into v_ename using v_empno;
     dbms_output.put_line('Employee name: ' || v_ename);
    end;
    第十章 PL/SQL---------游标
    游标的使用
        在 PL/SQL 程序中,对于处理多行记录的事务经常使用游标

    来实现。
    4.1 游标概念
    对于不同的SQL语句,游标的使用情况不同:
    SQL语句
    游标
    非查询语句
    隐式的
    结果是单行的查询语句
    隐式的或显示的
    结果是多行的查询语句
    显示的
    游标名%属性名
    显式游标的名字右用户定义,隐式游标名为SQL
    隐式游标只是一个状态
    4.1.1 处理显式游标
     
    1. 显式游标处理
    语法格式:
    CURSOR cursor_name is select * from emp;
    OPEN cursor_name;
    FETCH cursor_name INTO variables_list;
    CLOSE cursor_name;
    例1:
    DECLARE
      v_deptno NUMBER:=&inputno;
      v_row emp1%ROWTYPE;
      CURSOR v_cursor IS SELECT * FROM emp1 WHERE

    deptno=v_deptno;
    BEGIN
      --打开
      OPEN v_cursor;
      --提取
      LOOP
        FETCH v_cursor INTO v_row;--先提取
        EXIT WHEN v_cursor%NOTFOUND;
        dbms_output.put_line('Employee Name: ' || v_row.ename

    || ' ,Salary: ' || v_row.sal);
      END LOOP;
      --关闭
      CLOSE v_cursor;
    END;
    显式游标处理需四个 PL/SQL步骤:
    l 定义/声明游标:就是定义一个游标名,以及与其相对应的

    SELECT 语句。
    格式:
     
        CURSOR cursor_name[(parameter[, parameter]…)]
               
               [RETURN datatype]
        IS
            select_statement;
            select_statement;
     
    游标参数只能为输入参数,其格式为:
     
    parameter_name [IN] datatype [{:= | DEFAULT} expression]
    在指定数据类型时,不能使用长度约束。如NUMBER(4),CHAR(10)

    等都是错误的。
    [RETURN datatype]是可选的,表示游标返回数据的数据。如果选

    择,则应该严格与select_statement中的选择列表在次序和数据

    类型上匹配。一般是记录数据类型或带“%ROWTYPE”的数据。
     
    l 打开游标:就是执行游标所对应的SELECT 语句,将其查询结果

    放入工作区,并且指针指向工作区的首部,标识游标结果集合。

    如果游标查询语句中带有FOR UPDATE选项,OPEN 语句还将锁定数

    据库表中游标结果集合对应的数据行。
    格式:
     
    OPEN cursor_name[([parameter =>] value[, [parameter =>]

    value]…)];
     
    在向游标传递参数时,可以使用与函数参数相同的传值方法,即

    位置表示法和名称表示法。PL/SQL 程序不能用OPEN 语句重复打

    开一个游标。
     
    l 提取游标数据:就是检索结果集合中的数据行,放入指定的输

    出变量中。
    格式:
     
    FETCH cursor_name INTO {variable_list | record_variable

    };
     
    执行FETCH语句时,每次返回一个数据行,然后自动将游标移动指

    向下一个数据行。当检索到最后一行数据时,如果再次执行FETCH

    语句,将操作失败,并将游标属性%NOTFOUND置为TRUE。所以每次

    执行完FETCH语句后,检查游标属性%NOTFOUND就可以判断FETCH语

    句是否执行成功并返回一个数据行,以便确定是否给对应的变量

    赋了值。
    l 对该记录进行处理;
    l 继续处理,直到活动集合中没有记录;
    l 关闭游标:当提取和处理完游标结果集合数据后,应及时关闭

    游标,以释放该游标所占用的系统资源,并使该游标的工作区变

    成无效,不能再使用FETCH 语句取其中数据。关闭后的游标可以

    使用OPEN 语句重新打开。
    格式:
     
    CLOSE cursor_name;
     
         注:定义的游标不能有INTO 子句。
     
    例1. 查询前10名员工的信息。
    DECLARE
       CURSOR c_cursor
       IS SELECT first_name || last_name, Salary FROM

    EMPLOYEES WHERE rownum<11;
       v_ename EMPLOYEES.first_name%TYPE;
       v_sal EMPLOYEES.Salary%TYPE;
    BEGIN
      OPEN c_cursor;
      FETCH c_cursor INTO v_ename, v_sal;
      WHILE c_cursor%FOUND LOOP
         DBMS_OUTPUT.PUT_LINE(v_ename||'---'||to_char(v_sal)

    );
         FETCH c_cursor INTO v_ename, v_sal;
      END LOOP;
      CLOSE c_cursor;
    END;
     
    2.游标属性
     Cursor_name%FOUND 布尔型属性,当最近一次提取游标操作

    FETCH成功则为 TRUE,否则为FALSE;
     Cursor_name%NOTFOUND 布尔型属性,与%FOUND相反;
     Cursor_name%ISOPEN 布尔型属性,当游标已打开时返回 TRUE;
     Cursor_name%ROWCOUNT 数字型属性,返回已从游标中读取的记

    录数。
     
    例2:没有参数且没有返回值的游标。
    DECLARE
       v_f_name employees.first_name%TYPE;
       v_j_id employees.job_id%TYPE;
       
       CURSOR c1 --声明游标,没有参数没有返回值
       IS
          SELECT first_name, job_id FROM employees WHERE

    department_id = 20;
    BEGIN
       OPEN c1; --打开游标
       LOOP
          FETCH c1 INTO v_f_name, v_j_id; --提取游标
          IF c1%FOUND THEN
             DBMS_OUTPUT.PUT_LINE(v_f_name||'的岗位是'||

    v_j_id);
          ELSE
             DBMS_OUTPUT.PUT_LINE('已经处理完结果集了');
             EXIT;
          END IF;
       END LOOP;
       CLOSE c1; --关闭游标
    END;
     
    例3:有参数且没有返回值的游标。
    DECLARE
       v_f_name employees.first_name%TYPE;
       v_h_date employees.hire_date%TYPE;
       
       CURSOR c2(dept_id NUMBER, j_id VARCHAR2) --声明游标,有

    参数没有返回值
       IS
          SELECT first_name, hire_date FROM employees WHERE

    department_id = dept_id AND job_id = j_id;
    BEGIN
       OPEN c2(90, 'AD_VP'); --打开游标,传递参数值
       LOOP
          FETCH c2 INTO v_f_name, v_h_date; --提取游标
          IF c2%FOUND THEN
             DBMS_OUTPUT.PUT_LINE(v_f_name||'的雇佣日期是'||

    v_h_date);
          ELSE
             DBMS_OUTPUT.PUT_LINE('已经处理完结果集了');
             EXIT;
          END IF;
       END LOOP;
       CLOSE c2; --关闭游标
    END;
    例4:有参数且有返回值的游标。
    DECLARE
       TYPE emp_record_type IS RECORD(
            f_name employees.first_name%TYPE,
            h_date employees.hire_date%TYPE);
       v_emp_record EMP_RECORD_TYPE;
       v_emp_record EMP_RECORD_TYPE;
       CURSOR c3(dept_id NUMBER, j_id VARCHAR2) --声明游标,有

    参数有返回值
              RETURN EMP_RECORD_TYPE
       IS
          SELECT first_name, hire_date FROM employees WHERE

    department_id = dept_id AND job_id = j_id;
    BEGIN
       OPEN c3(j_id => 'AD_VP', dept_id => 90); --打开游标,传

    递参数值
       LOOP
          FETCH c3 INTO v_emp_record; --提取游标
          IF c3%FOUND THEN
             DBMS_OUTPUT.PUT_LINE(v_emp_record.f_name||'的雇

    佣日期是'||v_emp_record.h_date);
          ELSE
             DBMS_OUTPUT.PUT_LINE('已经处理完结果集了');
             EXIT;
          END IF;
       END LOOP;
       CLOSE c3; --关闭游标
    END;
     例5:基于游标定义记录变量。
    DECLARE
       CURSOR c4(dept_id NUMBER, j_id VARCHAR2) --声明游标,有

    参数没有返回值
       IS
          SELECT first_name f_name, hire_date FROM employees

    WHERE department_id = dept_id AND job_id = j_id;
        --基于游标定义记录变量,比声明记录类型变量要方便,不

    容易出错
        v_emp_record c4%ROWTYPE;
    BEGIN
       OPEN c4(90, 'AD_VP'); --打开游标,传递参数值
       LOOP
          FETCH c4 INTO v_emp_record; --提取游标
          IF c4%FOUND THEN
             DBMS_OUTPUT.PUT_LINE(v_emp_record.f_name||'的雇

    佣日期是'||v_emp_record.hire_date);
          ELSE
             DBMS_OUTPUT.PUT_LINE('已经处理完结果集了');
             EXIT;
          END IF;
       END LOOP;
       CLOSE c4; --关闭游标
    END;
    3. 游标的FOR循环
        PL/SQL语言提供了游标FOR循环语句,自动执行游标的OPEN、

    FETCH、CLOSE语句和循环语句的功能;当进入循环时,游标FOR循

    环语句自动打开游标,并提取第一行游标数据,当程序处理完当

    前所提取的数据而进入下一次循环时,游标FOR循环语句自动提取

    下一行数据供程序处理,当提取完结果集合中的所有数据行后结

    束循环,并自动关闭游标。
    格式:
       FOR index_variable IN cursor_name[(value[, value]…)]

    LOOP
        -- 游标数据处理代码
       END LOOP;
    其中:
    index_variable为游标FOR 循环语句隐含声明的索引变量,该变

    量为记录变量,其结构与游标查询语句返回的结构集合的结构相

    同。在程序中可以通过引用该索引记录变量元素来读取所提取的

    游标数据,index_variable中各元素的名称与游标查询语句选择

    列表中所制定的列名相同。如果在游标查询语句的选择列表中存

    在计算列,则必须为这些计算列指定别名后才能通过游标FOR 循

    环语句中的索引变量来访问这些列数据。
    注:不要在程序中对游标进行人工操作;不要在程序中定义用于

    控制FOR循环的记录。
     
    例6:当所声明的游标带有参数时,通过游标FOR 循环语句为游标

    传递参数。
    DECLARE
      CURSOR c_cursor(dept_no NUMBER DEFAULT 10)
      IS
      SELECT department_name, location_id FROM departments

    WHERE department_id <= dept_no;
    BEGIN
        DBMS_OUTPUT.PUT_LINE('当dept_no参数值为30:');
        FOR c1_rec IN c_cursor(30) LOOP
       DBMS_OUTPUT.PUT_LINE(c1_rec.department_name||'---'||

    c1_rec.location_id);
        END LOOP;
        DBMS_OUTPUT.PUT_LINE(CHR(10)||'使用默认的dept_no参数

    值10:');
        FOR c1_rec IN c_cursor LOOP
       DBMS_OUTPUT.PUT_LINE(c1_rec.department_name||'---'||

    c1_rec.location_id);
        END LOOP;
    END;
     
    例7:PL/SQL还允许在游标FOR循环语句中使用子查询来实现游标

    的功能。
    BEGIN
    --隐含打开游标
       FOR r IN (SELECT * FROM emp1 WHERE deptno=v_deptno)

    LOOP
    --隐含执行一个FETCH语句
          dbms_output.put_line('Employee Name: ' || r.ename

    || ' ,Salary: ' || r.sal);
    --隐含监测c_sal%NOTFOUND
       END LOOP;
    --隐含关闭游标
    END;
     
    4.1.2 处理隐式游标
    对于非查询语句,如修改、删除操作,则由ORACLE 系统自动地为

    这些操作设置游标并创建其工作区,这些由系统隐含创建的游标

    称为隐式游标,隐式游标的名字为SQL,这是由ORACLE 系统定义

    的。对于隐式游标的操作,如定义、打开、取值及关闭操作,都

    由ORACLE 系统自动地完成,无需用户进行处理。用户只能通过隐

    式游标的相关属性,来完成相应的操作。在隐式游标的工作区中

    ,所存放的数据是与用户自定义的显示游标无关的、最新处理的

    一条SQL 语句所包含的数据。
    格式调用为: SQL%
     
    注:INSERT, UPDATE, DELETE, SELECT(单查询) 语句中不必明

    确定义游标。
     
    隐式游标属性
    属性

    SELECT
    INSERT
    UPDATE
    DELETE
    SQL%ISOPEN
     
    FALSE
    FALSE
    FALSE
    FALSE
    SQL%FOUND
    TRUE
    有结果
     
    成功
    成功
    SQL%FOUND
    FALSE
    没结果
     
    失败
    失败
    SQL%NOTFUOND
    TRUE
    没结果
     
    失败
    失败
    SQL%NOTFOUND
    FALSE
    有结果
     
    成功
    失败
    SQL%ROWCOUNT
     
    返回行数,只为1
    插入的行数
    修改的行数
    删除的行数
     
    例8: 通过隐式游标SQL的%ROWCOUNT属性来了解修改了多少行。
    DECLARE
       v_rows NUMBER;
    BEGIN
    --更新数据
       UPDATE employees SET salary = 30000
       WHERE department_id = 90 AND job_id = 'AD_VP';
    --获取默认游标的属性值
       v_rows := SQL%ROWCOUNT;
       DBMS_OUTPUT.PUT_LINE(
       DBMS_OUTPUT.PUT_LINE('更新了'||v_rows||'个雇员的工

    资');
    --回退更新,以便使数据库的数据保持原样
       ROLLBACK;
    END;
     
    4.1.3 使用游标更新和删除数据
    游标修改和删除操作是指在游标定位下,修改或删除表中指定的

    数据行。这时,要求游标查询语句中必须使用FOR UPDATE选项,

    以便在打开游标时锁定游标结果集合在表中对应数据行的所有列

    和部分列。
    为了对正在处理(查询)的行不被另外的用户改动,ORACLE 提供一

    个 FOR UPDATE 子句来对所选择的行进行锁住。该需求迫使

    ORACLE锁定游标结果集合的行,可以防止其他事务处理更新或删

    除相同的行,直到您的事务处理提交或回退为止。
    语法:
     
    SELECT column_list FROM table_list FOR UPDATE [OF column

    [, column]…] [NOWAIT]
     
    如果使用 FOR UPDATE 声明游标,则可在DELETE和UPDATE 语句中

    使用
    WHERE CURRENT OF cursor_name子句,修改或删除游标结果集合

    当前行对应的数据库表中的数据行。
     
    例9:从EMPLOYEES表中查询某部门的员工情况,将其工资最低定

    为 1500;
    DECLARE
        V_deptno employees.department_id
        V_deptno employees.department_id%TYPE :=&p_deptno;
       
      CURSOR emp_cursor
      IS
      SELECT employees.employee_id, employees.salary FROM

    employees WHERE employees.department_id=v_deptno FOR

    UPDATE NOWAIT;
    BEGIN
        FOR emp_record IN emp_cursor LOOP
        IF emp_record.salary < 1500 THEN
            UPDATE employees SET salary=1500 WHERE CURRENT OF

    emp_cursor;
        END IF;
        END LOOP;
        COMMIT;
    END;
    4.2 游标变量
    与游标一样,游标变量也是一个指向多行查询结果集合中当前数

    据行的指针。但与游标不同的是,游标变量是动态的,而游标是

    静态的。游标只能与指定的查询相连,即固定指向一个查询的内

    存处理区域,而游标变量则可与不同的查询语句相连,它可以指

    向不同查询语句的内存处理区域(但不能同时指向多个内存处理

    区域,在某一时刻只能与一个查询语句相连),只要这些查询语

    句的返回类型兼容即可。
    4.2.1 声明游标变量
    游标变量为一个指针,它属于参照类型,所以在声明游标变量类

    型之前必须先定义游标变量类型。在PL/SQL中,可以在块、子程

    序和包的声明区域内定义游标变量类型。
    语法格式为:
    1.定义游标变量
    TYPE cursortype IS REF CURSOR;
    cursor_variable cursortype;
    2.打开游标变量
    OPEN cursor_variable FOR dynamic_string
    [USING bind_argument[,bind_argument]...]
    3.循环提取数据
    FETCH cursor_variable INTO {var1[,var2]...|

    record_variable};
    EXIT WHEN cursor_variable%NOTFOUND
    4.关闭游标变量
    CLOSE cursor_variable;
     
    例10:使用游标变量(没有RETURN子句)
    DECLARE
    --定义一个游标数据类型
       TYPE emp_cursor_type IS REF CURSOR;
    --声明一个游标变量
       c1 EMP_CURSOR_TYPE;
    --声明两个记录变量
       v_emp_record employees%ROWTYPE;
       v_reg_record regions%ROWTYPE;
    BEGIN
       OPEN c1 FOR SELECT * FROM employees WHERE

    department_id = 20;
       LOOP
          FETCH c1 INTO v_emp_record;
          EXIT WHEN c1%NOTFOUND;
          DBMS_OUTPUT.PUT_LINE(v_emp_record.first_name||'的雇

    佣日期是'||v_emp_record.hire_date);
       END LOOP;
    --将同一个游标变量对应到另一个SELECT语句
       OPEN c1 FOR SELECT * FROM regions WHERE region_id IN(

    1,2);
       LOOP
          FETCH c1 INTO v_reg_record;
         
          EXIT WHEN c1%NOTFOUND;
          DBMS_OUTPUT.PUT_LINE(v_reg_record.region_id||'表

    示'||v_reg_record.region_name);
       END LOOP;
       CLOSE c1;
    END;
     
    例11:使用游标变量(有RETURN子句)
    DECLARE
    --定义一个与employees表中的这几个列相同的记录数据类型
       TYPE emp_record_type IS RECORD(
            f_name employees.first_name
            f_name employees.first_name%TYPE,
            h_date employees.hire_date
            h_date employees.hire_date%TYPE,
            j_id employees.job_id
            j_id employees.job_id%TYPE);
    --声明一个该记录数据类型的记录变量
       v_emp_record EMP_RECORD_TYPE;
    --定义一个游标数据类型
       TYPE emp_cursor_type IS REF CURSOR
            RETURN EMP_RECORD_TYPE;
    --声明一个游标变量
       c1 EMP_CURSOR_TYPE;
    BEGIN
       OPEN c1 FOR SELECT first_name, hire_date, job_id FROM

    employees WHERE department_id = 20;
       LOOP
          FETCH c1 INTO v_emp_record;
          EXIT WHEN c1%NOTFOUND;
          DBMS_OUTPUT.PUT_LINE('雇员名称:'||

    v_emp_record.f_name||' 雇佣日期:'||

    v_emp_record.h_date||' 岗位:'||v_emp_record.j_id);
       END LOOP;
       CLOSE c1;
    END;
     
    第十一章 视图
    视图:是一个封装了各种复杂查询的语句,就称为视图。不存储

    数据,只存储定义,定义被保存在数据字典中
    作用:1、可以保证安全,隐藏一些数据,保证数据不会被误删;
               2、多表连接,可以使复杂的查询易于理解和使用
    15.1、创建视图
    需要权限才能创建
    grant create view to scott;
     CREATE OR REPLACE VIEW 视图名字(字段) AS 子查
     CREATE OR REPLACE VIEW v_表名_业务 AS 查询语句
    建立一个只包含 20 部门雇员信息的视图(雇员的编号、姓名、

    工资)
     CREATE VIEW empv20 (empno,ename,sal) AS SELECT

    empno,ename,sal FROM emp WHERE deptno=20 ;
     现在直接更新视图里的数据 将 7369 的部门编号修改为 30。此

    操作在视图中完成。
       update empv20 SET deptno=30 where empno=7369 ; 此时,

    提示更新完成。
     默认情况下创建的视图,如果更新了,则会自动将此数据从视图

    中删除,之后会更新原本的数据。
     
    在建立视图的时候有两个参数:
     · WITH CHECK OPTION à 保护视图的创建规则
    CREATE OR REPLACE VIEW empv20
    AS SELECT empno,ename,sal,deptno FROM emp WHERE deptno=20
    WITH CHECK OPTION CONSTRAINT empv20_ck;----约束条件
    ALTER TABLE emp1 add CONSTRAINT empv20_ck check(约束条

    件);
     再执行更新操作:
      update empv20 SET deptno=30 where empno=7369 ; à 此处更

    新的是部门编号,失败
       |- 之前是按照部门编号建立的视图,所以不能修改部门编号
      update empv20 SET ename='tom' where empno=7369 ; à 可以

    更新,更新的是名字,成功
     · WITH READ ONLY(只读,不可修改),视图最好不要轻易的

    修改
    CREATE OR REPLACE VIEW empv20
    AS SELECT empno,ename,sal,deptno FROM emp WHERE deptno=20
    WITH READ ONLY;
     现在任意的字段都不可更改,所以现在的视图是只读的。
    如果视图的基表有多行查询(比如:group by,distinct)那么该

    视图也是只读的
     
    15.1、查看视图
    SELECT * FROM v_emp;
    update v_emp SET deptno=20 where empno=7369;
    DELETE FROM v_emp WHERE empno=7369;
    ROLLBACK;
    DROP VIEW v_emp;
    在视图终不能被修改删除,1、多表构成的视图;2、group by
    资料:
    http://database.51cto.com/art/200904/118306.htm
    http://blog.csdn.net/fan_xiao_ming/article/details/617406

    5
    第十六章 索引
    工作原理:rowid
    用执行计划检测索引是否起作用(set autot on exp)
    执行计划 cbo(选择)和cro(规则)
       
    16.1、索引
    索引是一种用于提升查询效率的数据库对象,通过快速定位数据

    的方法,索引信息与表独立存放,Oracle数据库自动使用和维护

    索引
    索引的存储
           索引和表都是独立存在的。在为索引指定表空间的时候,

    不要将被索引的表和索引指向同一个表空间,这样可以避免产生

    IO 冲突。使 Oracle 能够并行访问存放在不同硬盘中的索引数据

    和表数据,更好的提高查询速度。
    16.2、索引优缺点
    建立索引的优点
      1.加快数据的检索速度;
      2.创建唯一性索引,保证数据库表中每一行数据的唯一性;
      3.加速表和表之间的连接;
      4.在使用分组和排序子句进行数据检索时,可以显著减少查询

    中分组和排序的时间。
    索引的缺点
      1.索引需要占物理空间。
      2.当对表中的数据进行增加、删除和修改的时候,索引也要动

    态的维护,降低了数据的维护速度。
    16.3、创建索引
    创建索引的方式
    1、自动创建:在定义主键或唯一键约束时系统会自动在相应的字

    段上创建唯一性索引
    2、手动创建:用户可以在其他列上创建非唯一索引,以加速查询


    创建索引:创建索引一般有以下两个目的:维护被索引列的唯一

    性和提供快速访问表中数据的策略。
    --在 select 操作占大部分的表上创建索引;
    --在 where 子句中出现最频繁的列上创建索引;
    --在选择性高的列上创建索引(补充索引选择性,最高是 1,eg

    :primary key)
    --复合索引的主列应该是最有选择性的和 where 限定条件最常用

    的列,并以此类推第二列……。
    --小于 5M 的表,最好不要使用索引来查询,表越小,越适合用

    全表扫描。
    Create [UNIQUE|BITMAP] index
    [schema.]index_name on [schema.]table_name(column_name

    [ASC|DESC],…n,[column_expression])|CLUSTER [schema.]

    cluster_name
    [INITRANS integer]
    [MAXTRANS integer]
    [PCTFREE integer]
    [PCTUESD integer]
    [TABLESPACE tablespace_name]
    [STORAGE storage_clause]
    [NOSORT]
    [REVERSE]
    UNIQUE 指定索引所基于的列(或多列)值必须唯一。默认的索引

    是非唯一的。
    BITMAP 指定建立位映射索引而不是B*索引。位映射索引保存的行

    标识符与作为位映射的键值有关。位映射中的每一位都对应于一

    个可能的行标识符,位设置意味着具有对应行标识符的行包含该

    键值。
    ON table_name 建立基于函数的索引。用table_name的列、常数

    、SQL函数和自定义函数创建的表达式。指定column_expression

    ,以后用基于函数的索引查询时,必须保证查询该

    column_expression不为空。
    CLUSTER 创建cluster_name簇索引。若表不用schema限制,

    oracle假设簇包含在你自己的方案中。不能为散列簇创建簇索引


    NOSORT 数据库中的行以升序保存,在创建索引时不必对行排序。

    若索引列或多列的行不以升序保存,oracle会返回错误。
    REVERSE 指定以反序索引块的字节,不包含行标识符。NOSORT不

    能与REVERSE一起指定。
    CREATE INDEX idx_表名_列名 on 表名(列1,列2...)
    create index abc on student(sid,sname);
    create index abc1 on student(sname,sid);
    这两种索引方式是不一样的
    索引 abc 对 Select * from student where sid=1; 这样的查询

    语句更有效索引 abc1 对 Select * from student where

    sname=?louis?; 这样的查询语句更有效
    因此建立索引的时候,字段的组合顺序是非常重要的。一般情况

    下,需要经常访问的字段放在组合字段的前面
    16.4、使用索引的原则
    --查询结果是所有数据行的 5%以下时,使用 index 查询效果最

    好;
    --where 条件中经常用到表的多列时,使用复合索引效果会好于

    几个单列索引。因为当 sql 语句所查询的列,全部都出现在复合

    索引中时,此时由于 Oracle 只需要查询索引块即可获得所有数

    据,当然比使用多个单列索引要快得多;
    --索引利于 select,但对经常 insert,delte 尤其 update 的

    表,会降低效率。
    eg:试比较下面两条 SQL 语句(emp 表的 deptno 列上建有

    ununique index):
    语句 A:SELECT dname, deptno FROM dept WHERE deptno NOT

    IN (SELECT deptno FROM emp);
    语句 B:SELECT dname, deptno FROM dept WHERE NOT EXISTS

    (SELECT deptno FROM emp WHERE dept.deptno = emp.deptno);
    这两条查询语句实现的结果是相同的,但是执行语句 A 的时候,

    ORACLE 会对整个 emp 表进行扫描,没有使用建立在 emp 表上的

    deptno 索引,执行语句 B 的时候,由于在子查询中使用了联合

    查询,ORACLE 只是对 emp 表进行的部分数据扫描,并利用了

    deptno 列的索引,所以语句 B 的效率要比语句 A 的效率高。
     
    ----where 子句中的这个字段,必须是复合索引的第一个字段;
    eg:一个索引是按 f1, f2, f3 的次序建立的,若 where 子句是

    f2 = : var2, 则因为 f2 不是索引的第 1 个字段,无法使用该

    索引。
    ---- where 子句中的这个字段,不应该参与任何形式的计算:任

    何对列的操作都将导致表扫描,它包括数据库函数、计算表达式

    等等,查询时要尽可能将操作移至等号右边。 ----应尽量熟悉各

    种操作符对 Oracle 是否使用索引的影响:以下这些操作会显式
    (explicitly)地阻止 Oracle 使用索引: is null ; is not

    null ; not in; !=; like ; numeric_col+0;date_col+0;

    char_col||' '; to_char; to_number,to_date 等。
    Eg:
    Select jobid from mytabs where isReq='0' and to_date

    (updatedate) >= to_Date ( '2001-7-18',
    'YYYY-MM-DD');--updatedate 列的索引也不会生效。
    在正确使用索引的前提下,索引可以提高检索相应的表的速度。

    当用户考虑在表中使用索引时,应遵循下列一些基本原则。
    (1)在表中插入数据后创建索引。在表中插入数据后,创建索引

    效率将更高。如果在装载数据之前创建索引,那么插入每行时

    oracle都必须更改索引。
    (2)索引正确的表和列。如果经常检索包含大量数据的表中小于

    15%的行,就需要创建索引。为了改善多个表的相互关系,常常使

    用索引列进行关系连接。
    (3)主键和唯一关键字所在的列自动具有索引,但应该在与之关

    联的表中的外部关键字所在的列上创建索引。
    (4)合理安排索引列。在create index 语句中,列的排序会影

    响查询的性能,通常将最常用的列放在前面。创建一个索引来提

    高多列的查询效率时,应该清楚地了解这个多列的索引对什么列

    的存取有效,对什么列的存取无效。
    (5)限制表中索引的数量。尽管表可以有任意数量的索引,可是

    索引越多,在修改表中的数据时对索引做出相应更改的工作量也

    越大,效率也就越低。同样,目前不用的索引应该及时删除。
    (6)指定索引数据块空间的使用。创建索引时,索引的数据块是

    用表中现存的值填充的,直到达到PCTFREE为止。如果打算将许多

    行插入到被索引的表中,PCTFREE就应设置得大一点,不能给索引

    指定PCTUSED。
    (7)根据索引大小设置存储参数。创建索引之前应先估计索引的

    大小,以便更好地促进规划和管理磁盘空间。单个索引项的最大

    值大约是数据块大小的一半。
    16.6、删除索引
     drop index PK_DEPT1;
    16.7、索引类型
    B树索引 B-tree indexes;
    B树索引又可分为以下子类:
    索引组织表Index-organized tables;
    反转索引Reverse key indexes;
    降序索引Descending indexes;
    B树聚簇索引B-tree cluster indexes;
    位图和位图联合索引Bitmap and bitmap join indexes;
    基于函数的索引Function-based indexes;
    应用域索引Application domain indexes;
    B-Tree是一个平衡树的结构【注意这里的B表示Balanced平衡的意

    思,而不是Binary二叉】,B树索引也是Oracle里最为常见的索引

    类型。B树索引里的数据是已经按照关键字或者是被索引字段事先

    排好序存放的,默认是升序存放。
    对于这幅B树存储结构图作以下几点介绍:
    1 、索引高度是指从根块到达叶子块时所遍历的数据块的个数,

    而索引层次=索引高度-1;本图中的索引的高度是3,索引层次等

    于2;通常,索引的高度是2或者3,即使表中有上百万条记录,也

    就意味着,从索引中定位一个键字只需要2或3次I/O,索引越高,

    性能越差;
    2、 B树索引包含两种数据块儿:分枝块(Branch Block)和叶子块

    (Leaf Block);
    3 、分枝块里存放指向下级分枝块(索引高度大于2,即有超过两

    层分枝块的情况)或者直接指向叶子块的指针(索引高度等于2,即

    层次为1的索引);
    4 、叶子块,就是位于B树结构里最底层的数据块。叶子块里存放

    的是索引条目,即索引关键字和rowid,rowid用来精确定位表里

    的记录;索引条目都是按照索引关键字+rowid已经排好序存放的

    ;同一个叶子块里的索引条目同时又和左右兄弟条目形成链表,

    并且是一个双向链表;
    5 、B树索引的所有叶子块一定位于同一层上,这是由B树的数据

    结构定义的。因此,从根块到达任何一个叶子块的遍历代价都是

    相同的;
    B 树索引(B-Tree Index)
    创建索引的默认类型,结构是一颗树,采用的是平衡 B 树算法:
    l 右子树节点的键值大于等于父节点的键值 l 左子树节点的键值

    小于等于父节点的键值
    位图索引(BitMap Index)
    如果表中的某些字段取值范围比较小,比如职员性别、分数列

    ABC 级等。只有两个值。
    这样的字段如果建 B 树索引没有意义,不能提高检索速度。这时

    我们推荐用位图索引
    Create BitMap Index student on(sex);
    索引按功能和索引对象分还有以下类型。
        (1)唯一索引意味着不会有两行记录相同的索引键值。唯一

    索引表中的记录没有RowID,不能再对其建立其他索引。在

    oracle10g中,要建立唯一索引,必须在表中设置主关键字,建立

    了唯一索引的表只按照该唯一索引结构排序。
        (2)非唯一索引不对索引列的值进行唯一性限制。
        (3)分区索引是指索引可以分散地存在于多个不同的表空间

    中,其优点是可以提高数据查询的效率。
        (4)未排序索引也称为正向索引。Oracle10g数据库中的行

    是按升序排序的,创建索引时不必指定对其排序而使用默认的顺

    序。
        (5)逆序索引也称反向索引。该索引同样保持列按顺序排列

    ,但是颠倒已索引的每列的字节。
        按照索引所包含的列数可以把索引分为单列索引和复合索引

    。索引列只有一列的索引为单列索引,对多列同时索引称为复合

    索引。
    16.8、管理索引
    1)先插入数据后创建索引
    向表中插入大量数据之前最好不要先创建索引,因为如果先建立

    索引。那么在插入每行数据的时候都要更改索引。这样会大大降

    低插入数据的速度。
    2)设置合理的索引列顺序
    3)限制每个表索引的数量
    4)删除不必要的索引
    5)为每个索引指定表空间
    6)经常做 insert,delete 尤其是 update 的表最好定期

    exp/imp 表数据,整理数据,降低碎片(缺点:要停应用,以保

    持数据一致性,不实用);
         有索引的最好定期 rebuild 索引(rebuild期间只允许表的

    select 操作,可在数据库较空闲时间提交),以降低索引碎片,

    提高效率
     
    16.8、索引问题
    1.一个表的查询语句可以同时用到两个索引。
     
    2.索引是以独立于表存在的一种数据库对象,它是对基表的一种

    排序(默认是 B 树索引就是二叉树的排序方式),比如:
    3.这样的查询效率,肯定是大于没有索引情况的全表扫描(table

    access full),但是有两个问题。
        问题一:建立索引将占用额外的数据库空间,更重要的是增

    删改操作的时候,索引的排序也必须改变,加大的维护的成本 问

    题二:如果经常查询 x=?和 y=?,那推荐使用组合 index(x,y),

    这种情况下组合索引的效率是远高于两个单独的索引的。
    同时在用组合索引的时候,大家一定要注意一个细节:建立组合

    索引 index(x,y,z)的时候,那在查询条件中出现 x,xy,xyz,yzx

    都是可以用到该组合索引,但是 y,yz,z 是不能用到该索引的。
    第十三章 序列、同义词
    13.1、 创建序列(sequence)
    CREATE SEQUENCE seq
      INCREMENT BY 2--增量
      START WITH 2--起始值 不能小于min
      MAXVALUE 10--最大值
      MINVALUE 1--最小值
      CYCLE--/NOCYCLE 序列号是否可循环(到了maxvalue在从min开

    始)
      CACHE 5--/NOCACHE 缓存下一个值,必须满足大于1,小于等于

    (MAXVALUE-MINVALUE)/INCREMENT
      NOORDER--/NOORDER 序列号是否顺序产生
    13.2、 属性 NextVal,CurrVal
    --当前值 -----currval
    SELECT seq.currval FROM dual;
    --下一个值------nextval
    SELECT seq.nextval FROM dual;
    (必须先有 nextval,才能有 currval)
    --在向表中插入数据时使用
    INSERT INTO emp1(empno) VALUES(seq.nextval);
     使用 cache 或许会跳号, 比如数据库突然不正常 down 掉
    (shutdown abort),cache中的sequence就会丢失. 所以可以在

    create sequence的时候用nocache防止这种情况
    13.3、 修改
    不能改变当前值,但是可以改变增量
    ALTER SEQUENCE seq INCREMENT BY 3;
    ALTER SEQUENCE seq CACHE 3;
    13.4、 删除
     DROP SEQUENCE seq;
    13.5、 同义词 (synonym)
    Select * from dual;
    为什么?因为同义词的存在
    Dual 其实是 sys 用户下的一张表
    select table_name from user_tables where lower

    (table_name) = 'dual';
    1、概念
    同义词是数据库方案对象的一个别名,经常用于简化对象访问和

    提高对象访问的安全性。在使用同义词时,Oracle数据库将它翻

    译成对应方案对象的名字。与视图类似,同义词并不占用实际存

    储空间,只有在数据字典中保存了同义词的定义。在Oracle数据

    库中的大部分数据库对象,如表、视图、同义词、序列、存储过

    程、包等等,数据库管理员都可以根据实际情况为他们定义同义

    词。
    同义词,顾名思义就是两个词的意思一样,可以互相替换.
    2、作用:
    1) 多用户协同开发中,可以屏蔽对象的名字及其持有者。如果没

    有同义词,当操作其他用户的表时,必须通过user名.object名的

    形式,采用了Oracle同义词之后就可以隐蔽掉user名,当然这里

    要注意的是:public同义词只是为数据库对象定义了一个公共的

    别名,其他用户能否通过这个别名访问这个数据库对象,还要看

    是否已经为这个用户授权。
    2) 简化sql语句。上面的一条其实就是一种简化sql的体现,同时

    如果自己建的表的名字很长,可以为这个表创建一个Oracle同义

    词来简化sql开发。
    3)为分布式数据库的远程对象提供位置透明性。
    4)Oracle同义词在数据库链接中的作用
    数据库链接是一个命名的对象,说明一个数据库到另一个数据库

    的路径,通过其可以实现不同数据库之间的通信。
    Create database link 数据库链名 connect to user名

    identified by 口令 using ‘Oracle连接串’;
    访问对象要通过 object名@数据库链名。同义词在数据库链中的

    作用就是提供位置透明性。
    3、分类:
    Create synonym dept for soctt.dept;(这样创建的同义词是私

    有的,只有创建者才能用)
    Drop synonym dept;
    Create public synonym dept for soctt.dept;(这样创建的同

    义词才是公有的)
    Drop public synonym dept;
    4、权限管理
    与同义词相关的权限有CREATE SYNONYM、CREATE ANY SYNONYM、

    CREATE PUBLIC SYNONYM权限。
    1:用户在自己的模式下创建私有同义词,这个用户必须拥有

    CREATE SYNONYM权限,否则不能创建私有同义词。
    2:如果需要在其它模式下创建同义词,则必须具有CREATE ANY

    SYNONYM的权限。
    3:创建公有同义词则需要CREATE PUBLIC SYNONYM系统权限。
    5、查看同义词
    SQL> SELECT * FROM DBA_SYNONYMS WHERE SYNONYM_NAME IN (

    'SYSN_TEST','PUBLIC_TEST');
    OWNER SYNONYM_NAME TABLE_OWNER TABLE_NAME DB_LINK
    ------------------------------

    ------------------------------
    PUBLIC PUBLIC_TEST ETL TEST
    ETL SYSN_TEST ETL TEST
    SQL> SELECT * FROM USER_SYNONYMS
    6、使用同义词
    SELECT * FROM SYSN_TEST;
    使用同义词可以保证当数据库的位置或对象名称发生改变时,应

    用程序的代码保持稳定不变,仅需要改变同义词;
    当使用一个没有指定schema的同义词是,首先在用户自己的

    schema中寻找,然后再公共同义词中寻找
    7、删除同义词
    DROP [ PUBLIC ] SYNONYM [ schema. ] 同义词名称 [ FORCE ];
    DROP SYNONYM SYSN_TEST;
    DROP PUBLIC SYNONYM PUBLIC_TEST;--当同义词的原对象被删除

    是,同义词并不会被删除
    8、编译同义词
    ALTER SYNONYM T COMPILE; --当同义词的原对象被重新建立时,

    同义词需要重新编译
    对原对象进行DDL操作后,同义词的状态会变成INVALID;当再次

    引用这个同义词时,同义词会自动编译,状态会变成VALID,无需

    人工干预,当然前提是不改变原对象的名称
    问题锦集
    1:公用同义词与私有同义词能否同名呢?如果可以,访问同义词

    时,是共有同义词还是私有同义词优先?
    可以,如果存在公用同义词和私有同义词同名的情况,在访问同

    义词是,访问的是私有同义词的指向的对象。
    2:为啥OE用户创建的公用同义词,HR用户不能访问呢?
    因为HR没有访问OE模式下对象的权限,如果OE模式给HR用户赋予

    了SELECT对象等权限,那么HR用户即可访问。
    3:对象、私有同义词、公共同义词是否可以存在三者同名的情况


    存在同名对象和公共同义词时,数据库优先选择对象作为目标,

    存在同名私有对象和公共对象时,数据库优先选择私有同义词作

    为目标
    第十四章 函数
    in 只读
    out 只写
    in out 可读写
     函数就是一个有返回值的过程。
    定义一个函数:此函数可以根据雇员的编号查询出雇员的年薪
    CREATE OR REPLACE FUNCTION myfun(eno emp.empno%TYPE)
    RETURN NUMBER
    AS
     rsal NUMBER ;
    BEGIN
     SELECT (sal+nvl(comm,0))*12 INTO rsal FROM emp WHERE

    empno=eno ;
    RETURN rsal ;
    END ;
    /
    直接写 SQL 语句,调用此函数:
    SELECT myfun(7369) FROM dual ;
    第十五章 触发器
    15.1分类:
    DML触发器-----------基于表的(insert、alter、update)
    替代触发器-----------基于VIEW的
    系统触发器-----------基于系统的
    好处:自动调用、记录日志、保证数据安全、用数据库触发器可

    以保证数据的一致性和完整性。
    语法:
    CREATE [OR REPLACE] TRIGGER trigger_name
    {BEFORE | AFTER }
    {INSERT | DELETE | UPDATE [OF column [, column …]]}
    [OR {INSERT | DELETE | UPDATE [OF column [, column

    …]]}...]
    ON [schema.]table_name | [schema.]view_name
    [REFERENCING {OLD [AS] old | NEW [AS] new| PARENT as

    parent}]
    [FOR EACH ROW ]
    [WHEN condition]
    PL/SQL_BLOCK | CALL procedure_name;
           
           BEFORE 和AFTER指出触发器的触发时序分别为前触发和后

    触发方式,前触发是在执行触发事件之前触发当前所创建的触发

    器,后触发是在执行触发事件之后触发当前所创建的触发器。
           FOR EACH ROW选项说明触发器为行触发器。行触发器和语

    句触发器的区别表现在:行触发器要求当一个DML语句操走影响数

    据库中的多行数据时,对于其中的每个数据行,只要它们符合触

    发约束条件,均激活一次触发器;而语句触发器将整个语句操作

    作为触发事件,当它符合约束条件时,激活一次触发器。当省略

    FOR EACH ROW 选项时,BEFORE 和AFTER 触发器为语句触发器,

    而INSTEAD OF 触发器则只能为行触发器。
           REFERENCING 子句说明相关名称,在行触发器的PL/SQL块

    和WHEN 子句中可以使用相关名称参照当前的新、旧列值,默认的

    相关名称分别为OLD和NEW。触发器的PL/SQL块中应用相关名称时

    ,必须在它们之前加冒号(:),但在WHEN子句中则不能加冒号。
          WHEN 子句说明触发约束条件。Condition 为一个逻辑表达

    时,其中必须包含相关名称,而不能包含查询语句,也不能调用

    PL/SQL 函数。WHEN 子句指定的触发约束条件只能用在BEFORE 和

    AFTER行触发器中,不能用在INSTEAD OF 行触发器和其它类型的

    触发器中。
    15.2、 触发器触发次序
    1. 执行 BEFORE语句级触发器;
    2. 对与受语句影响的每一行:
    l 执行 BEFORE行级触发器
    l 执行 DML语句
    l 执行 AFTER行级触发器
    3. 执行 AFTER语句级触发器
    15.3、语句触发器
    after 语句触发器
    Before 语句触发器
    例如:禁止工作人员在休息日改变雇员信息
    create or replace trigger tr_src_emp
    before insert or update or delete
    on emp
    begin
    if to_char(sysdate,'DY','nls_date_language=AMERICAN') in(

    'SAT','SUN') then
    raise_application_error(-20001,'can?t modify user

    information in weekend');
    end if;
    end;
    /
     
    使用条件谓语---------inserting、updating、deleting
     create or replace trigger tr_src_emp
    before insert or update or delete
    on emp
    begin
    if to_char(sysdate,'DY') in( '星期六','星期天') then
    case
    when inserting then
      raise_application_error(-20001,'fail to insert');
    when updating then
      raise_application_error(-20001,'fail to update');
     when deleting then
      raise_application_error(-20001,'fail to delete');
    end case;
    end if;
    end;
    /
    15.4、行触发器
    执行 DML 操作时,每作用一行就触发一次触发器。
    Bofre 行触发器
    例如:确保员工工资不能低于原有工资
    Create or replace trigger tr_emp_sal
    before update of sal
    on emp
    for each row
    begin
    if :new.sal<:old.sal then
     raise_application_error(-20010,'sal should not be

    less');
    end if;
    end;
    /
    after 行触发器
    例如:统计员工工资变化
    Create table audit_emp_change(
    Name varchar2(10),
    Oldsal number(6,2),
    Newsal number(6,2),
    Time date);
    Create or replace trigger tr_sal_sal after update of sal

    on emp for each row declare v_temp int;
    begin
    select count(*) into v_temp from audit_emp_change where

    name=:old.ename; if v_temp=0 then
    insert into audit_emp_change values

    (:old.ename,:old.sal,:new.sal,sysdate); else
     update audit_emp_change set

    oldsal=:old.sal,newsal=:new.sal,time=sysdate where

    name=:old.ename;
    end if; end;
    /
    限制行触发器
    Create or replace trigger tr_sal_sal
    after update of sal
    on emp
    for each row when (old.job=?SALESMAN?)
    declare
    v_temp int;
    begin
    select count(*) into v_temp from audit_emp_change where

    name=:old.ename;
    if v_temp=0 then
    insert into audit_emp_change values

    (:old.ename,:old.sal,:new.sal,sysdate);
    else
     update audit_emp_change set

    oldsal=:old.sal,newsal=:new.sal,time=sysdate where

    name=:old.ename;
    end if;
    end;
    /
    注意:
    例如:如果要基于 EMP 表建立触发器。那么该触发器的执行代码

    不能包含对 EMP 表的查询操作编写 DML 触发器的时,触发器代

    码不能从触发器所对应的基表中读取数据。
    Create or replace trigger tr_emp_sal
    Before update of sal
    on emp
    For each row
    declare
    Maxsal number(6,2);
    Begin
    If :new.sal>maxsal then Select max(sal) into maxsal from

    emp;
    Raise_application_error(-21000,?error?);
    End if;
    End;
    /
     创建的时候不会报错。但是一旦执行就报错了
    update emp set sal=sal*1.1 where deptno=30
    DML触发器的限制
    l CREATE TRIGGER语句文本的字符长度不能超过32KB;
    l 触发器体内的SELECT 语句只能为SELECT … INTO …结构,或

    者为定义游标所使用的SELECT语句。
    l 触发器中不能使用数据库事务控制语句 COMMIT; ROLLBACK,

    SVAEPOINT 语句;
    l 由触发器所调用的过程或函数也不能使用数据库事务控制语句


    l 触发器中不能使用LONG, LONG RAW 类型;
    l 触发器内可以参照LOB 类型列的列值,但不能通过 :NEW 修改

    LOB列中的数据;
     
     :NEW 修饰符访问操作完成后列的值
     :OLD 修饰符访问操作完成前列的值
    特性
    INSERT
    UPDATE
    DELETE
    OLD
    NULL
    实际值
    实际值
    NEW
    实际值
    实际值
    NULL
     
    15.4 替代触发器
    语法:
    CREATE [OR REPLACE] TRIGGER trigger_name
    INSTEAD OF
    {INSERT | DELETE | UPDATE [OF column [, column …]]}
    [OR {INSERT | DELETE | UPDATE [OF column [, column

    …]]}...]
    ON [schema.] view_name --只能定义在视图上
    [REFERENCING {OLD [AS] old | NEW [AS] new| PARENT as

    parent}]
    [FOR EACH ROW ] --因为INSTEAD OF触发器只能在行级上触发,所

    以没有必要指定
    [WHEN condition]
    PL/SQL_block | CALL procedure_name;
    例2:创建复杂视图,针对INSERT操作创建INSTEAD OF触发器,向

    复杂视图插入数据。
    l 创建视图:
    CREATE OR REPLACE FORCE VIEW "HR"."V_REG_COU" ("R_ID",

    "R_NAME", "C_ID", "C_NAME")
    AS
     SELECT r.region_id,
        r.region_name,
        c.country_id,
        c.country_name
     FROM regions r,
        countries c
     WHERE r.region_id = c.region_id;
     
    l 创建触发器:
    CREATE OR REPLACE TRIGGER "HR"."TR_I_O_REG_COU"
    INSTEAD OF INSERT
    ON v_reg_cou
    FOR EACH ROW
    DECLARE
    v_count NUMBER;
    BEGIN
     SELECT COUNT(*) INTO v_count FROM regions WHERE

    region_id = :new.r_id;
     IF v_count = 0 THEN
        INSERT INTO regions
          (region_id, region_name
          ) VALUES
          (:new.r_id, :new.r_name
          );
     END IF;
     SELECT COUNT(*) INTO v_count FROM countries WHERE

    country_id = :new.c_id;
     IF v_count = 0 THEN
        INSERT
        INTO countries
          (
            country_id,
            country_name,
            region_id
          )
          VALUES
          (
            :new.c_id,
            :new.c_name,
            :new.r_id
          );
     END IF;
    END;
     
    创建INSTEAD OF触发器需要注意以下几点:
    l 只能被创建在视图上,并且该视图没有指定WITH CHECK OPTION

    选项。
    l 不能指定BEFORE 或 AFTER选项。
    l FOR EACH ROW子可是可选的,即INSTEAD OF触发器只能在行级

    上触发、或只能是行级触发器,没有必要指定。
    l 没有必要在针对一个表的视图上创建INSTEAD OF触发器,只要

    创建DML触发器就可以了。
     
    15.5、系统事件触发器
    语法:
    CREATE OR REPLACE TRIGGER [sachema.]trigger_name
    {BEFORE
    {BEFORE|AFTER}
    {ddl_event_list
    {ddl_event_list | database_event_list}
    ON { DATABASE | [schema.]SCHEMA }
    [WHEN condition]
    PL/SQL_block | CALL procedure_name;
    其中: ddl_event_list:一个或多个DDL 事件,事件间用 OR 分

    开;
             database_event_list:一个或多个数据库事件,事件

    间用 OR 分开;
    下面给出系统触发器的种类和事件出现的时机(前或后):
    事件
    允许的时机
    说明
    STARTUP
    AFTER
    启动数据库实例之后触发
    SHUTDOWN
    BEFORE
    关闭数据库实例之前触发(非正常关闭不触发)
    SERVERERROR
    AFTER
    数据库服务器发生错误之后触发
    LOGON
    AFTER
    成功登录连接到数据库后触发
    LOGOFF
    BEFORE
    开始断开数据库连接之前触发
    CREATE
    BEFORE,AFTER
    在执行CREATE语句创建数据库对象之前、之后触发
    DROP
    BEFORE,AFTER
    在执行DROP语句删除数据库对象之前、之后触发
    ALTER
    BEFORE,AFTER
    在执行ALTER语句更新数据库对象之前、之后触发
    DDL
    BEFORE,AFTER
    在执行大多数DDL语句之前、之后触发
    GRANT
    BEFORE,AFTER
    执行GRANT语句授予权限之前、之后触发
    REVOKE
    BEFORE,AFTER
    执行REVOKE语句收权限之前、之后触犯发
    RENAME
    BEFORE,AFTER
    执行RENAME语句更改数据库对象名称之前、之后触犯发
    AUDIT / NOAUDIT
    BEFORE,AFTER
    执行AUDIT或NOAUDIT进行审计或停止审计之前、之后触发
    /*create or replace trigger tr_emp1_1
      --before update on emp1
      after update on emp1
      for each row
    declare
      -- local variables here
    begin
      if :new.sal<:old.sal then
        Raise_application_error(-20000, ':new.sal>:old.sal');
      end if;
    end tr;*/
    /*create or replace trigger tr_emp1_2
       after delete on emp1
       --before delete on emp1
       for each row
    begin
      Raise_application_error(-20001, '不能删');
    end;*/
    create or replace trigger tr_emp1_3
    after delete or update or insert on emp1
    for each ROW
    begin
      if deleting then
        if :new.sal>0 then
           Raise_application_error(-20000, 'deleting');
        end IF;
      /*elsif updating then
        if :new.sal<:old.sal then
           Raise_application_error(-20001, 'updating');
        end if;
      else
        if :new.sal<:old.sal then
           Raise_application_error(-20002, 'inserting');
        end if;*/
      end if;
    end;
    资料:
    http://www.cnblogs.com/huyong/archive/2011/04/27/2030466.

    html
    第十六章 存储过程
    16.1、存储过程
    CREATE OR REPLACE PROCEDURE procedure_name AS PL/SQL块
    现在定义一个简单的过程,就是打印一个数字
    CREATE OR REPLACE PROCEDURE myproc AS
     i NUMBER ;
    BEGIN
     i := 100 ;
     DBMS_OUTPUT.put_line('i = '||i) ;
    END ;
    /
    执行过程: exec 过程名字---------set serveroutput on
    下面编写一个过程,要求,可以传入部门的编号,部门的名称,

    部门的位置,之后调用此过程就可以完成部门的增加操作。
    CREATE OR REPLACE PROCEDURE myproc(dno dept.deptno%TYPE,
      name dept.dname%TYPE,
      dl dept.loc%TYPE)
    AS
    cou NUMBER ;
    BEGIN
     -- 判断插入的部门编号是否存在,如果存在则不能插入
     SELECT COUNT(deptno) INTO cou FROM dept WHERE deptno=dno

    ;
     IF cou=0 THEN
      -- 可以增加新的部门
    INSERT INTO dept(deptno,dname,loc) VALUES(dno,name,dl) ;

    DBMS_OUTPUT.put_line('部门插入成功!') ;
    ELSE
      DBMS_OUTPUT.put_line('部门已存在,无法插入!') ;
     END IF ;
    END ;
    /
    16.2 过程的参数类型:
    ? IN:值传递,默认的-----只读
    ? IN OUT:带值进,带值出---可读写
    ? OUT:不带值进,带值出----只写
    IN OUT 类型:
    CREATE OR REPLACE PROCEDURE myproc(dno IN OUT

    dept.deptno%TYPE,
    name dept.dname%TYPE,
    dl dept.loc%TYPE) AS
     cou NUMBER ;
    BEGIN
     -- 判断插入的部门编号是否存在,如果存在则不能插入
     SELECT COUNT(deptno) INTO cou FROM dept WHERE deptno=dno

    ;
     IF cou=0 THEN
      -- 可以增加新的部门
      INSERT INTO dept(deptno,dname,loc) VALUES(dno,name,dl)

    ;
      DBMS_OUTPUT.put_line('部门插入成功!') ;
      -- 修改 dno 的值
      dno := 1 ;
     ELSE
      DBMS_OUTPUT.put_line('部门已存在,无法插入!') ; dno :=

    -1 ;
     END IF ;
    END ;
    /
    编写 PL/SQL 块验证过程:
    DECLARE
     deptno dept.deptno%TYPE ; BEGIN
     deptno := 12 ;
     myproc(deptno,'开发','南京') ;
     DBMS_OUTPUT.put_line(deptno) ;
    END ;
    /
    OUT 类型 不带任何值进,只把值带出来。
    CREATE OR REPLACE PROCEDURE myproc(dno OUT dept.deptno

    %TYPE)
    AS
     I number
    BEGIN
      I:= dno;
    END ;
    /
    执行上面的存储过程
    DECLARE
     deptno dept.deptno%TYPE ;
    BEGIN
    deptno :=myproc(deptno) ;
     DBMS_OUTPUT.put_line(deptno) ;
    END ;
    /
    第十七章 包
    17.1 定义
    包------规范和主体
    包就是将一系列的相关联的PLSQL类型、项目和子程序等有计划的

    组织起来封装在一起
    规范(包头)---------一个操作或应用的接口部分
    主体----------对包的规范部分进行实现
    语法;
    包的规范
    CREATE OR REPLACE PACKAGE package_name AS|IS
    参数、类型(type)、异常(exception)、游标(cursor)、

    procedure、function
    END[package_name];
    包的主体
    CREATE OR REPLACE PACKAGE BODY package_name AS|IS
    参数、类型(type)、异常(exception)、游标(cursor)、

    procedure、function
    END[package_name];
    调用:
    package_name.type_name;
    package_name.item_name;
    package_name.call_spec_name;
    删除:
    drop package package_name;
    drop package body package_name;
    好处:
    1、模块化;-----提高应用程序的交互性
    2、信息隐藏
    例:
    CREATE OR REPLACE PACKAGE DEMO_PKG
    IS
      DEPTREC DEPT%ROWTYPE;
     
      --Add dept...
      FUNCTION add_dept(
               dept_no NUMBER,
               dept_name VARCHAR2,
               location VARCHAR2)
      RETURN NUMBER;
     
      --delete dept...
      FUNCTION delete_dept(dept_no NUMBER)
      RETURN NUMBER;
     
      --query dept...
      PROCEDURE query_dept(dept_no IN NUMBER);
    END DEMO_PKG;
    CREATE OR REPLACE PACKAGE BODY DEMO_PKG
    IS
    FUNCTION add_dept
    (
       dept_no NUMBER,
       dept_name VARCHAR2,
       location VARCHAR2
    )
    RETURN NUMBER
    IS
      empno_remaining EXCEPTION; --自定义异常
      PRAGMA EXCEPTION_INIT(empno_remaining, -1);
       /* -1 是违反唯一约束条件的错误代码 */
    BEGIN
      INSERT INTO dept VALUES(dept_no, dept_name, location);
      IF SQL%FOUND THEN
         RETURN 1;
      END IF;
    EXCEPTION
         WHEN empno_remaining THEN
            RETURN 0;
         WHEN OTHERS THEN
            RETURN -1;
    END add_dept;
    FUNCTION delete_dept(dept_no NUMBER)
    RETURN NUMBER
    IS
    BEGIN
      DELETE FROM dept WHERE deptno = dept_no;
      IF SQL%FOUND THEN
        RETURN 1;
      ELSE
        RETURN 0;
       END IF;
    EXCEPTION
      WHEN OTHERS THEN
        RETURN -1;
    END delete_dept;
    PROCEDURE query_dept
    (dept_no IN NUMBER)
    IS
    BEGIN
          SELECT * INTO DeptRec FROM dept WHERE

    deptno=dept_no;
    EXCEPTION
           WHEN NO_DATA_FOUND THEN
              DBMS_OUTPUT.PUT_LINE('温馨提示:数据库中没有编码

    为'||dept_no||'的部门');
           WHEN TOO_MANY_ROWS THEN
              DBMS_OUTPUT.PUT_LINE('程序运行错误,请使用游标进

    行操作!');
           WHEN OTHERS THEN
               DBMS_OUTPUT.PUT_LINE(SQLCODE||'----'||

    SQLERRM);
    END query_dept;
    BEGIN
        Null;
    END DEMO_PKG;


    一、数据库连接
        1、JDBC连接
              1、加载JDBC驱动程序;
                        Class.forName

    ("com.mysql.jdbc.Driver");//oracle.jdbc.OracleDriver

        2、创建数据库的连接;

            Connection conn = DriverManager.getConnection

    (url,user,password);

        3、创建一个Statement对象;

            Statement stat = conn.createStatement() ;
            //PreparedStatement pstat =

    conn.prepareStatement(SQL_classification_INSERT);

        4、执行SQL语句;

            executeQuery 、executeUpdate  和execute
            ResultSet rs = stmt.executeQuery("SELECT * FROM

    ...") ;
            //rs=pstat.executeQuery();

        5、返回并处理结果;

            while(rs.next()){

                ...

            }

        6、关闭连接;

            rs.close() ;
            stat.close();
            conn.close();

        2、Hibernate连接
                <session-factory>

              <property

    name="dialect">org.hibernate.dialect.MySQLDialect</proper

    ty>

              <property

    name="connection.url">jdbc:mysql://localhost:3306/eshop_1

    </property>

              <property

    name="connection.username">root</property>

              <property

    name="connection.password">107510</property>

              <property

    name="connection.driver_class">com.mysql.jdbc.Driver</pro

    perty>

              <property

    name="myeclipse.connection.profile">eshop_1</property>

              <property name="show_sql">true</property>

              <property name="format_sql">true</property>

              <mapping class="com.yhtb.entity.TUsers" />

         </session-factory>

        Configuration cfg=new Configuration().configure();
                  SessionFactory sf=cfg.buildSessionFactory

    ();------------------2级缓存
                  Session session=sf.openSession

    ();-------------------------------------1级缓存
                  Transaction tx=session.beginTransaction();
                  session.save()//增删改查的动作
                  tx.commit();
                  session.close();
                  sf.close();

        3、SSH中数据源连接
                 <bean id="dataSource"

    class="org.apache.commons.dbcp.BasicDataSource">

              <property name="url"

    value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"></property>

              <property name="driverClassName"

    value="oracle.jdbc.OracleDriver"/>

              <property name="username"

    value="scott"></property>

              <property name="password"

    value="tiger"></property>

              <property name="defaultAutoCommit"

    value="false"></property>

             </bean>

        <bean id="sessionFactory"    

    class="org.springframework.orm.hibernate3.annotation.Anno

    tationSessionFactoryBean">

              <property name="dataSource">

               <ref bean="dataSource" /></property>

              <property name="hibernateProperties">

               <props><prop

    key="hibernate.dialect">org.hibernate.dialect.OracleDiale

    ct</prop>

                <prop key="hibernate.show_sql">true</prop>

                <prop

    key="hibernate.format_sql">true</prop></props></property>

              <property

    name="annotatedClasses"><list><value>com.rain.entity.Emp<

    /value></list></property>

             </bean>

    二、Oracle
        1、 事务的特性
            原子性、隔离性、持久性、一致性
            savepoint p
           commit
           rollback

        2、 动态SQL
                dml:

          ddl:
          占位符’:‘
        declare
          v_no emp1.ename%type:='&请输入号码'; --&变量绑定符
          v_name emp1.ename%type;
          v_job emp1.job%type;
          v_sql long:='select ename,job from emp1 where

    ename=:xxx';--占位符
        begin
           execute immediate v_sql into v_name,v_job using

    v_no;
           dbms_output.put_line('name= '||v_name||' job='||

    v_job);
        end;

        3、游标
            1、分类:
                显示游标----游标名%属性名
                隐式游标----SQL%
            2、步骤;

              显示游标 语法格式:

            CURSOR cursor_name is select * from emp;--声明游



            OPEN cursor_name;--打开游标

            FETCH cursor_name INTO variables_list;--提取游标

            CLOSE cursor_name;--关闭游标

            例1:

            DECLARE

              v_deptno NUMBER:=&inputno;

              v_row emp1%ROWTYPE;

              CURSOR v_cursor IS SELECT * FROM emp1 WHERE

    deptno=v_deptno;--声明游标

            BEGIN

              OPEN v_cursor; --打开

              --提取

              LOOP

                FETCH v_cursor INTO v_row;--先提取

                EXIT WHEN v_cursor%NOTFOUND;

                dbms_output.put_line('Employee Name: ' ||

    v_row.ename || ' ,Salary: ' || v_row.sal);

              END LOOP;

              --关闭

              CLOSE v_cursor;

            END;


            --隐式游标

                自动打开游标

                自动关闭游标

            通过隐式游标SQL的%ROWCOUNT属性来了解修改了多少行


            DECLARE
               v_rows NUMBER;
            BEGIN
            --更新数据
               UPDATE employees SET salary = 30000
               WHERE department_id = 90 AND job_id = 'AD_VP';
            --获取默认游标的属性值
               v_rows := SQL%ROWCOUNT;
               DBMS_OUTPUT.PUT_LINE('更新了'||v_rows||'个雇员

    的工资');
            --回退更新,以便使数据库的数据保持原样
               ROLLBACK;
            END;

            3、应用中---for游标----无需声明、打开、提取、关闭
               BEGIN

        --隐含打开游标
           FOR r IN (SELECT * FROM emp1 WHERE

    deptno=v_deptno) LOOP
        --隐含执行一个FETCH语句
              dbms_output.put_line('Employee Name: ' ||

    r.ename || ' ,Salary: ' || r.sal);
        --隐含监测c_sal%NOTFOUND
           END LOOP;
        --隐含关闭游标

             END;

        4、视图
                   1、假表【不存储数据,只存储定义,定义被保

    存数据字典】

             2、作用:数据安全:(隐藏行或者列,保证数据不会

    被误删除)
                   简化查询
             3、定义格式:
               CREATE OR REPLACE VIEW v_表名_业务
               as
                 查询语句

        5、索引

            1、原理:先在索引中根据关键字找到记录的rowid,然

    后利用rowid在基表中直接定位记录并检索出来,所以速度快
            2、特征:1、索引自动维护
                            2、索引需要占据实际存储空间
                            3、对于表中的主键列,将自动建立唯

    一索引          
            3、语法:

                create index 索引名

                on

                表名(列1,列2,...)

                drop index 索引名

           4、作用:提高查询速度,通常情况下,索引应该建立在

    那些经常出现在where子句中的列上


        6、序列
              1、步骤

            CREATE SEQUENCE seq

              INCREMENT BY 2--增量

              START WITH 2--起始值 不能小于min

              MAXVALUE 10--最大值

              MINVALUE 1--最小值

              CYCLE--/NOCYCLE 序列号是否可循环(到了maxvalue

    在从min开始)

              CACHE 5--/NOCACHE 缓存下一个值,必须满足大于1,

    小于等于(MAXVALUE-MINVALUE)/INCREMENT

              NOORDER--/NOORDER 序列号是否顺序产生

        2、 属性   NextVal,CurrVal

              3、作用
                    序列通常和触发器一起使用,来自动生成主键

        7、函数
              1、定义:函数就是一个有返回值的过程。

        2、步骤:此函数可以根据雇员的编号查询出雇员的年薪

            CREATE OR REPLACE FUNCTION myfun(eno emp.empno

    %TYPE)

            RETURN NUMBER

            AS

                 rsal NUMBER ;

            BEGIN

                 SELECT (sal+nvl(comm,0))*12 INTO rsal FROM

    emp WHERE empno=eno ;

                RETURN rsal ;

            END ;

            /

        3、直接写 SQL 语句,调用此函数:

            SELECT myfun(7369) FROM dual ;

            v_dfd := EXEC myfun(7369);


        8、触发器
            1、分类;

            DML触发器-----------基于表的(insert、alter、

    update)

            替代触发器-----------基于VIEW的---行级

            系统触发器-----------基于系统的

          2、创建步骤;
                CREATE [OR REPLACE] TRIGGER trigger_name

            {BEFORE | AFTER }

            {INSERT | DELETE | UPDATE [OF column [, column …

    ]]}

            [OR {INSERT | DELETE | UPDATE [OF column [,

    column …]]}...]

            ON [schema.]table_name | [schema.]view_name

            [REFERENCING {OLD [AS] old | NEW [AS] new| PARENT

    as parent}]

            [FOR EACH ROW ]

            [WHEN condition]

            PL/SQL_BLOCK | CALL procedure_name;

          3、作用
                自动调用、记录日志、保证数据安全、用数据库触

    发器可以保证数据的一致性和完整性。
           
             触发器(语句级、行级、谓词、分类、作用)
                 基于表的触发器:[delete\update\insert]

        create or replace trigger tr_src_emp
        before insert or update or delete
        on emp
        begin
        if to_char(sysdate,'DY') in( '星期六','星期天') then
        case

        when inserting then
          raise_application_error(-20001,'fail to insert');  
        when updating then
          raise_application_error(-20001,'fail to update');
         when deleting then
          raise_application_error(-20001,'fail to delete');
        end case;
        end if;
        end;

        /


        9、存储过程
            1、定义
                CREATE OR REPLACE PROCEDURE procedure_name
                AS PL/SQL块
            2、参数类型
                ?  IN:值传递,默认的-----只读

        ?  IN OUT:带值进,带值出---可读写

        ?  OUT:不带值进,带值出----只写

            3、作用
                将通用的执行过程封装起来

        10、包
                1、语法;

        包的规范

        CREATE OR REPLACE PACKAGE package_name AS|IS

            参数、类型(type)、异常(exception)、游标(cursor)

    、procedure、function

        END[package_name];


        包的主体

        CREATE OR REPLACE PACKAGE BODY package_name AS|IS

            参数、类型(type)、异常(exception)、游标(cursor)

    、procedure、function

        END[package_name];

        2、调用:

            package_name.type_name;

            package_name.item_name;

            package_name.call_spec_name;

               3、作用
                    1、模块化;-----提高应用程序的交互性
                    2、信息隐藏

        11、体系结构
    三、Struts 2.1
              1、校验框架

        2、配置文件
        <struts>
          <package name="mypackage" extends="json-default">
            <action name="login" class="UsersAction"

    method="login">
              <result name="success" >/index.jsp</result>
              <result name="error" >/login.jsp</result>
            </action>
        </package>
        </struts>

        3、国际化
        <constant name="struts.i18n.encoding" value="utf-8"

    />
        4、工作原理

            1、struts1 工作原理
            2、struts2工作原理

        6、struts2标签

            <%@taglib uri="/struts-tags" prefix="s"%>

        7、EL表达式的四个范围
                pageScope、requestScope、sessionScope、

    appalicationScope
        8、客户端校验和服务端校验的优缺点
                客户端校验比服务端校验快,但如果用户禁掉js的

    话,客户端校验即失效,服务端校验用户不能禁掉
        9、struts2的校验框架------服务端校验有基于action的硬

    编码和基于xml配置文件两种-------------十三中内置校验器

            一、基于Action的硬编码实现步骤
            1、Action必须extends ActionSpport
            2、对某个方法进行校验,需要在Action中添加一个

    validateXxx().该方法无需返回值,在该方法中加入

    addFieldError(" "," ")或者addActionError(" ");
            3、在配置文件struts.xml中,必须增加一个<result

    name="input">/验证页面</result>
            4、在错误页面上显示错误信息。
               a、页面必须使用struts标签<s: addFieldError>、

    <s:addActionError>
                b、修改配置文件中的过滤器
                      <filter-mapping>

                    <filter-name>struts2</filter-name>

                    <url-pattern>/*</url-pattern>

                  </filter-mapping>
                二、基于XML配置文件的实现步骤


            a、找到对应的DTD文件头
            <!DOCTYPE validators PUBLIC
                "-//OpenSymphony Group//XWork Validator

    1.0.2//EN"
                "http://www.opensymphony.com/xwork/xwork-

    validator-1.0.2.dtd">

    四、Hibernate 3.3
            1、查询方式
                HQL【delete、update、select】
                QBC【条件】
                QBE【FindByExample】
                 load/get查询

           native SQL查询
           命名SQL查询

            2、缓存
                一级缓存:session
                二级缓存:sessionFactory

            3、接口
                SessionFactory
                Session
                Transacation
                Query
                Criteroa

            4、对象状态
                 瞬时态、持久态、游离态
            5、关联映射
                one-to-many,many-to-one,one-to-one,many-

    to-many
            6、hibernate常见主键增长方式:
                increment、identity、native、assigned、

    foreign、sequence
                select max(id) from TABLE
                id+1            n+1
            7、 hibernate的抓取策略:
                   select、join、fetch
            8、hibernate的延迟策略:
                  proxy

            lazy[关联级别、类级别]

            
    五、Spring 3.0

        1、Spring是什么?
           Spring是一个容器框架,它管理所有的JavaBean的生命周


           Spring提供了六大模块:(core、aop、dao、orm、JEE、

    web)
           Spring提供了强大的解耦,【IOC/DI,aop】
        2、IOC
           DI注入的方式:setter、construstor

            3、AOP

        切面(aspect):用来切插业务方法的类。
        连接点(joinpoint):是切面类和业务类的连接点,其实就是

    封装了业务方法的一些基本属性,作为通知的参数来解析。
        通知(advice):在切面类中,声明对业务方法做额外处理的

    方法。
        切入点(pointcut):业务类中指定的方法,作为切面切入的

    点。其实就是指定某个方法作为切面切的地方。
        目标对象(target object):被代理对象。
        AOP代理(aop proxy):代理对象。

    AOP通知类型:

        前置通知(before advice):在切入点之前执行。
        后置通知(after returning advice):在切入点执行完成后

    ,执行通知。
        环绕通知(around advice):包围切入点,调用方法前后完成

    自定义行为。
        异常通知(after throwing advice):在切入点抛出异常后,

    执行通知。

    11、AJAX
          1、什么是AJAX
                AJAX = Asynchronous JavaScript and XML(异步

    的 JavaScript 和 XML)。
        2、ajax的特点:局部刷新
        3、Ajax所涉及的技术:JavaScript、XML、CSS、DOM(文档对

    象模型,在内存中以树结构存储的模型)
        4、Ajax的核心类:XMLHttpRequest               
                注意:不同的厂家ActiveXObject(IE5及以下)
        5、Ajax常见的框架:JQuery、DOJO、prototype(原型)、

    DWR(直接web远程访问)、YUI(雅虎用户界面)、ExtJS
        6、Ajax应用的开发步骤:

        //1、创建XMLHttpRequest()对象
           if (window.XMLHttpRequest){// code for IE7+,

    Firefox, Chrome, Opera, Safari
             xmlhttp=new XMLHttpRequest();
           }else{// code for IE6, IE5
             xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
           }
         //2、处理响应(responseText或responseXML)
           xmlhttp.onreadystatechange=function(){
              if (xmlhttp.readyState==4 &&

    xmlhttp.status==200){
                //局部刷新的代码,通常有以下语句        

    document.getElementById

    ("data").innerHTML=xmlhttp.responseText;
                //js操作Html
               }
             };
           //3、向服务器发送请求
           xmlhttp.open("GET","/ajax1/index.jsp?

    t="+Math.random(),true);
           xmlhttp.send();//只有是GET提交时才赋值为NULL

    12、JSON

        1、JSON是什么

               a、JavaScript 对象表示法(JavaScript Object

    Notation)。
              {


            "employees": [


            { "firstName":"Bill" , "lastName":"Gates" },


            { "firstName":"George" , "lastName":"Bush" },


            { "firstName":"Thomas" , "lastName":"Carter" }


            ]


        }

              b、JSON 是存储和交换文本信息的语法。类似 XML。

              c、JSON 比 XML 更小、更快,更易解析

        

    13、js的对象

         1、内置对象

                String: var s = new String("23213");

                Date:      var d = new Date();

                Math:     Math.random();

                Array:     var a = new Array();

                Object:   var o = new Object();

        2、js的浏览器对象(BOM)

                window: window.alert()、 window.confirm、

    window.setTimeout()                                       

            

                document:document.getElementById()、

                                  

    document.getElementByTagName()

                location:window.location.href

        3、js中的DOM对象

            HTML、BODY、SELECT、INPUT

        4、js的自定义对象

              <script type="text/javascript">

              <!--

            方法一:

             //1、定义类

              function person(name,sex){

                   this.name=name;

                   this.sex=sex;

              }

             //2、实例化

             var p1 = new person("rain","man");


            方法二:--------------------JSON

            定义并实例化:

            var p2 = {"name":"你的","sex":"women"};


            var p = [{"name":"张三丰","sex":"男","tel":

    {"t1":"332","t2":"445"}},{"name":"张无忌","sex":"男 "},

    {"name":"张翠山","sex":"男 "}];


             //3、显示数据

             alert(p.name);

             alert(p.sex);

             confirm(p.name);


            //alert(p[1].name);

             //alert(p[0].sex);

             //confirm(p[2].name);

             alert(p[0].tel.t1);


            //将字符串转化成对象-----------JSON

             var pp = '{"name":"张三丰","sex":"男","tel":

    {"t1":"332","t2":"445"}}';

             alert(eval('('+pp+')').name);


              //-->

          </script>


    14、JQuery
            
        1、定义:Jquery是一个丰富的js库    
        2、JQuery对象就是通过Jquery包装DOM对象后产生的对象

            <script type="text/javascript" src="jquery-

    1.11.0.js"></script>

             <script type="text/javascript">

             <!--/*//第一种格式:

              function f1(){

               alert('Hello World!');

              };

              $(document).ready(f1);

             //第二种格式:

              $(document).ready(function(){

               alert('Hello World!');

              });*/

             $(document).ready(function(){

               //$('#111').css('background-color','blue')

               // .css('width','234')

               // .css('height','333')//修改样式

               // .html('<hr/>hello')//修改值

               // .html();//取值

               //$('#111').css({'background-

    color':'blue','width':'120','height':'120'})//修改样式

               // .text('<hr/>hello');//修改值

               //$('.222,#111').html('<hr/>');

               //$('div:last').html('hehehhe');

               //$('div:first').html('hehehhe');

               //$('#111>p').html('<hr/>');

               //$('#111 p').html('<hr/>');

               //$('#111+.222').html('<hr/>');

               //$('#111 ~ p').html('<hr/>');

               //$('tr:odd').css({'background-

    color':'blue'});

               //$('tr:even').css('background-

    color','#eeffee');

               //$('tr:eq(0)').css({'background-

    color':'blue'});

               //$('tr:gt(1)').css({'background-

    color':'blue'});

               $('tr:lt(1)').css({'background-

    color':'blue'});

             });

             //--></script> </head>

             <body>

              <div id="111">sssssssssss

              <p>sfdsf</p>

              </div>

              <p>sfdsf</p>

              <div class="222">sssssssssss</div>

              <div >sssssssssss</div>

              <table border="1"><center>

             <tr><td>1</td><td>1</td></tr>

             <tr><td>22</td><td>22</td></tr>

             <tr><td>333</td><td>333</td></tr>

             <tr><td>4444</td><td>4444</td></tr>

              </table></center></body>

            例2:
            <script type="text/javascript" src="jquery-

    1.11.0.js"></script>
               <script type="text/javascript">
                $(function(){
                 alert(222);
                 $('button').click(function(){
                  $('#list').load('index.jsp');
                 });
                });
               </script>
              </head>
             
              <body>
                <div id="list"></div>
                <button>获取服务器数据</button>
              </body>

    六、SSH

        Spring----------3.0
                定义:是一个管理JavaBean生命周期的容器型的轻

    量型框架,包含六大模块DAO、ORM、Web、Core、JEE、AOP
        Hibernate------3.3
                ORM持久型框架---映射---POJO的属性和表中的字段

    ,对象和表,POJO的属性的类型与表中字段的属性的类型
        Struts-----------1.3/2.1
                MVC的web轻量型框架



        VO--------------------值对象
        DTO------------------数据传输对象
        BO--------------------业务对象
        PO---------------------持久化对象
        POJO-----------------简单无规则Java对象(JavaBean)
        DAO-------------------数据访问对象


    七、泛型DAO
            1、设计通用DAO接口

              public interface IGenericDAO<T,ID extends

    Serializable>{
                 public abstract void save(T entity);
                 public abstract void update(T entity);
                 public abstract void delete(ID id);
                 public abstract T findById(ID id);
                 public abstract List<T> findAll();
                 public abstract List<T> findByExample(T

    entity);
                 public abstract int count(T entity);
                 public abstract pageVO<T> findByPage(T

    entity,int currentpage,int pageSize);
              }
         
        2、设计通用DAO的实现类
             public class GenericDAOImpl<T,ID extends

    Serializable> extends HibernateDaoSupport implements

    IGenericDAO<T,ID>{
                 protected class<?> clazz;
                //初始化clazz
                public GenericDAOImpl(){
         //1、得到我们的通用范型实现类的子类,例如:得到

    EmpDAOImpl
             Class<?> cls=getClass();
         //2、得到具体类【EmpDAOImpl】的父类,由于父类是范型

    类,所以,方法为:
             ParameterizedType ptype=(ParameterizedType)

    cls.getGenericSuperclass();
         //3、得到具体的参数实际类型
            clazz=(Class<?>)(ptype.getActualTypeArguments()

    [0]);
                }
         
                 public void save(T entity){
                     getHibernateTemplate().save(entity);
                 }
                 public void update(T entity){
                     getHibernateTemplate().update(entity);
                 }
                 public void delete(ID id){
                     getHibernateTemplate().delete(id);
                 }
                 public T findById(ID id){
                       return T(getHibernateTemplate().get

    (clazz,id));
                 }
                 public List<T> findAll(){
           DetachedCriteria

    criteria=DetachedCriteria.forClass(entityClass);
          return getHibernateTemplate().findByCriteria

    (criteria);;
          }
                 public List<T> findByExample(T entity){
          return getHibernateTemplate().findByExample

    (instance);
          }
                 public int count(T entity){}
                 public pageVO<T> findByPage(T entity,int

    currentpage,int pageSize){}
             
        3、设计每个业务DAO接口,例如IEmpDAO
              public interface IEmpDAO extends

    IGenericDAO<Emp,Integer>{
                  //新增自己DAO的特有方法:例如登录
                  Emp login(String account,String password);
              }
        4、设计每个业务DAO的实现类,例如EmpDAOImpl
              public class EmpDAOImpl extends

    GenericDAOImpl<Emp,Integer> implements IEmpDAO{
                      public Emp login(String account,String

    password){
                          return null;
                      }
              }
            }

        购物车





        链接:
        1、JAVA
        2、JDBC
        3、OA开发
        4、Oracle
        5、WEB
        6、AJAX
        7、Hibernate
        8、Spring
        9、struts1
        10、总结

    展开全文
  • java知识总结 android知识总结和j2ee知识总结 绝对对的起你下载的资源分
  • java知识总结针对java学习过程可能出现的一些容易混淆的问题进行了汇总
  • java知识总结——关键字(二)说明一、static关键字 说明   本文仅仅为了博主面试时方便查阅与梳理相关知识,如果有错误与不到位的地方,欢迎大佬指点改正,谢谢!   阅读书籍:《java程序员面试笔试宝典》 一、...

    说明

      本文仅仅为了博主面试时方便查阅与梳理相关知识,如果有错误与不到位的地方,欢迎大佬指点改正,谢谢!
      阅读书籍:《java程序员面试笔试宝典》

    一、static关键字

      1、作用
      static关键字主要有两种作用:第一,为某特定数据类型或对象分配单一的存储空间,而与创建对象的个数无关。第二,实现某个方法或属性与类而不是与对象关联在一起,即在不创建对象的情况下就可以通过类来直接调用方法或使用类的属性。
      2、使用情况
      static主要有4种使用情况:成员变量、成员方法、代码块和内部类
      (1)static成员变量(静态变量)
      变量可以通过static达到全局的效果。

      java提供类提供了两种类型的变量:用static关键字修饰的静态变量和不同static关键字修饰的实例变量
      静态变量属于类,在内存中只有一个复制(所有实例都指向同一个内存地址),只要静态变量所在的类被加载,这个静态变量就会被分配空间。
      对静态变量有两种引用方式:“类.静态变量和对象.静态变量”
      实例变量属于对象,只有对象被创建后,实例变量才会被分配空间,才能被使用,它在内存中存在多个复制。只能用“对象.实例变量”的方式来引用。

      静态变量只有一个,被类拥有,所有对象都共享这个静态变量,而实例对象是与具体对象相关的。
      注意:不能在方法体中定义static变量。
      (2)static成员方法(静态方法)
      static方法是类的方法,不需要创建对象就可以被调用。而非static方法是对象的方法,只有对象被创建出来后才可以被使用。
      static方法中不能使用this和super关键字,不能调用非static方法,只能访问所属类的静态成员变量和成员方法,因为当static方法被调用时,这个类的对象可能还没被创建,即使已经被创建了,也无法确定调用哪个对象的方法。

      static的重用用途之一:实现单例模式
      单例模式的特点是该类只能有一个实例,为了实现这一功能,必须隐藏类的构造函数,即把构造函数声明为private,并提供一个创建对象的方法,由于构造对象被声明为private,外界无法直接创建这个类型的对象,只能通过该类的方法来获取类的对象,要达到这样的目的只能把对象的方法声明为static。

      用public修饰的static变量和方法本质上都是全局的,若在static变量前用private修饰,则表示这个变量可以在类的静态代码块或者类的其他静态成员方法中使用,但是不能在其他类中通过类名来直接引用。
      (3)static代码块(静态代码块)
      静态代码块在类中是独立于成员变量和成员函数的代码块的。它不在任何一个方法体内,JVM在加载类时会执行static代码块,如果有多个static代码块,JVM将会按照属性来执行。static代码块经常被用来初始化静态变量
      注意:这些static代码块只会被执行一次。
      (4)static内部类
      static内部类是指被声明为static的内部类,它可以不依赖于外部类实例对象而被实例化,而通常的内部类需要在外部类实例化后才能被实例化。静态内部类不能与外部类有相同的名字,不能访问外部类的普通成员变量,只能访问外部类值中的静态成员和静态方法(包括私有类型)
      注意:只有内部类才能被定义为static。

      什么是实例变量?什么是局部变量?什么是类变量?什么是final变量?
      实例变量:变量归对象所有(只有实例化对象后才可以)。每当实例化一个对象时,会创建一个副本并初始化,如果没有显示初始化,那么会初始化一个默认值。各个对象中的实例变量互不影响。
      局部变量:在方法中定义的变量,在使用前必须初始化。
      类变量:用static修饰的书写、变量归类所有,只要类加载,这个变量就可以被使用(类名.变量名)。所有实例化的对象共享类变量。
      final变量:表示这个变量为常量,并不能被修改。

      static和final结合使用表示什么意思?
      在java语言中,static关键字常与final关键字结合使用,用来修饰成员变量和成员方法。对于变量,若使用static final修饰,则表示一旦赋值,就不可修改,并且通过类名可以访问。对于方法,若用static修饰,则表示该方法不可覆盖,并且可以通过类名直接访问。

    二、switch的使用

      switch语句用于多分值选择,使用switch(expr)时,expr只能是一个枚举常量(内部也是由整型或字符类型实现)或一个整数表达式,其中整数表达式可以是基本类型int或其对应的包装类Integer,当然也包括不同的长度整型,例如short。**由于byte、short和char类型的值都能被隐式地转换为int类型,因此这些类型以及它们对应的包装类型都可以作为switch的 表达式。但是,long、float、double、String类型不能够隐式的转换为int类型,因此它们不能被用作switch的表达式。**如果一定要使用的话,需要强制转换为int类型。
      与switch对应的是case语句,case语句之后可以是直接的常量数值,也可以是一个常量计算式,还可以是final型的变量(final变量必须是编译时的常量)

      注意:在java7之后,switch开始支持String类型。
      从本质上讲,switch对字符串的支持,实际上是int类型值的匹配。

      注意:使用switch时,一般必须在case语句结尾添加break语句。
      一旦通过switch语句确定了入口点,就会顺序执行后面的代码,直到遇到关键字break。否则,会执行满足这个case之后的其他case语句而不管case是否匹配,直到switch结束或者遇到break为止。如果在switch语句中忽略了brake语句,那么匹配的case值后的所有情况(包括default)都会被执行。

    三、volatile的使用

      在用java语言编写的程序中,有时为了提高程序的运行效率,编译器会自动对其进行优化,把经常访问的变量缓存起来,程序在读取这个变量时又可能会直接从缓存中来读取这个值,而不会去内存中读取。好处是提高了程序的运行效率,但是在遇到多线程编程时,变量的值可能因为被的线程而改变了,而该缓存的值不会相应改变,从而造成应用程序读取的值和实际的变量值不一致

      volatile是一个类型修饰符,被设计用来修饰被不同线程访问和修改的变量被volatile类型定义的变量,系统每次用到它时都是直接从对应的内存当中提取,而不会利用缓存。在使用了volatile修饰变量后,所有线程在任何时候所看到变量的值都是相同的。
      `注意:volatile不能保证操作的原子性,因此,一般情况下volatile不能代替sychronized。此外,使用volatile会阻止编译器对代码的优化,因此会降低程序的执行效率。

    四、instanceof的使用

      instanceof是java语言中的一个二元运算符,它的作用是判断一个引用类型的变量所指向的对象是否是一个类(或接口、抽象类和父类)的实例,即它左边的对象是否是它右边的类的实例该运算符返回boolean类型数据
      常见用法

    	result = object instanceof class
    	//如果object是class的一个实例,那么instanceof运算符返回true;
    	//如果object不是class的一个实例,或者object为null,那么instanceof运算符返回false。
    

    五、strictfp的使用

      1、概念
      关键字strictfp是strict float point的缩写,指的是精确浮点
      2、作用
      用来确保浮点数运算的准确性,在不同的硬件平台上会有一致的运行结果。

    展开全文
  • Java知识总结--SE篇

    千次阅读 多人点赞 2020-06-15 13:12:44
    1-1-什么是Java的跨平台原理 Java通过不同的系统,不同的版本不同的位数的Java虚拟机(JVM)来屏蔽不同的指令集,然后对外提供了统一的Java接口(API),这样,我们的开发者只需按照接口开发即可,如果系统需要...

    Java-SE


    目录

    Java-SE

    1-1-什么是Java的跨平台原理

    1.2-JDK 和 JRE 有什么区别?

    1.3-Java基本数据类型

    1.4-Java基本类型所占字节和范围

    1.5-int(long) 和 float(double) 哪个表示的范围大?为什么?

    1.6-Int和Integer的区别,在使用时有什么区别?

    1.7-有了基本的数据类型,为什么还需要包装类型

    1.8-装箱和拆箱,自动拆箱,自动装箱

    1.9-重写,重载

    1.10-==和equals方法的区别

    1.11- final 在 java 中有什么作用?

    1.12-面向对象的特征有哪些方面

    1.13-接口和抽象类(接口的抽象级别最高)

    1.14-抽象类不是必须要有抽象方法

    1.15-普通类和抽象类的区别

    1.16-抽象类不能使用 final 修饰

    1.17-String底层实现,不可变的原因

    1.18-String 不属于基础的数据类型

    1.19-String str="str"与 String str=new String("str")的内存分配

    1.20- String 类的常用方法

    1.21-String,StringBuilder,StringBuffer的区别?

    1.22-什么是值传递和引用传递?

    1.23-SimpleDateFormat的作用和用法

    1.24- java 中 IO 流分类

    1.25-Java的流

    1.26- Files的常用方法

    1.27-如何创建文件和目录?

    1.28-面向对象编程的六大原则

    1.29-设计模式

    1.30- 运行时异常与一般异常的区别

    1.31-&和&&的区别

    1.32-final, finally, finalize的区别。

    1.33-error和exception的区别。

    1.34-Math.round(9.5)等多少? Math.round(-9.5)等多少?

    1.35-Java流程控制语句

    1.36-反射

    1.37-反射相关的类

    1.38-反射的功能

    1.39-反射的优点

    1.40-反射的缺点

    1.41-反射的使用场景

    1.42-动态代理

    1.43-动态代理的应用场景

    1.44-动态代理实现

    1.45-序列化和反序列化

    1.46-序列化使用场景

    1.47-怎么实现序列化

    1.48-序列化需要付出的代价

    1.49-BIO,NIO,AIO


    1-1-什么是Java的跨平台原理

                 Java通过不同的系统,不同的版本不同的位数的Java虚拟机(JVM)来屏蔽不同的指令集,然后对外提供了统一的Java接口(API),这样,我们的开发者只需按照接口开发即可,如果系统需要部署在不同的环境是,只需要系统上面按照片对应版本的虚拟机即可


    1.2-JDK 和 JRE 有什么区别?

    • JDK:java 开发工具包,提供了 java 的开发环境和运行环境。
    • JRE:java 运行环境,为 java 的运行提供了所需环境。

    1.3-Java基本数据类型


    1.4-Java基本类型所占字节和范围


    1.5-int(long) 和 float(double) 哪个表示的范围大?为什么?


    float表示的 范围更大。float 和 int 都是4个字节,而 float 还要表示小数,为什么 float 表示的数字范围大?

    • int 底层使用的是补码的方式表示一个数:1 位符号位 + 31 位二进制数

    • float 底层使用的是IEEE 754 浮点单精度数字格式,简单来说就是用指数的形式去表示一个数:1 位符号位 + 8 位指数 + 23位尾数

    1.6-Int和Integer的区别,在使用时有什么区别?

    1. Integerint的包装类,int则是java的一种基本数据类型

    2. Integer变量必须实例化后才能使用,而int变量不需要

    3. Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int则是直接存储数据值

    4. Integer的默认值是null,int的默认值是0


    1.7-有了基本的数据类型,为什么还需要包装类型

    • 因为Java是一个面向对象的语言,而基本的数据类型不具备面向对象的特性

    1.8-装箱和拆箱,自动拆箱,自动装箱

    1. 装箱:把基本的数据类型转换成对应的包装类型

    2. 拆箱:把包装类型转换成对应的基本数据类型

    3. 自动装箱实际上编译时会调用integer.valueOf方法来装箱   Integer i=1;

    4. 自动拆箱实际上编译时会调用intValue方法来拆箱   Int j=i.intValue();


    1.9-重写,重载

    重载:方法名字相同,而参数不同。返回类型可以相同也可以不同

    重写:子类定义的方法与父类中的方法具有相同的方法名字,相同的参数表和相同的返回类型

    • 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为 private 和 final 的方法。

    • 子类和父类不在同一个包中,那么子类只能够重写父类的声明为 public 和 protected 的非 final 方法。

    • 声明为 static 的方法不能被重写,但是能够被再次声明。

    • 子类如果不是抽象类,则必须重写父类中的abstract方法。

    • 如果不能继承一个方法,则不能重写这个方法。


    1.10-==和equals方法的区别

    ==对于基本类型是比较的是是否相同,对于引用类型比较的是地址是否相同。equals默认情况下是引用的比较,只是很多类重写了 equals的方法,比如spring,integer等把它变成了值比较,所以一般情况下equals比较的是是否相等


    1.11- final 在 java 中有什么作用?

    • final 修饰的类叫最终类,该类不能被继承。

    • final 修饰的方法不能被重写。

    • final 修饰的变量叫常量,常量必须初始化,初始化之后值就不能被修改。


    1.12-面向对象的特征有哪些方面

    多态,继承,封装, (抽象)

    • 抽象:把一个对象,抽象为类

    • 封装:隐藏类的内部信息,外部类不可以直接访问,可以通过get/set去获取或值改变这个类

    • 继承:通过extends继承父类的基本特征和行为,子类也可以改变这些基本特征和行为

    • 多态:也就是同一个操作作用在不同对象上面的时候可以产生不同的效果


    1.13-接口和抽象类(接口的抽象级别最高)

    相同点:

    • 不能被实例化。

    不同点:

    • 抽象类要被子类继承extends,接口要被类实现implements 

    • 抽象类可以有构造函数;接口不能有。

    • 接口支持多继承,抽象类只允许单继承。

    • 接口只能做方法声明,抽象类中可以作方法声明,也可以做方法实现。

    • 接口里定义的变量只能是公共的静态的常量,抽象类中的变量是普通变量。

    • 抽象类可以有具体的方法和属性,接口只能有抽象方法和不可变常量。

    • 抽象类可以有 main 方法,并且我们能运行它;接口不能有 main 方法。


    1.14-抽象类不是必须要有抽象方法

         不需要,抽象类不一定非要有抽象方法。

    public abstract class Person{
        public static void say() {
            System.out.println("HELLO");
        }
    }

    1.15-普通类和抽象类的区别

    • 普通类不能包含抽象方法,抽象类可以包含抽象方法。

    • 抽象类不能直接实例化,普通类可以直接实例化。


    1.16-抽象类不能使用 final 修饰

    定义抽象类就是让其他类继承的,如果定义为 final 该类就不能被继承,这样彼此就会产生矛盾,所以 final 不能修饰抽象类


    1.17-String底层实现,不可变的原因

    String的底层是使用char数组的,char数组和String类都是被final修饰的,所以不可以改变


    1.18-String 不属于基础的数据类型

    String 不属于基础类型,String 属于对象。


    1.19-String str="str"与 String str=new String("str")的内存分配

    因为内存的分配方式是不一样的,String str="str"的方式,java 虚拟机会将其分配到常量池中;而 String str=new String("str") 则会被分到堆内存中。


    1.20- String 类的常用方法

    • length()字符串的长度

    • charAt() 截取一个字符

    • equals()和equalsIgnoreCase() 比较两个字符串

    • compareTo()和compareToIgnoreCase() 比较字符串

    • concat() 连接两个字符串

    • replace() 替换

    • toUpperCase() /toLowerCase() 转换为大小写

    • trim() 去掉起始和结尾的空格

            String test="abcdefg";
            String test2="   ABCDEFG    ";
            System.out.println("字符串长度=" + test.length());
            System.out.println("截取一个字符 = " + test.charAt(2));
            int compareTo = test.compareTo(test2);
            System.out.println("compareTo = " + compareTo);
            int compareToIgnoreCase = test.compareToIgnoreCase(test2);
            System.out.println("compareToIgnoreCase = " + compareToIgnoreCase);
            boolean b = test.equals(test2);
            System.out.println("b = " + b);
            boolean b1 = test.equalsIgnoreCase(test2);
            System.out.println("b1 = " + b1);
            String str=test.concat(test2).concat("test");
            System.out.println("str = " + str);
            str=str.replace("test","idea");
            System.out.println("str = " + str);
            str=str.toLowerCase();
            System.out.println("str = " + str);
            str=str.toUpperCase();
            System.out.println("str = " + str);
            int test2Length=test2.length();
            test2=test2.trim();
            System.out.println("test2Length2 = " + test2Length);
            int test2Length1=test2.length();
            System.out.println("test2Length1 = " + test2Length1);
    //字符串长度=7
    //截取一个字符 = c
    //compareTo = 65
    //compareToIgnoreCase = 65
    //b = false
    //b1 = false
    //str = abcdefg   ABCDEFG    test
    //str = abcdefg   ABCDEFG    idea
    //str = abcdefg   abcdefg    idea
    //str = ABCDEFG   ABCDEFG    IDEA
    //test2Length2 = 14
    //test2Length1 = 7
    

    1.21-String,StringBuilder,StringBuffer的区别?

    • String是只读字符,值不可以改变的

    • StringBuffer的值是可以改变的,线程安全

    • StringBuilder的值是可以改变的,线程不安全


    1.22-什么是值传递和引用传递?

    • 值传递是对基本类型变量而言的,传递的是该变量的一个副本,改变副本不影响原来变量.

    • 引用传递一般是对于对象型变量而言的,传递的是该对象地址的一个副本, 并不是原对象本身 。

    一般认为,java内的基础类型数据传递都是值传递. java中实例对象的传递是引用传递


    1.23-SimpleDateFormat的作用和用法

    SimpleDateFormat的作用是用于设置时间格式的

    把日期转换为指定格式的字符串

    SimpleDateFormat sdformat = new SimpleDateFormat("yyy y-MM-dd HH:mm:ss");
    String text = sdformat .format(new Date());
    
    //text = 2020 2020-06-14 16:00:54

    把字符串转换为指定格式日期 

    public static void main(String []args) throws ParseException {
           String text = "2020年1月1日 1:11:11";
            SimpleDateFormat sdformat= new SimpleDateFormat("yyyy年M月dd日 H:mm:ss");
            Date date= sdformat.parse(text);
            System.out.println("date = " + date);
    }
    //date = Wed Jan 01 01:11:11 CST 2020
    

    1.24- java 中 IO 流分类

    • 按功能来分:输入流(input)、输出流(output)。

    • 按类型来分:字节流和字符流。

     


    1.25-Java的流


    1.26- Files的常用方法

    • Files.exists():检测文件路径是否存在。

    • Files.createFile():创建文件。

    • Files.createDirectory():创建文件夹。

    • Files.delete():删除一个文件或目录。

    • Files.copy():复制文件。

    • Files.move():移动文件。

    • Files.size():查看文件个数。

    • Files.read():读取文件。

    • Files.write():写入文件。


     

    1.27-如何创建文件和目录?

    File file = new File("D:", "one");
    //创建文件夹
    file .mkdir();          
     //创建文件 
    file .createNewFile();  
     //删除文件
    file .delete();         
    

    1.28-面向对象编程的六大原则

    1、开闭原则(Open Close Principle)

    开闭原则的意思是:对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。简言之,是为了使程序的扩展性好,易于维护和升级。想要达到这样的效果,我们需要使用接口和抽象类。

    2、里氏代换原则(Liskov Substitution Principle)

    里氏代换原则是面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。LSP 是继承复用的基石,只有当派生类可以替换掉基类,且软件单位的功能不受到影响时,基类才能真正被复用,而派生类也能够在基类的基础上增加新的行为。里氏代换原则是对开闭原则的补充。实现开闭原则的关键步骤就是抽象化,而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现抽象化的具体步骤的规范。

    3、依赖倒转原则(Dependence Inversion Principle)

    这个原则是开闭原则的基础,具体内容:针对接口编程,依赖于抽象而不依赖于具体。

    4、接口隔离原则(Interface Segregation Principle)

    这个原则的意思是:使用多个隔离的接口,比使用单个接口要好。它还有另外一个意思是:降低类之间的耦合度。由此可见,其实设计模式就是从大型软件架构出发、便于升级和维护的软件设计思想,它强调降低依赖,降低耦合。

    5、迪米特法则,又称最少知道原则(Demeter Principle)

    最少知道原则是指:一个实体应当尽量少地与其他实体之间发生相互作用,使得系统功能模块相对独立。

    6、单一职责原则(Single responsibility principle)

    单一职责原则是指:一个类应该只有一个发生变化的原因,即一个类只负责一项职责。
    如果一个类有多个职责,这些职责就耦合在了一起。当一个职责发生变化时,可能会影响其它的职责。另外,多个职责耦合在一起会影响复用性。
    此原则的核心是解耦和增强内聚性。


    1.29-设计模式

    ​​​​​单例模式(饱汉模式,饥汉模式)

    • 1)构造方法私有化,让除了自己类能创建外其他地方都不可以创建
    • 2)在自己的类中创建一个单实例(饱汉模式一出来就创建单实例,饥汉模式需要的时候才 创建)
    • 3)提供一个方法获取该实例对象(饥汉模式创建时需要进行方法同步)

    工程模式:spring的IOC就是使用工程模式

    对象的创建交给一个工厂创建

    代理模式:Spring的AOP就是使用的动态代理

    包装模式


    1.30- 运行时异常与一般异常的区别

    异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误。java编译器要求方法必须声明抛出可能发生的非运行时异常,但是并不要求必须声明抛出未被捕获的运行时异常。


    1.31-&和&&的区别

    &是位运算符,表示按位与运算,&&是逻辑运算符,表示逻辑与(and)

     


    1.32-final, finally, finalize的区别。

    • final 用于声明属性,方法和类,分别表示属性不可变,方法不可覆盖,类不可继承。

    • finally是异常处理语句结构的一部分,表示总是执行。

    • finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法,可以覆盖此方法提供垃圾收集时         的其他资源回收,例如关闭文件等。


    1.33-error和exception的区别。

    • error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。

    • exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。


    1.34-Math.round(9.5)等多少? Math.round(-9.5)等多少?

    • Math.round(9.5)     =10
    • Math.round(-9.5)    =-9

    数轴上取值时,中间值(0.5)向右取整,所以正 9.5 是往上取整,负 9.5 是直接舍弃。


    1.35-Java流程控制语句

    break ,continue ,return

    • break 跳出总上一层循环,不再执行循环(结束当前的循环体)
    • continue 跳出本次循环,继续执行下次循环(结束正在执行的循环 进入下一个循环条件)
    • return 程序返回,不再执行下面的代码(结束当前的方法 直接返回)

    1.36-反射

    自己写的反射文章,点击链接跳转:反射-新手必看

    更多内容建议参考,点击链接跳转:反射

    在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法对于任意一个对象,都能够调用它的任意方法和属性这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。


    1.37-反射相关的类

    1. Class类                         类的实体,在运行的Java应用程序中表示类和接口
    2. Field类                          类的成员变量/类的属性
    3. Method类                      类的方法
    4. Constructor类               类的构造方法

    1.38-反射的功能

    在运行时判断任意一个对象所属的类,对象,所具有的成员变量和方法同时可以调用任意一个对象的方法。 


    1.39-反射的优点

    反射提高了程序的灵活性和扩展性,在底层框架中用的比较多,但是还是建议在业务层面的开发过程中尽量少用。


    1.40-反射的缺点

    1. 速度慢
    2. 程序逻辑会更加的复杂,所以维护起来比较累人,建议少用

    1.41-反射的使用场景

    • 拷贝属性值(BeanUtils.copyProperties);
    • 实现ORM框架;
    • 实现RPC框架等;

    1.42-动态代理

    在运行时,创建目标类,可以调用和扩展目标类的方法


    1.43-动态代理的应用场景

    1. Spring AOP
    2. 加权限,事务,日志等操作

    1.44-动态代理实现

    Java的两种动态代理方式:JDK反射机制生成代理还有就是CGLIB代理

    • JDK反射机制生成代理:继承InvocationHandler接口
    • CGLIB代理:继承MethodInterceptor接口

    JDK代理必须要提供接口,而CGLIB则不需要,可以直接代理类


    1.45-序列化和反序列化

    1. 序列化:把对象转换成字节序列的过程就叫做序列化
    2. 反序列化:把字节序列恢复成对象的过程就叫做反序列化

    1.46-序列化使用场景

    1. 把内存的对象状态保存到文件和数据库中的时候需要序列化
    2. 网络传输对象的时候需要序列化

    1.47-怎么实现序列化

    • 简单的实现Serializable接口即可


    1.48-序列化需要付出的代价

    这里给大家贴出链接,由于演示需要比较多的文字,所以给大家推荐一篇写的很不错的文章,还请理解


    1.49-BIO,NIO,AIO 

    1. BIO(Block IO):同步阻塞式 IO,就是我们平常使用的传统 IO,特点是模式简单使用方便,并发处理能力低。

    2. NIO(Non IO):同步非阻塞 IO,是传统 IO 的升级,客户端和服务器端通过 Channel(通道)通讯,实现了多路复用。

    3. AIO(Asynchronous IO):是 NIO 的升级,也叫 NIO2,实现了异步非堵塞 IO ,异步 IO 的操作基于事件和回调机制。


    //持续更新。。。。。。

    展开全文
  • 毕向东Java知识总结

    千次阅读 2017-10-30 10:06:21
    Java基础知识总结(超级经典) 写代码: 1,明确需求。我要做什么? 2,分析思路。我要怎么做?1,2,3。 3,确定步骤。每一个思路部分用到哪些语句,方法,和对象。 4,代码实现。用具体的java语言...
  • Java知识总结索引

    2017-06-22 21:52:44
    1.基础知识2.进阶3.高级编程
  • Java知识总结----队列的使用

    千次阅读 2017-01-08 16:29:13
    Java知识总结----队列的使用  今天跟大家来看看如何在项目中使用队列。首先我们要知道使用队列的目的是什么?一般情况下,如果是一些及时消息的处理,并且处理时间很短的情况下是不需要使用队列的,直接阻塞式...
  • Java知识总结之框架篇

    千次阅读 2019-03-19 15:18:47
    目录 博客链接 ...spring源码深度解析一篇总结 https://www.jianshu.com/p/9ea61d204559 https://www.processon.com/special/template/5c9c2cd1e4b08cb4bb00691f
  • Java知识总结--Mysql篇

    千次阅读 2020-06-15 13:14:24
    最大连接数为100 1.5-对jdbc的理解 Java只定义接口,让数据库厂商自己实现接口,对于开发而言,只需要导入对应厂商开发的实现即可,然后以接口实现即可,然后进行调用(mysql+mysql驱动(实现)+jdbc) 1.6-jdbc...
  • java知识总结(六)包装类

    千次阅读 2016-12-29 15:42:28
    原文出自java包装类,需要转载请注明出处。 一、什么是java的包装类? java是一种面向对象语言,java中的类把方法与数据连接在一起,并构成了自包含式的处理单元.但在java中不能定义基本类型(primitive type),为了...
  • java知识总结(九)多线程

    千次阅读 2017-01-06 15:43:18
    二、java在多线程中的基础知识 1.Java中如果我们自己没有产生线程,那么系统就会给我们产生一个线程(主线程,main方法就在主线程上运行),我们的程序都是由线程来执行的。 2. 进程:执行中的程序...
  • 今天就简单介绍一下如何快速搭建Java开发环境。 1、安装JDK  下载地址:http://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html  安装之后,需要配置环境变量。JAVA_HOME=JAVA_HOME=E:
  • select ... from ... where ... group by ... having ... order by ... limit ...
  • Java知识体系最强总结(2020版)

    万次阅读 多人点赞 2019-12-18 10:09:56
    本人从事Java开发已多年,平时有记录问题解决方案和总结知识点的习惯,整理了一些有关Java知识体系,这不是最终版,会不定期的更新。也算是记录自己在从事编程工作的成长足迹,通过博客可以促进博主与阅读者的共同...
  • 面试总结 有任何问题,或者好的建议,好的面试相关的题目都可以在这里面进行提交! 联系我: tingzai.yang@gmail.com 有什么问题也可以在这里进行讨论 本文会持续更新!欢迎大家收藏。 面试之-排序算法总结 ...
  • ①继承:java多态性的体现。提高软件的可复用性和可维护性。  子类基于父类,子类吸收了父类所有的属性和方法,并有新的方法。 子类先调用父类的构造方法 默认调用无参的构造方法 使用super()调用有参的构造方法...
  • Java知识总结----事件处理机制(九)

    千次阅读 2015-09-12 10:52:37
    在上一篇文章中,跟大家介绍了队列的使用,在基于数据库的队列的是实现中,提到了可以使用事件处理机制类进行...import java.util.concurrent.atomic.AtomicInteger; /** * 消息实体类 */ public class Event {
  • Java知识总结----Spring拦截器(六)

    千次阅读 2015-08-26 14:29:03
    Java中,过滤器是使用Filter实现的,实现原理都是基于回调函数的。最常见的过滤器的应用就是字符编码的过滤、用户信息验证的过滤等。拦截器呢,就是用来拦截的,可以在方法的执行时,添加一些其他的信息,拦截器是...
  • Java知识总结----队列的使用(八)

    万次阅读 2015-09-09 10:58:37
    Java的并发包中已经提供了BlockingQueue的实现,比较常用的有ArrayBlockingQueue和LinkedBlockingQueue,前者是以数组的形式存储,后者是以Node节点的链表形式存储。至于数组和链表的区别这里就不多说了。 ...
  • 2017-2-18  进程和线程 一,进程线程基本概念  进程:一个正在执行的应用程序。 线程:程序中的一个代码流。...关系:一个线程只能属于一个进程,但是一个进程可以有多个线程,但是只有一个主线程。...
  • 很多人特别是Java开发者,都在说MVC,都挺别人说MVC,那么MVC到底是什么,这个又跟SSH、SSM有什么关系呢?  MVC其实是一种设计的架构模式,Model+View+Controller。这个跟我们现在Web开发有很大的关系。Web开发
  • Java知识体系总结(2021版)

    万次阅读 多人点赞 2021-01-09 16:20:53
    但感觉知识还是相当的匮乏,没自信,也许是努力程度还不够吧。很感谢CSDN,因为是它给了我学习的动力,之前写了一篇记录CSDN博客访问量的文章,也许大家感觉很幼稚,但真的很有用,很有效果,仿佛磕了药一样,努力...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 33,027
精华内容 13,210
关键字:

java知识总结

java 订阅