core java

What is java
-----------------------------------------------------------------------------------------------------
java 语法

MODULE 1
===============================================================================================================================================


Java语言的特性:
------------------------------------------------------------------------------------------------------
1.提供了一个解释性的环境 一次编写,到处运行

    1)java ---编译中间语言,byte code字节码 ==.class文件
        类似于汇编语言,不受操作系统和cpu影响

    2)byte code ---机器指令,与特定的操作系统相关
2.对比c/c++的优势:
    1)消除了指针,改用引用来代替指针,保留了指针中好的特性

    2)代码中消除了内存管理,
        c/c++:中开发人员需要自己申请和释放内存
        java:自动内存管理机制    所有的对象都是用new操作符建立在内存堆区
    
    

    

JVM --- 解释性的环境
------------------------------------------------------------------------------------------------------

源程序从开发到最终运行经历的两个步骤:
    1.编译---做简单的语法检查
        命令:javac ***.java
        功能:.java --> .class(字节码)
        .class文件可以跨平台
    2.运行
        命令:java ***
        1)class loader --- 类加载器
            将字节码文件加载到内存中
        2)byte code cerifier --- 字节码校验器
            验证字节码是否合法
        3) 执行:
            解释器 --- 将字节码逐行翻译成机器指令
                每次都要逐行翻译并运行,效率低
            JIT(Just intime technology) -- 即时翻译技术
                找出20%的热点代码,一次编译成机器指令

GC(Gabage Collection) --- 垃圾回收机制,提供了自动的内存管理
    目的:开发人员无需关注内存释放

    1)GC始终运行在后台的 优先级最低的 系统级线程 
        大部分时间不工作,只有系统闲置或内存不够时工作        
    2)开发人员可以在代码中,建议JVM进行回收,但是是否执行由JVM决定(suggest,not force)
        System.gc(); 或 Runtime.gc();

-----------------------------------------------------------
path:执行命令的目录
classpath:程序员写的类库
-----------------------------------------------------------


类加载器
------------------------------------------------------------------------------------------------------
1.启动类加载器
    bootstrap class loader
    加载jdk核心类库$JDK\jre\lib\rt.jar
2.扩展类加载器(第三方)
    extensible class loader
    加载扩展API:$JDK/jre/lib/ext/*.jar
3.系统类加载器
    system class loader
    加载自定义的类:$CLASSPATH


双亲委托机制

1)可以避免同名的类重复加载,当上一级已经加载到该类时,不会再向下加载
2)考虑到安全性,否则自定义的类可动态替代java核心API

打jar包命令:
    jar -cvf hello.jar 
解压包命令:
    jar -xvf hello.jar


字节码校验器
-----------------------------------------------------------------------------------------------------
    检验代码中非法的或破坏性的操作
1)验证版本是否兼容
2)验证代码不会破坏系统的一致性
    确保所有操作指令不会对操作系统进行非法的操作
3)不会在内存中发生栈下溢和栈上溢
4)方法调用时的参数类型合法,不能超过其合理的数据范围
5)数据类型转换是否正确


第一个java程序:Hello.java
--------------------------------------------------------------------------------------------------------
编译:当前目录ch01
    javac -d bin src\Hello.java
    -d:指定编译后的字节码文件的存放路径

运行:java -cp bin com.briup.ch01.Hello
    -cp:指定字节码文件的搜索路径

构建java源程序的三要素:
     package  import  class 顺序不能错

1.package 包(可省略)
    语法:package com.briup.ch01; //用分隔
        命名:小写
        package不是目录,但编译后以目录形式存在运行时需要完整的类名:包名.类名

2.import 导入(可省略)
    两种情况无需import
    1)java.lang包中的类
    2)同一个package中的类
3.class定义类
    语法: class 类名 {...}
    命名:类名首字母大写
    
    知识点:
    1)一个java源文件中可以定义多个class,但是只能有一个public类
    2)源文件名称一定要和public类的类名一致
    3)运行的程序必须要有main方法,该方法是程序的唯一的执行入口,只能有一个main方法。
        main方法的定义:public static void main(String[] agrs){....}

jdk中常用的包
------------------------------------------------------------------------------------------------------------
1.java.lang -- 最常用的类,不需要import
2.java.awt/javax.swing/java.awt.event
    --开发图形用户界面
3.java.io -- 输入/输出流
4.java.net -- 网络
5.java.util -- 常用的工具类


Module 2 标识符 关键字 数据类型
===============================================================================================================================================

1.Comments注释
-------------------------------------------------------------------------------
    ---增强程序的可读性
    三种注释:
        1)单行注释://紧挨着要注释的代码
        2)多行注释:/*
                  ...
                 */
        3)javadoc注释:可以生成javadoc文档,
                /**
                ...
                */
            可以写html标签,生成的是html格式的网页
            @author 作者
            @version 版本
            @since 从哪一个版本的jdk开始应用
            @param 参数
            @return 返回类型
            @throws ---@exception 异常
         命令:javadoc -d doc src\*.java 

2.标识符--表意性强
---------------------------------------------------------------------------------------------------
              在程序中给类,方法或变量命名
1)以 字母,“_”,“$”开始

2)后跟字母,"_",“$”,或数字
3)大小写敏感
4)没有长度限制
    类名---首字母大写,后续单词首字母大写
    方法名/变量名---首字母小写,后续单词首字母大写
    常量---都是大写
5)回避java中的关键字
    
    java中的关键字:
    1)goto/const---非关键字,属于保留字,需要回避
    2)true false null --- 具有特殊含义,回避
    
    注:java程序中的数据一定存在类型

3.java中的数据类型
--------------------------------------------------------------------------------------------------
1.基本数据类型--四类八种
    整形:byte  short  int  long
    浮点型:float  double
    布尔型:boolean
    字符型:char

    boolean: true/false 不能用0或非0
    
    char:无符号的16位整型数
        1)单引号表示:char c='A';
        2)用整型表示: char c = 96;
        3)unicoded表示:char c ='\u0060';

    整型:三种表示法

        1)十进制:默认是十进制int型 123
        
        2)八进制:前面加0   0123
        
        3)十六进制:前面加0x 0x123
    
    浮点型:3.1415926
        默认为double类型

    数据类型的转换规则:
    1.隐式转换  窄 -->宽
        byte,short,char -->int-->long-->float-->double

    2显示转换    宽-->窄
        强制转换:(目标类型)变量
            存在精度丢失问题,由开发人员自己负责
    


    java中内存分区:
        1)堆区
            new操作符创建的对象都存在堆区
            特点:所有程序公用,空间不连续,容量大,速度慢
            存放对象和成员变量等
        2)栈区
            特点:存储空间连续,容量小,速度快
            存放局部变量,引用型变量(声明的对象)和基本数据类型变量等
        3)代码区
            存放代码块,方法体等
        4)静态/常量区
            存放静态变量,常量等
    
2.引用类型(类类型)
    Teacher zhao; //声明 栈区
    zhao = new Teacher(...);//堆区创建一个Teacher对象

    引用型变量:Person p;在栈区开辟空间
        注:引用型变量指向一个具体的对象

自动封装包装
----------------------------------------------------
jdk<=1.4中:
Integer i1 = 123    //illegal
Integer i2 = new Integer(123);

jdk>=5.0中:
Integer i3 = 128;
Integer i4 = 128;
System.out.println("i3==i4:"+(i3==i4));  //i3==i4:false
Integer i7 =127;
Integer i8 =127;
System.out.println("i7==i8:"+(i7==i8));  //i7==i8:true
int i5 = 128;   
int i6 = 128;
System.out.println("i5==i6:"+(i5==i6));  //i5==i6:true
Ingeger类型的数据,当值小于128时,不会维护缓存  ;即Ingeger类型的数据<=127时,共用同一个常量区。另:

/*
 * Float Double :不维护缓存
 * Byte Boolean :全部维护缓存
 * Character Integer Short Long:维护一个字节的缓存   -128~127
*/
------------------------------------------------------


类-class
---------------------------------------------------------------------------------
生活中:
    同种类型的一个群体,具有 共同特征 和 共同的行为
程序中:
    群体--(抽象)-->class
        共同特征--(抽象)-->成员变量(属性)
        共同行为--(抽象)-->方法


    定义:public class Person{
        //Person具有的共同属性,成员变量
        String name;
        int age;
        boolean gender;
        //Person具有的共同的行为
        public void ear(){....}        
        public void shout(){...}
    }


对象 -- object
-----------------------------------------------------------------------------------
生活中:
    群体中一个独立的个体,具有特定的属性取值和行为
程序中:
    new + 类名(param1,param2,...);
    类的一个实例化对象
    
    class PersonTest{//测试程序
        public static void main(String[] args){
            Person person ;//变量声明
            person = new Person();//创建Person
            person.name = "fenghb";
            person.age=22;
            person.eat();
        }
    }


构造器:
---------------------------------------------------------------------------------------
    构造器是对成员变量进行初始化,不属于类的行为
    构造器允许定义多个,参数类型或个数不同
    类中没有显示定义构造器时,java会默认分配一个无参的构造器
    类中由于显示定义了构造器,java不会在分配无参的构造器

类中的语法成分:
---------------------------------------------------------------------------------------
1)成员变量
2)构造器
3)普通方法

作业:构建一个矩形类Rectangle.java
    成员变量:长  宽  
    行为:求周长 求面积
    写测试程序

命令:(RectangleTest中调用了Rectangle类,-cp bin 需要制定Rectangle类的字节码的搜索路径)
    javac -d bin -cp bin src\RectabgleTest.java


Module 3  
================================================================================================================================================
1)成员变量(实例变量)和局部变量
2)操作符
3)流程控制语句


1.局部变量
    1)定义在方法内部
    2)没有默认的初始化值,使用前必须赋值
    3)只作用方法内部
2.成员变量
    1)定义在类的内部,方法的外部
    2)具有默认的初始化值:
        a)基本数据类型
            整型:0
            浮点型:0.0
            char型:'\u0000'
            boolean型:false    
        b)引用类型
            默认null        


Operators操作符
---------------------------------------------------------------------------------------------------
1.算数运算符
    +  -  *  /
    两边的类型要一致,否则小类型自动转换为大类型,结果类型也为大类型
    5/3 = 1

2.赋值操作符
    =
    复合赋值操作符:
        int i=5; i+=3 ==>i=i+3;
    i++;==>先使用i,然后再自增
    ++i;==>先自增,在用新的i进行运算
3.比较操作符
    结果是boolean类型

4.移位操作符
    针对的是二进制串进行移位操作

    >> --- 右移,高位按符号位   
    << --- 左移   
    >>> --- 无符号的右移,高位填0
    i=3; 0000...0011(32位) 
    i>>2;0000...0000 ==> 0
    i<<2;0000...1100 ==> 12

    i=-3; 1111...1101
    i>>2; 1111...1111 ==>-1
    i>>>2;0011...1111 
5.位操作符
    针对二进制数进行操作
    
    int i =3,j=5;
        i: 0000...0011
        j: 0000...0101
    
    1)位与&: 0000...0001 ==> 1
    2)位或|: 0000...0111 ==> 7
    3)异或^: 0000...0110 ==> 6
        相同为0  不同位1
    4)取反~:  针对一个二进制数操作,每位取反

    
6.逻辑操作符
    参与运算的都是boolean型数据,结果也是boolean

    逻辑与&&:
        A&&B : A和B都为true时,结果为true,否则false
        短路规则:当A为false时,B不参与运算

    逻辑或||:
        A||B:A或B中有一个味true,结果true
        短路规则:当A为true时,B不参与运算

7.条件运算符:
    A?B:C
    A---boolean型结果
        当A为true时,整个表达式结果为B,否则为C
        num1>num2?num1:num2;
    注:冒号两边类型要一致,否则小类型自动转换为大类型


    int a=2,b=5;double c =3.14;(a>b)?(int)c:b==>5.0        
    


流程控制语句
----------------------------------------------------------------------------------------
1.if/else

2.switch/case
    1)temp取值:byte short char int (jdk1.5枚举类型)
    2)case 是程序的分支入口,一旦进入会顺序执行下去
    3)case的出口:break;
    4)default可任意放置,习惯放最后

3.循环控制语句:
    代码反复执行多次
    1)for循环
        for(A;B;C){code block;}
        执行A(只执行一次)
            -->B(条件判断)--->false,跳出for循环
                    --->true --- >code block ---> C-->B 
    2)while循环
        
        先判定boolean表达式结果,结果为true进入循环体
    
    3)do/while循环
        循环代码体至少执行一次,在判断表达式    

附加作业:
    实现功能:计算出下一天的年月日addDay();

Module4  数组Array
================================================================================================================================================

数组Array
------------------------------------------------------------------------------------------------
    也是一种数据结构,用来存储【指定长度】的【相同类型数据】的【集合】

    1)数组声明时必须指定数组中元素;
    2)指定长度且不能再更改
    3)属于引用类型,使用前必须用new创建,length可看做数组对象的属性


声明
    基本数据类型
        int[] array;或 int array[]
    引用类型
        Student[] arrays;或 Student arrays[];
创建
    用new操作符创建数组

    基本数据类型:
        int[] array = new int[7];
    引用类型:
        Student[] arrays = new Student[7];
    
    注:创建数组只是指定元素的最大个数,开辟空间,但是数组中的元素需要单独创建

初始化
    默认初始化

        数值型 :0  
        boolean: false 
        引用型:null

    动态初始化
        1)声明,创建,初始化独立分开
            int[] array;//声明
            array = new int[2];//创建
            array[0] = 0;//初始化
            array[1] = 1;
        2)同时声明,创建,初始化
            int[] array = {1,2,3,4};
                
                错误:int[] array; array={2,3};
            
            int[] array = new int[]{1,2,3,4};
                不可以再[]里面指定数
                
                错误:int[] array = new int[4]{1,2,3,4};

            引用类型:
            Student[] ss = new Student[]{
                new Student("fenghb"),
                new Student("lisi")
            };
            Student[] students ={new Student("fenghb"),new Student("lisi")};
                
数组元素的访问
    数组名[元素下标]
    元素下标:0~length-1;


数组的遍历
    for(int i =0;i<array.length;i++){
        array[i];
    }

多维数组
---------------------------------------------------------------------------------------------------------
1)java中的数组都是一维数组,多维数组就是存放数组的数组
2)最多可以定义255维度

一维数组反应的是线性关系,在内存中也是一段地址连续的线性内存空间


二维数组
---------------------------------------------------------------------------------------------------------
1.对称数组(矩阵)
    int[][] array = new int[2][3]    

    注意:第一个维度代表数组array的长度。一定要在创建该数组时指定

2.非对称数组(锯齿形)
    每个元素都是一个一维数组,需要单独创建
    int[][] array = new int[3][];
    
    array相当于一个一维数组    
    array[0] = new int[2];
    array[1] = new int[5];
    array[2] = new int[3];

    array.length = 3;//二维数组的长度由第一维度决定
    
3.二维数组的遍历
    
    int[][] array = new int[3][5];
    for(int i=0;i<array.length;i++){

        for(int j=0;j<array[i].length;j++){

            array[i][j] = i*j;
        }
    }


数组拷贝
-------------------------------------------------------------------------------------------------
System.arraycopy(from,fromIndex,to,toIndex,count)
    from --- 源数组
    fromIndex -- 源数组的索引位置
    to -- 目标数组
    toIndex -- 目标数组的索引位置
    count -- 要拷贝的元素个数


注:只是浅层拷贝,当元素为引用类型时,复制出来的对象不能
独立于原对象,当原来的对象属性值改变时,目标数组中的元素也相应的改变

类中的set方法作用是供用户更新数据l


重写toString()方法打印所需要的内容字符
对象可以自动调用toString方法

不重写会输出对象在堆区的内存地址

Module 5 OOP--Object Oritention Programming
==================================================================================================================================================
面向对象编程的三大特性:

class类:具有相同属性和行为的一组对象的集合
    
    人:---(抽象)-->class Student{}
        静态属性:-->成员变量
        
            姓名 性别 年龄
        
        动态行为:-->方法
        
            学习 吃饭 考试

Object对象:

    Student s = new Student("feng",20);
    s.study(); zx.exam();
    s = new Student("feng",20);
    
    
Encapsulation--封装
--------------------------------------------------------------------------------------------------------------------------------------
    目的:实现信息隐藏
        1)静态属性的信息隐藏
        2)方法的实现细节的隐藏


Inheritance--继承
-----------------------------------------------------------------------------------------------------------------------------------------
    1)对象间具有一定的相似性
        a)子类具有父类的属性和行为
        b)子类可以具有自己特有的属性和行为
        class Point{
            int x;
            int y;
        }    
        class Circle{
            int x;
            int y;
            int ridius;
        }
        Circle 继承 Point
    2)父子类之间一定要满足“is a ”的语义关系    

        子类 is a 父类
    
        Circle is a Point? //错误的继承关系
    
    注:父类 代表一个大群体,子类 是大群体中的一个小群体    
    


语法:
    class Teacher extends Person{}

1.一定要满足“is a”的语义关系

2.单继承,子类只能有一个父亲

3.子类继承父类的那些语法成分?
    
    1)成员变量
    2)普通方法
        子类继承父类的(除私有)方法
        直接调用
    3)构造器?
        构造器不能被继承,但是子类一定会调用父类的构造器

        a)隐式调用
            子类构造器中没有显示调用父类的构造器时,JVM会默认调用父类的无参构造器
            相当于子类构造器中执行了super();

        b)显示调用
            super(param1,param2);
            一定要放在构造器中的第一个语句
            
        注:父类的构造函数中用到的方法和子类的中的方法一样时,只调用子类的方法

super的用法
--------------------------------------------
1.在子类中要调用父类的同名方法,用super.method();

2.在子类构造器中调用父类的构造器super(...);


Polymorphism--多态
------------------------------------------------------------------------------------------------------------------------------------
    对于不同的对象,相同的行为产生不同的结果
    例:
        BasketBall    FootBall  继承   Ball
        play()        play()           play()
        用手玩        用脚踢
    1)对象只有一种类型 new Teacher()
    2)变量可以有多种形态
        Person  p;
        p = new Teacher();
        p = new Student();
        p.display()

        

多态存在的三个必要条件:
---------------------------------------
1)要有父子类的【继承】关系

2)要有子类重写父类的同名方法;Overriding

3)父类的引用指向子类的对象(上转型)


练习:
    创建 Cat   Bird   继承Animal
       eat()   eat()   eat()
      catch()  fly()
    创建测试程序AnimalTest

Overriding重写(覆盖)
---------------------------------------
1)在父子类之间,区别于Overloading

2)定义了同名的方法,参数列表,返回类型都相同

3)可见范围不能被子类缩小 (包括static修饰符)

4)异常不能被放大(不能一个有异常一个没有异常)
    

 重写是运行时多态


方法的重载Overloading
-------------------------------------------------------------
1)在一个类的内部
2)定义多个同名的方法
3)参数的类型或个数不同
4)返回类型不做要求
    外部用户无需关注编译器调用的是哪个方法,有JVM自己判断使用的方法
 
    重载是编译时多态


instanceof操作符
----------------------------------------
1)boolean型
    用法:引用型变量  instanceof 类名
    判断前面的引用变量的动态类型是否是后面的类自身或者是其子类,是返回true,否则返回false
    Person p = new Teacher()
    p instanceof Person? true
    p instanceof Teacher? true
    p instanceof Student? false


---------------------------------------        
1.操作名称的多态

    重载是多态的一种

    在一个类的内部有多个操作具有相同的名,参数的类型和个数不同的方法

2.和继承有关的多态

    子类重写父类的方法

    方法的参数类型和返回类型都一致
    同一个方法被不同对象调用时产生的结果不同

方法的定义和调用
-----------------------------------------------------------------------------------------------------------------------
方法定义:
    1)修饰符:允许存在多个,无顺序要求
        public static ==== static public 
    2)返回类型
        方法一定存在返回类型,没有返回值用void
        存在返回类型的方法,要求方法中的任一分支都有返回值 (return) 

        int method(){
            if(){
                return 0;
            }else{
                return 1;
            }
        }
    3)参数列表:更具需求,可有可无

        用于接收外部传入的数据
        一定要指定参数的数据类型
        参数的作用域范围仅限方法内部
        int add(int a,int b){}

方法的调用:
    1)同一个类中调用

    2)在外部类中调用
        class A{
            int methodA(){}
        }        
        classbB{
            int methodB(){
            //创建A的实例化对象
                A a = new A();
                a.methodA();
            }
        }

注意:方法定义时,参数没有明确的取值
      方法调用时,给参数传值

    形参:方法定义时的参数
    实参:方法调用时给形参传值


***
1)基本数据类型
    传值:实参的值拷贝一份传递给形参

2)引用类型
    传递的是引用的地址
***


this关键字
------------------------------------------------------------
1)    当成员变量名和局部变量名相同时,用this区分
    this指向的是当前类或对象
    this.name ---> 成员变量name
    name --> 局部变量

2)在一个构造器中要调用另一个构造器时,用this(...)
    构造器中的this()语句必须放在第一行


创建对象
-------------------------------------------------------------
    new Person("feng",22)

1)在内存堆区开辟空间

2)为成员变量进行默认初始化0,false,null

3)显示初始化
    缺乏灵活性,类的所有对象都具有相同的属性值
    class Person{
        private String name = "unknown";
        private int age =18;
    }
4)构造器
    可以为不同的对象赋予不同的初始化值
    设计目的:只对属性进行简单的初始化,不涉及复杂的业务代码

    1)一个类中一定存在构造器,没有显示定义时,JVM会自动分配默认的无参构造器
    2)显示定义了构造器的类,JVM不在分配无参构造器
    3)允许定义多个,构造器重载,提供多种初始化方案
        如何简化构造器中的代码??  this();
            

Module 6  高级语言特性
====================================================================================================================================
1.static/final修饰符
2.==和equals()比较
3.访问权限控制
4.抽象类和接口(*)
5.内部内
6.集合(*)
7.反射(*)


static修饰符 -- 特点:类的所有对象共享
-----------------------------------------------------------------------
1.修饰成员变量(非局部变量)
    class A{
        int a; 
        static int b;
    }
    类的普通成员变量是和对象关联
    A a = new A(); a.a
    
    A b = new A(); a和b都共享静态变量b 

    静态变量可以直接用类名直接调用

    静态变量赋值:
        1)在类中可以直接赋值也可以再static语句块中赋值
        2)在类的构造器中用参数赋值
    
2.修饰方法---静态方法


    1)只能访问静态的语法成分(静态变量/静态方法)

    2)访问非静态的语法成分,一定先创建该类的对象
    
        静态的方法可以用类名直接调用

    3)不能被子类重写为非静态的方法

    
    对于工具类和工具方法,通常定义为static

3.修饰代码块 -- 静态初始化代码块

    1)静态代码块只能被执行一次,在  类加载  时一次性执行

    2)允许定义多个静态代码块,编译器会合并执行

    3)优先于main()和构造器
        
    用法:
        通常用于对静态变量进行一次性的初始化
    

final修饰符
---------------------------------------------------------------------------------------
特点:不可更改性

1.修饰变量 -- 常量
    一经赋值,不能更改

2.修饰方法
    该方法在子类中只能被继承,不能被重写

3.修饰类
    不能被继承 String
    
    常见用法:
        static final ---  静态常量
    例题:
        Employee中添加基本工资 -- static
        1)永远不会更改基本工资  static final
        2)允许调整 static
    
        

==和equals()比较
-------------------------------------------------------
1.“==”比较
    1)基本数据类型   比值
    2)引用类型
        Person p = new Person("zhangsan",25);
        Person p1 = new Person("zhangsan" 25);

        p==p1? false
        ==比较地址,比的是对象在内存中存放的地址    
        p = p1;
        p==p1; true
    


2.boolean equals()----适用于引用类型
    Object 祖先类
    java中的所有类默认继承Object类
    equals(Object o)
        ----比较两个对象的类型和内容是否相同
            比较类类型的时候必须重写equals()方法
    
    1)java提供的类的比较
        jdk对这些类已经重写了equals(),可以直接比较
    2)自己开发的类的比较
        需要重写equals()方法
        1)先比两个对像的动态类型 instanceof
        2)比两个对象的各个属性取值是否相同
    
    总结:只有类型和属性值都相同,才认为两个对象相同
    
    注
    String m = "abc"
    String n = "abc"
    String在内存中搜索的是同一地址
    new String("abc") 是在堆区开辟新的存储空间
    m==n? true

Access Control 访问权限
------------------------------------------------------------------------------------
    class Student{
        private Sting name;
        int id;
        protect int age;
        public String sex;
        
    }
private:

    另外一个类中创建Student对象时不能访问private变量和方法
friend:

    任何与Student同一包中的类创建的对象,都可以访问friend变量和方法
    如果不是在同一包中类创建的对象就 不能访问 friend变量和方法
protected:

    任何与Student同一包中的类创建的对象,都可以访问protected变量和方法
    如果不是在同一包中类创建的对象就 不能访问 protected变量和方法
public:

    任何 一个类中创建Student对象时都能访问public的变量和方法

继承的访问

1.子类和父类在同一包中的继承
    子类继承了父类不是private的所有变量和方法(除构造方法)

2.子类和父类不在同一包中的继承
    子类只继承了父类的protected和public的变量和方法(除构造方法)
    不继承friend和private变量和方法

抽象类和抽象方法
--------------------------------------------------------------------------------------
关键字:abstract

1.抽象类
    语法:public abstract class A{}
    思想:
        现实对象 -- (抽象) --->具体类 Cat Dog
        具体类 --- (抽象)--->抽象类 Animal
    特点:
        1)不能实例化对象(不能用new操作符)
               Animal a = new Animal();//非法
           Animal a ;//变量声明  合法
           a = new Cat();// 合法

    设计目的:用抽象父类的引用型变量操作具体的子类对象
        2)满足“is a”的关系
            Cat is a Animal
        3)单继承
    问:抽象类中能否存在构造器?
    答:存在,给子类调用

    抽象类可以实现(implements)接口,抽象类是否可继承实体类,但前提是实体类必须有明确的构造函数。

2.抽象方法
    语法:abstract void play();不能用private修饰
    特点:
        1)只有方法的声明,不提供实现
    设计目的:
        定义了一种规范,规定了所有  子类  具有的共同行为
        2)子类必须对这些抽象方法提供实现
    知识点:
        1)有抽象方法的类必须是抽象类;
        2)抽象类中可以包含0~多个抽象方法;
        3)具体类  继承  抽象类? 
        4)abstract 和 final 同时修饰类?不能
            abstract --> 用来继承
            final -->  不能被继承

    abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized?
    答案:都不能

接口 interface
---------------------------------------------------------------------------------------------------        
    定义接口:interface A{}
    特点:
        1)间接满足多继承
        2)不能实例化   new A();//非法
    语法成分:    
        1)成员变量
            都是static final静态常量
        2)方法
            都是抽象的
        
         interface A{
            int i = 10;  //static final int i = 10;
            public void method(){}  //非法
            public void method();   //abstract
         }
        
        

    设计目的:
        定义了一种规范,定义了该接口的所有  实现类  所具有的共同行为,接口是对行为的抽象
        
    例:
         Cat     Dog    Bird    Plane
        eat()   eat()   eat()    fly()
                fly()     
        设计:Animal  抽象类   eat()
            abstract class Animal{
                public abstract void eat();
            }
            public class Cat extends Animal{
                public void eat(){}
            }

            public interface IFlyable{
                public void fly();
            }
            public class Bird extends Animal implements IFlyable{
                public void eat(){}
                public void fly(){}                
            }

        知识点:
            1)类可以实现多个接口
                class A implements B,C{}
            2)接口之间的关系
                接口可以继承多个接口
                A extends B,C{}
                A,B,C:接口

        问:1)接口可以继承类?  不可以   抽象到具体 合法    具体不能到抽象
    
            2)接口中是否存在构造器?  不存在

         特殊的接口:
            1)常量接口(全是常量)   不推荐使用
            2)标识接口(接口里没有任何方法和常量)   序列化接口   
        
        3)构造器
            没有构造器

    练习:
        Door        PanpanDoor   
        open()       
        close()

面试题

抽象类和接口的区别
---------------------------------------------------------------------------------
1.共同点
    1)不能创建实例化对象
    2)包含未实现的方法的声明(抽象方法)
    3)子类或实现类必须提供这些方法的实现

2.不同点
    
语法:

         抽象类                                       接口
关键字        abstract                interface
        
变量        成员变量/static/final            只有static final
        
方法        抽象方法/普通方法            只有抽象方法
        
构造器        存在,可自定义                不存在
        

编程思想:

        抽象类                    接口

        is a
        具体类--(抽象)-->抽象类        行为 ---(抽象)--->接口

练习:
    实现List链表,根据索引号存取数据,元素有顺序
        操作:增删改查
        实现:用数组的形式实现
            


考虑:

内部类 Inner Class
-------------------------------------------------------------------------------------------------
    把一个类定义在另一个类的内部
class A{
    int i;
    class B{
        int j=10;
        void method(){...}
    }
    
}

B就是A的内部类

设计目的:精确控制类的使用范围
作用:
    1)减少命名冲突,可以再不同的类中定义同名的类
        class A{class C}   class B{class C}
    2)缩小类的使用范围,使其比包还小,可以在一个类的内部或者方法内部甚至表达式内部使用
    3)内部类可以共享外部类的语法成分
例:
    class 发动机{
        void produce(){
            //生产发动机
        }
    }
    class 汽车装配厂{
        void 装配(){
            new 发动机();
            new 轮胎();
        }
    }

    1)改造一:汽车发动机只能在汽车装配厂中运用
        
    class 汽车装配厂{
        class 汽车发动机{   //成员内部类
            void produce(){
            //生产发动机
            }
        }
        void 装配(){
            new 发动机();
            new 轮胎();
        }
    }

    2)改造二:进一步缩小使范围,汽车发动机只能装配方法中使用到
    
    class 汽车装配厂{
        
        void 装配(){
            class 发动机{    // 局部内部类
                void produce(){
                    //生产发动机
                }
            }
            new 发动机();
            new 轮胎();
        }
    }

    3) 改造三:如何避免对此创建内部类对象?匿名内部类
    无名可调
    


四种内部类
--------------------------------------------------------------------------------
1.静态内部类
    定义在类的内部,参考静态成员变量
         1)不依赖于外部类对象,可以独立构建
        2)只能访问外部类的静态语法成分
    class Outer{
        int i = 10'
        static int j = 20;
        static void method(){
            Inner inn = new Inner();

        }
        static class Inner{ //静态内部类
            void method(){
                i++;//非法
                j++;//合法
                Outer.method();// 访问外部类的同名方法
            }
        }
        
    }
应用:
    1)在外部类  内部  如何创建内部类对象
        Inner inn = new Inner();
    2)在外部类  外部  如何创建内部类对象
        Outer.Inner inn = new Outer.Inner();
        
        Outer o = new Outer();//只创建了外部类对象
        
练习:
    一个数组中存放了一系列整数,要求一次性从该数组中同时获取最大值和最小值
分析:
    getMaxMin()一个方法同时返回两个值?


2.成员内部类    
    参考成员变量或普通方法
    定义在类的内部,没有static
    1)成员内部类对象必须紧密依赖于外部类对象
    2)可以访问外部类的所有语法成分,包括私有
        class Outer{
            private int i;
            class Inner{
                void method(){
                    i++;
                    Outer.method();//非法 如果method()在外部类中是static可以用Outer.method()调用外部类的方法method()方法
                    Outer.this.method();//访问外部类同名方法
                }
                
            }
            public void method(){}
            public void method1(){
                Inner inn = new Inner();
                inn.method();//
            }
            
        }
应用:
    1)在外部类内部
        Inner inn = new Inner();
    2)在外部类外部
        1)声明
            Outer.Inner inn;
        2)创建
            inn = new Outer.Inner();//非法
             
            inn = (new Outer()).new Inner();//合法 
    

3.局部内部类
    参考局部变量
    定义在方法内部
        1)能访问外部类的所有语法成分

        2)只能访问局部常量,final修饰

        3)不能加public/protected/private修饰符;无意义
        4)局部内部类作用域范围仅限方法内部
        class Outer{
            int i = 10;
            void method(){
                int j = 20;
                final int a = 2;
                class Inner{
                    i++;//非法
                    void method1(){
                        i++;
                        a;
                        j++;//非法
                    }
                }
                Inner inn = new Inner();//合法
            }

        }

问:如何避免多次创建局部内部类对象?

4.匿名内部类
    定义在方法内部
    1)只允许在方法内一次性运用,类的定义和运用同步
    2)通常会继承一个父类或实现一个接口
    3)无类名,无构造器,无class/extends/implements
        借用的是父类或接口名称
        new 接口(){...};


注:匿名内部内运用最广泛,GUI事件监听中

class 汽车装配厂{
        
        void 装配(){
            //new 汽车发动机();
            new 发动机();//非法,接口不能实例化

            new 发动机(){
                void produce(){
                    //生产汽车发动机
                }
            };
            new 轮胎();
            ...
        }
    }

Collection集合框架
--------------------------------------------------------------------------------------
对数据结构的实现,半成品对象,在此基础之上进行二次开发

要求:
    1) 理解常用数据结构的特点
    2)会查询API,包java.util
    3)能够对数据结构进行增删改查操作

注: 存储的都是对象    


接口
    
1.Collection接口 --- 存储没有依赖关系的一组对象

    List接口--- 数据按照顺序存放,以索引号方式存取,
            允许对象重复,允许为null

    Set接口 --- 对象无顺序,不允许重复
        
        SortedSet---允许排序的Set
            
2.Map接口---以键值对的形式管理一组成对的对象
        key~value key唯一不重复
        选择Map,需要找出唯一不重复的标识

    SortedMap---具有排序功能的Map,根据key排序

实现类:
    List实现类
        ArrayList --- 采用数组实现,增删低效,查询高效
        LinkedList --- 双向链表,增删高效,查询低效
        Vector --- 线程安全的ArrayList
    
    Set实现类
        HashSet --- 无序不重复
    SortedSet实现类
        TreeSet -- 具有排序功能

    
练习:
1.List的应用
    自定义一个类Account,
    属性: int code;
        String name;
        double balance;
    方法:toString()输出账户信息

2.Set的应用
    Set set = new HashSet();
    Account中重写equals()方法
    Set中不能重复过滤的Account

    Set存储数据的方式:
    数据按照hashtable的散列算法进行存放    

    Set中比较两个对象是否相同,需要重写两个方法:
    1)hashcode()
    2)equals()

3.SortedSet的应用
    具体排序功能的Set
    
    思考:对象如何排序?
    对象存在多个属性,根据哪个属性进行排序,需要开发人员制定
    
    SoctedSet set = new TreeSet();

练习:
    1)创建比较器CodeComparator,实现Comparator接口,提供对账户的账号进行正序排列
    2)创建比较器BalanceComparator。提供对账户余额


Map实现类
------------------------------------------
1)HashTable
    线程安全的,类似Vector和ArrayList

2)HashMap
    线程不安全


HashMap和Hashtable区别
主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。


SortedMap实现类
    TreeMap -- 具有排序功能的Map


key ---Object,也是对象,唯一不重复

value -- Object,允许重复

put(key,value)

Set entrySet()    
    --拿到所有key~value的对应关系,返回Set,其中的每个元素都是Map.Entry类型的对象,代表一个键值对,可以通过Map.Entry获取key和value值
Set keySet()   
    --获取Map中所有key的值,key值不重复,返回Set
Collection values()
    --获取Map中所有的value值,允许重复,无序


Re
collection values()flection 反射机制
--------------------------------------------------------------------------------------------
核心机制:
    
允许程序在  【运行时】  获取以知名字的class类的相关信息,动态构建该类的对象,获取类中的所有语法成分(成员变量,构造器,方法),可
    以动态修改属性取值,或调用其方法

类中语法成分:
--------------------------------
package/import
class 类名{ --->class的镜像
    
    属性:修饰符 类型 标识符 --->属性镜像
    方法:修饰符  返回类型 标识符 参数列表-->方法镜像
    构造器:修饰符 参数列表    -->构造器的镜像
}

反射常用的类:
--------------------------------
java.lang.class --- 类的镜像
java.lang.reflect.Field --- 属性的镜像
java.lang.reflect.Method --- 方法的镜像
java.lang.reflect.Constructor --- 构造器的镜像


    
    看透class的能力 --- introspection

    
    A a = new A();

    method(String classname){

        //1.拿到类的镜像
        Class c = Class.forName("java.lang.String");
        //2.
        
    }


获取类的镜像的方法:
1)知道类名,根据类名得到镜像
    方法:类名.class
    例:Class c = String.class;
        Class i = int.class;
2)知道引用型变量
    方法:变量名.getClass();
    例:String str = "abc";
        Class c = str.getClass();
3)知道字符串给定的类名
    方法:Class.forName(String classname);
    例:Class c = Class.forName("java.lang.String");

getMethods()
getFields()
    返回的是公共的属性和方法,包括继承的
getDeclareMethods()
getDeclareFields()
    返回的是所有的属性和方法(public/protected/default/private),不包括继承的

反射的用处
1)通过类的镜像获取类的信息
2)程序运行时动态创建类的对象
3)破坏封装,可以获得类的私有属性和方法


newInstance()----调用的是共有的无参的

Module7 Exception异常
============================================================================================================================================
    程序执行过程中可能出现的意外情况,不能期望外部用户应用始终正确,应该在程序中进行相关处理,确保在错误发生时,程序采取理智行为,不会意外终止
1)数组访问越界异常;
2)除以0;

异常都是类

异常发生,改变程序原有的正常流程
    --> 抛出某个特定类型的异常
        -->捕获异常,采取相应的处理


getMessage()---返回异常的简单描述信息
printStackTrace()---打印出异常完整的传播路径

异常的传播:
    异常在它发生的位置开始会一级级向上传播,在整个传播路径的任意有一个位置都可以捕获处理,一旦被处理,它的上层调用者不在受影响

异常的体系结构
------------------------------------
1.Error
    ---不是程序本身的错误,由外部因素引发,程序无法恢复,直接终止
    
2.Exception
    RuntimeException---unchecked exception
        是程序无法自我恢复的异常,用try/catch无意义,只能在编码时避免这样的应用
        如:
            Student s = null;
            s.display();//空指针异常        

    非RuntimeException ---checked exception
        一定要进行try/catch处理的异常
        如:    
            ATM取款,超出余额,不能系统崩溃


如何在原有异常基础上添加自己的异常描述信息
1)捕获了别人的异常,将它包装起来,添加自己的描述信息,扩展异常
2)unchecked exception -->checked exception,给异常添加更多的信息

    getCause() --- 获取引发本异常的异常对象,即被包装的异常


java 高级应用

Module 8 GUI图形用户界面
=============================================================================================================================
常用的包:
1)java.awt.*;
2) java.swing.*;
3) java.awt.event.*;

要求:
1.开发GUI的步骤
2.常用的布局管理器的特点

开发GUI图形界面的步骤
-----------------------------------------------------------
1.选择容器
    1)常见容器
       JFrame容器 --- 有缩小,最大,关闭按钮,通常作为顶层容器
       JDialog对话框---需要依赖其他容器,通常不独立出现
       JApplet --- 淘汰,运行在浏览器中
       
     JPanel --- 轻量级容器,没有缩小,最大等按钮,将大容器需要分割成多个小容器,给每个小容器设置自己特有的布局风格
           无滚动条
     JScrollPane --- 带滚动条的小容器 
    2)                    
        
2.设置布局管理器
    1)setLayout()
    2) 根据组件信息,决定组件在容器中的排序位置和大小
    3)setLocation setSize setBounds        
    4) 容器默认的布局管理器
        Window --- BorderLayout
        Panel --- FlowLayout
        Frame --- BorderLayout
3.往容器中添加组件
    1) 创建组件对象
        Button btu = new Button("+");
    2) 把组件对象加入容器
        add(btu);
    
   图形界面完成

4.给组件添加事件监听器
    btn.addActionListener(...);


练习:
     


常见的布局管理器
---------------------------------------------
1.FlowLayout -- 流式布局管理FlowLayout(int align)
    组件安行排列,一行放不下自动换行,窗口大小改变时自动排列, 默认居中排列
    align --指定左/中/右排列
    hgap/vgap -- 设置横向纵向间距值
2.BorderLayout
    容器划分为五大区域
    BorderLayout.CENTER
    BorderLayout.EAST
    BorderLayout.WEST
    BorderLayout.SOUTH
    BorderLayout.NORTH

    每个区域只能放一个组件,且组件充满整个区域,所以组件设置大小无意义,
    要实现放置多个组件,需要给每个区域放置轻量级小容器,给这些小容器设
    置不同的布局管理器

3.GridLayout --- 网格布局管理器
    把一个容器划分为若干行若干列大小相同的网格,每个网格只能放一个组件,
    且该组件充满整个网格,组件不能设置大小

4.CardLayout -- 卡片状布局管理器
    每个卡片只能放一个组件,且该组件充满整个组件    

Module 9  事件监听机制
==========================================================================================================
    按钮          点击         产生响应    
      事件源(产生)  事件(传给) 监听    ==>执行响应代码

事件处理机制的三要素:
1.事件源:
    能产生事件的组件 addBtu 
2.事件对象:
    把组件产生的事件包装成事件对象ActionEvent
3.事件监听器:
    接受事件对象,产生响应  ActionListener actionPerformed()

三者如何协同工作?
例:
    feng        送花        girlfriend
---------------------------------------------------
    事件源        事件对象    监听器

结论:
1)事件源要维护监听器列表,要知道事件的接受者是谁
2)事件对象要携带有事件源的信息
3)监听器根据不同的事件源做出不同的响应


事件源:Girl
    Set boys = new HashSet();
    addEmotionListener(Boy boy){}
    
    happy(){}
    sad(){}

事件对象:EmotionEvent
    Object source;

监听器:interface Boy{
        void actionPerformed(EmotionEvent);
    }


Module 10 Threads
===============================================================================================================================
进程:
    计算机运行过程中的任务单元
    1)CPU在一个时间点上只能执行一个进程
    2)每个进程执行时需要【独享资源】
线程:
    程序运行时的最小执行单位
    1)一个进程可以划分为多个线程
    2)多个线程可以【共享资源】

多个线程共享资源引发的问题:
    线程的互斥和同步问题
    

java.lang.Thread

线程的创建:
1.继承Thread类
    class MyThread extends Thread{
        public void run(){}
    }
    

2.实现Runnable接口
    class MyThread implements Runnable{
        public void run(){}
    }
    
    特点:run()方法必须要存在,线程一旦启动,该方法会自动被调用

线程的启动:
1) 继承Thread
    MyThread th = new MyThread();
    th.start();//调用Thread中的方法
2)实现接口:
    MyThread runnable = new MyThread();
    Thread th = new Thread(runnable);
    th.start();

实现方式和继承方式有什么区别呢?
-------------------------------------------------
实现方式好处:避免了单继承的局限性,在定义线程时,建议使用实现方式。
        资源可以独立共享,共享数据资源

两种方式区别:
继承---线程代码存放Thread子类run方法中
实现---线程代码存在接口的子类的run方法中 】


线程的状态转换
-------------------------------------------------------------------------
1.Runnable就绪状态
    th.start()-->Runnable
     等待JVM调度
2.Running执行状态
      JVM采取时间分片策略,根据Scheduler调度程序调度等待中线程
    Runnable--->Running(执行run()方法)
    时间片结束,JVM收回该线程的执行权,交由其他等待的线程
    Running --->Runnable
3.Dead死亡状态
    run()执行结束

4.Blocked阻塞状态
    


1)stop()--结束线程,不推荐使用,导致使用的资源不会被释放
2)设置标志变量,让线程主动结束(常用方式)
    

join()方法
    调用另一个线程的join方法,本线程进行阻塞状态,直到另一个线程执行结束,本线程才能离开blocked状态

     
人为使线程从blocked --->Runnable
1)interrupt()---线程从blocked --->Runnable
2)isInterrupted()---判断线程是否被中断,true表示被中断
    如何让线程知道是被中断的
    本线程可以通过捕获异常知道自己被打断
    其他线程通过isInterrupted()判断
3)interrupted() --- 清除中断标记


总结:
1.Running -->Blocked
    1).sleep()
    2).其他线程.join();
2.Bloack-->Runnable    
    1)sleep睡眠时间结束
    2)其他线程执行结束,本线程回到就绪状态
    3)人为中断:interrupt();


线程的并发访问问题
------------------------------------------------------------
解决方法
    synchronized(object){}

1)找出公有对象,多个线程同步竞争该公有对象的访问锁,一次只能有一个线程拿到锁(操作该对象)

2)精确控制临界区,确保多线程的执行效率

注:如果方法中所有的代码需要加锁,可在方法定义前加synchronized,否则不建议对整个方法加锁,影响程序性能

多线程的同步问题
---------------------------------
  并发访问:多个线程地位均等,同步竞争公有对象的访问权
  同步问题:解决的是多个线程对公有对象访问的先后顺序问题,相互协同工作

举例:打黑车到镇上
1)公有对象:  车
2)等待的线程: 打车的人
   通知的线程:司机  通知所有等待的线程
3)先有等待的线程

解决同步问题的思路:
1)找出公有对象,所有的线程都通过公有对象进行通讯
2)分析出哪个线程wait,哪个线程notify
3) 确保wait在notify之前

练习:                                                       
   有两个线程,一个Calculate线程负责计算1~100的和,放到公有对象Result中,另一个Print线程获取结果并打印输出
    测试程序,创建这两个线程并启动
public class Result{
   private int value;
}
class CalculateThread extends Thread{
    private Result result;
           public CalculateThread(Result res){}
}

class PrintThread extends Thread{
    private Result result;
    public PrintThread(Result res){}
}

public class CalculateTest{
   public static void main(String[] args){
    Result res = new Result();
    CalculateThread ct = new ...
    PrintThread pt = new...
   }
}
2)Print线程wait   Calculate线程notify

3) 确保wait在notify之前,添加标志变量hasWait

注意:
1)synchronized里面不能有sleep,否则抱着公有对象的锁睡觉,其他等待的线程无法拿到对象的访问锁
2)wait()在加入对象的等待队列之后,会释放该对象的访问锁
   synchronize(result){
    //result.wait();
     1)unlock(result)
     2)lock(result)
     3)entryQueue(result); //加入对象的等待队列
     4)unlock(result);  //进入blocked之前解锁对象
     5)进入blocked状态 <------notify()
     6)lock(result);
     7)leaveQueue(result); //离开对象的等待队列
   }

isAlive()---判断线程是否存活,除了dead状态,其他都为true
setPriority()---设置线程的优先级
Thread.yield()---将执行权让给优先级比自己高的线程来执行

死锁问题
--------------
   哲学家就餐问题

解决方式:
   确保线程获取多个资源的顺序相同


Module 11 I/O
==================================================================================================================================
I/O输入/输出流
------------------------------------------------------------
    java中采取流的概念,在应用程序和外围设备之间建立一个流对象,应用程序只单一地通过流对象进行数据的输入/输出,
    而不与外围数据源/数据目的地直接交互
    
按照流的方向划分:
输入流InputStream
    ---程序从输入流中【读取】数据,不能写入,read()
输出流OutputStream
    ---程序往输出流中【写入】数据,不能读取,write()

按传输的数据单位划分:
字节流
     以字节作为基本传输单位,一个个字节进行传输通常带有Stream的都是字节流

字符流
     以字符作为传输单位,字节的可读性差,希望以文本的方式读写数据通常带有Reader/Writer的都是字符流

具有缓存功能的流
     在流对象中设置缓存区,将数据先放入缓存区,再一次性提交给外围设备优势: 提高输入/输出的性能

过滤器
    对流中的数据进行进一步包装,借助过滤器可以把流中提供的字节或字符拼成程序需要的数据类型 
    readInt   readDouble  ...  

    注:【不能单独使用】,要结合基本字节流或字符流

常用方法
read()---每次返回一个字节,返回-1表示流中的数据读完
read(byte[])--一次可以读取多个字节,放入byte[]中,返回一次读取成功的字节数

字节流的层级结构
-------------------------------------------------------------------
   通常前面代表的是数据源/数据目的地的类型

FileInputStream---数据源是File,从file中读取数据
FileOutputStream---往file中写入数据

PipedInputStream---从管道中读取数据
PipedOutputStream---往管道中写入数据

FilterInputStream---过滤器,不能单独使用
   BufferedInputStream---具有缓存功能的流
   PushBackInputStream---把流中的数据退回去
   DataInputStream---把流中的字节包装成程序需要的基本数据类型(四类八种),以结构化的方式传输数据

包:java.io
异常:IOException

练习:
   完成文件内容的拷贝功能 Copy.java
   要求:以提高性能的方式进行文件的拷贝
   BufferedInputStream(FileInputStream(filename))
   BufferedOutputStream(FileOutputStream(destname))


练习:
   将一个整数以提高性能的方式写入文件中  MyCal.java
   int i = 6;

分析:
 1) DataOutputStream(
       BufferedOutputStream(
        FileOutputStream(destfile))
 2) 思考不用过滤器,如何一个个字节进行传输?


管道流
---------------------------------------------------------------------
PipedInputStream--管道输入流
    从管道中读取数据
PipedOutputStream--管道输出流
    往管道中写入数据

管道:内存中开辟的一块公共区域

  PIS(POS)   POS(PIS)

练习:
   构建两个线程
   Sender.java  ---把100个整数写入管道中 
            
   Fetch.java   ---从管道中读取并打印输出

分析:   Sender
        ---DataOutputStream(BOS(PipedOutputStream))
    Fetch
        ----DIS(BIS(PipedInputStream))
    测试程序PipedTest,构建以上两个线程对象,启动


字符流
------------------------------------------------
   和字节流的体系结构相似

基本的字符流
包装后的过滤器

1.BufferedReader/BufferedWriter
  功能:
    1)开辟缓存区,提高传输性能       类似BIS/BOS
    2)能在字符流和字符串之间进行转换  类似DIS/DOS
  方法:
    String readLine()
    write(String,int,int)
2.InputStreamReader/OutputStreamWriter
  功能:
    1)桥梁流,字节流<--->字符流
    InputStreamReader--- 字节流-->字符流
        OutputStreamWriter--- 字符流--->字节流
    2)提供java标准编码utf8和其他指定编码之间的转换

练习:
    把一个中文字符串写入文件中
    编译时指定编码格式:  -encoding utf8
分析: String--->file
       字符串--->字符流  BufferedWriter
       字符流--->字节流  OutputStreamWriter
       BW(OSW(FOS(filename),charSet))

3.FileReader/FileWriter
     ISR/OSW的子类,父类具有的功能它们都具有
  1)字符流<--->字节流
  2)具有操作文件的功能
  3)自动将编码转换为和操作系统对应的编码

练习:
    将一个中文字符串写入文件中,再从文件中读取并打印输出
    写入文件:BufferedWriter(FileWriter(filename))
    读取文件:BufferedReader(FileReader(filename))

System.out--标准输出
System.in --标准输入
System.err--标准错误

File file = new File();

FileInputStream(String filename);
File file = new File(String filename);

File.seperator---路径分隔符,自动与操作系统匹配
       windows:  c:\doc\
    linux:    /etc/

对象的持久化和序列化
-----------------------------------------------------------------------
对象的持久化:
    对象的寿命通常随着程序的终止而消亡,有时需要将对象的属性信息永久保存下来,在需要时再将该对象恢复,这个过程就叫对象的持久化


对象的序列化:
    将一个对象转变成字节流  Object--->File

ObjectInputStream
    Object readObject()--- 反序列化  得到一个对象  
 
ObjectOutputStream
    writeObject(Object o)---序列化,将对象写入外围

需要序列化的对象要实现接口:Serializable

练习:
     class Company implements Serializable{
    String name;
    int tel;
    transient Address address;  //该属性无法持久化
     }
     class Address{
    String city;
    String street;
    int code;
     }

RandomAccessFile随机访问文件
--------------------------------------------------------------------------
    可以跳到文件任意一个位置开始读/写

1)实现了两个接口:DataInput/DataOutput 具有过滤器功能
    readInt writeDouble ....readLint
2)读/写功能都具有  read  write
3)操作文件的功能
4)可随意在任一点读写
    skip(long)---跳过指定的字节数,但还是从文件起始位置开始遍历
    seek(long)---直接跳到指定位置开始读写
    
    构造器参数mode:
        "r" --- read
        "w" --- write
        "rw"---read/write


InputStream
    FileInputStream(String name) 

    PIpedInputStream(PipedOutputStream src)

    ByteArrayInputStream(byte[] buf)

    ObjectInputStream(InputStream in)

    FileterInputStream
        DataInputStream(InputStream)
        bufferedInputStream(InputStream)

Reader
    PipedReader(PipedWriter src) 

    InputStreamReader(InputStream in)   ----   桥梁流
        FileReader(String fileName)

    CharArrayReader(char[] buf)

    BufferedReader(Reader in) 

Module 12  网络编程
================================================================================================================================
1.基于TCP/IP协议的编程
2.基于UDP协议的编程

IP地址:可以唯一定位网络上的一台主机
Port端口号:人为制造的16位整型数,只能用1024之后的

包:
1.java.net
2.java.io
3.java.lang


IP
特点:无连接的,数据可靠性不能保证

TCP---解决的事数据传输的可靠性问题

特点:    1)面向连接的
          2)【完全可靠的数据传输】
    3)点对点的
    4)同一连接既可以发送也可以接收
    5)面向字节流的
    6)连接的建立和关闭经过双方确认


UDP---解决的是数据传输效率问题
    视频点播
邮递员送信

1.DatagramSocket
    --只负责报文的发送/接收
2.DatagramPacket
    --负责将数据打成报文对象

        


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值