java自己总结的学习笔记

大家好!这是我学完java基础后自己总结的学习笔记,希望对大家有帮助。

java中的语法:
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
  常量:

java中的常量:程序中固定的,不变化的量
    浮点型:就是小数
    布尔型:true false
    字符型:(数字符号)  'a''1'(只能放一个)“”空字符串
   字符串型:双引号表示,很多字符组成的串
     空常量:表示对象的引用为空。


整数进制:(计算机存储数据的方式)

  二进制:0-1
  八进制:0-7开头  (不太常用)  三个二进制位,就代表一个八进制位
  十六进制:0-9 A-F   0X开头    四个二进制位,就代表一个十六进制位
 十进制:0-9
 
    变量:

java中的变量。用于存储常量的内存空间
     空间里的值可以变化

 这个变量可以被重复使用

什么类型的数据往什么里面放。

数据类型:

八个二进制表示一个数据,一个字节!
 1.基本数据类型
      数值型  
          整数部分   byte(一个八位) short(二个八位) int(四个八位) long(八个八位)整数默认都是int型
          浮点类型  float(四个八位) double(八个八位) 小数默认都是double型的
      字符型 char
      布尔型 boolean
 2 引用数据类型       (null常量是给引用数据类型使用的)
      类 class
      接口  interface
      数组 ([])

 java当中,不同数据类型之间是不能直接进行运算的


 强制类型转换
 自动转换   视频一30分钟左右。是重点
............................................................................................................

java中的运算符:
 1.算术运算符:
    模运算
   连接符(+)
   自增 自减

 *任何数模与2不是0就是1,可以用做开关运算。

 2.赋值运算符:
     int a=4

   a+=3 只有赋值运算  等同  a=a+3  赋值运算和算术运算

例子:short s=3;      第二视频15分钟左右    
     s=s+2  // 

   s+=2; 能运算
 
  3.比较运算符:(非常明显的特点,运算完的结果,要么是真,要么是假)。 
 相等于 ==
   不等于!=

 instanceof 检查是否是类的对象      day7多态32分钟
  
         用于判断对象是否所属于指定类或者接口

 4.逻辑运算符:

 5.位运算符 (十进制转换成二进制)

  左移  <<          直接拿0补
  右移  >>        最高位是什么,就那什么补
  无符号右移 >>>    直接拿0补
  
& | ^ 也是位运算符

二进制1就是true,0就是false。

........................................................................................................

程序流程语句:
 1 判断语句
 
   if..
    if..else
  三元运算符:运算完必须有结果
   例:int x=3,y=0;
       if(x>3)
         y=100;   //不写大括号是控制 当条语句
       else
         y=200;
    y=(x>3)?100:200;三元运算符
 
  System.out.println("y="+(x>3)?100:200);
    if..else if..else if..else


  
  2 选择语句
     switch语句
                跳出或者结束break语句。
      四种类型  byte short int char  枚举

*if和switch都可以用于判断
  但是if比较强大,除了判断值以外
还能判断范围。而且if某些方法返回的布尔型的值

 Switch只能对值进行选择

什么时候用,和区分!
  当你有限的几个值进行判断,用switch较快。
switch能做,if基本都能够做。

  3 循环语句

  while 循环
 do..while 循环  无论条件是否满足,循环体都执行一次,只需要了解,用的极少。
 for循环
while和for的区别:

 书写时,用while写出来的,用for绝对没问题。
 使用上,变量仅为循环增量而存在 就用for
  如果定义一个变量被循环操作,还被下面语句所操作,就用while。
用到了内存消耗。

  无限循环:
 while(true){}

 for( ; ; ){}

更加重要的内容:什么时候用到循环语句(这是起初思想)

 程序自动去执行某些语句,让某些语句执行很多次的时候,
就使用循环结构。
 写循环的注意事项:哪些需要参与循环,哪些不需要参与循环。
                 一定要先明确出来。

循环应用:
  获取1-100的和:通过累加思想完成。
      累加思想:
    定义一个变量,不断记录每一次变化的结果
          并用该结果和下一个数据进行运算
      在运算时,因为数据较多,并有规律
       所以使用循环会较为方便。

  定义变量,并循环一走,就完事了。
     int sum=0;
   for(int x=1;x<=100;x++)
  {
     sum=sum+x;
   
  }
 System.out.println(sum);

 计数器思想:只要这条件满足,就计数一次
              都装完以后,看看到底计数了多少次。

    思想:定义一个变量,通过递增或者递减来记录次数,通常和循环互相结合
            并需要定义计数条件。

打印1-100的6的倍数 出现的次数
 */
 int count=0;
  for(int x=1;x<=100;x++)
   {
     if(x%6==0)
      count++;
   }
 System.out.println("count="+count);
  }
}


3000米,每天去除一半,需要多少天会小于5米

 思路:定义个变量表示天数
      除的动作和天数累加的动作是重复进行。
*/
    
      int day=0;
    for(int x=3000;x>=5;x/=2)
      {
           day++;   
      }
    System.out.println(day);
   }
 }
................................................................................................

用到时候,回头来复习。看看就能懂。
 break continue
break:用于选择结构 或者循环结构。

continue: 用于循环结构
                结束本次循环,开始下一次循环

.....................................................................

语句综合练习:
   FOR  FOR循环。

99乘法表
    for(int x=1;x<=9;x++)
  {
   for(int y=1;y<=x;y++)
    {
     System.out.print(y+"*"+x+"="+y*x+"\t");//不变化的加“”\t制表符
    }
   System.out.println();
  }
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
选择排序的思想:
 首先将第一个位置的元素标记为最小,依次与后面的元素比较,
 当发现比第一个元素更小的元素时,将那个元素标记为最小,
 然后用最小的这个元素继续与后面的元素比较,直到最后,
 然后将第一轮比较中最小的元素,与第一个元素交换位置。
 接下来,进行第二轮循环,再以第二个元素作为起点,将其标记为最小,
 因为第一个元素已经排好了位置。依然按照上面的方法比较。依次类推,
 直到将所有最小的元素选择出来,与前面的交换。所以叫做选择排序。

public void selSort() {

  int min; // 用于标记最小的下标

  for (int i = 0; i < nElems - 1; i++) {

   min = i;

   for (int j = i + 1; j < nElems; j++) {

    if (arr[j] < arr[min]) {

     min = j;

    }
   }

   if (min != i) {

    long temp = arr[min];

    arr[min] = arr[i];

    arr[i] = temp;

   }

  }

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
插入排序思想:
 * 将位置为1(即下标为1)的元素取出复制到temp的临时变量,
 * 然后将它与位置1之前(当然这里只有0)的元素进行比较,如果temp中的值比位置0的值大,
 * 则直接将temp复制到位置1。如果它比位置0的值小,则将位置0的值向右移动一位,
 * 然后将temp复制到位置0。这样前两位元素就局部有序了。
 * 接下来,取出位置2上的元素复制到temp临时变量,将它与2之前的两个元素进行比较,
 * 如果比它们都大,就将它放回位置2;如果比位置1上的小,而比位置0上的大,
 * 则将位置1复制到位置2,然后将temp复制到位置1;如果比它们两个都小,
 * 则将它们两分别向后移动一位,然后将temp复制到位置0。依次类推。
 * 因此,可以发现插入排序是属于局部有序的,对于局部本来就有顺序的数组来说,插入排序无疑是一种很好的选择。

public static int[] insertSort(int[] args) {  //工具方法
  for(int i=1;i<args.length;i++){
   for(int j=i;j>0;j--){
    if(args[j-1]>args[j]){
     int temp = args[j-1];
     args[j-1] = args[j];
     args[j] = temp;
    } else {
     break;
    }
   }
  }
  return args;
 }

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
 冒泡排序的思想:
  1. 首先这些简单排序(包括:冒泡排序、选择排序和插入排序)针对的数据结构是数组。
 2. 冒泡排序的整个思想是:
 从左到右,依次对相邻的两个元素比较大小,将较大的元素移动到右侧
 (这里的移动其实是将较小的元素放入中间临时变量temp,
 将较大的移动到右侧,然后将较小的放回到左侧。当然,如果原本右边的值就大,就不需要交换位置。),
 当第一轮比较完后,最后一个元素即为数组中最大的元素。
 接下来,进行第二轮的循环,此时就不需要对整个数组进行遍历了,
 只需要遍历到倒数第二个元素,因为最后一个已经排好序了。依次类推,直到将所有的元素排好序。
 

public void bubbleSort() {

       for(int i=nElems-1; i>0; i--) {

           for(int j=0; j<i; j++) {

              if(arr[j] > arr[j+1]) {

                  long temp = arr[j+1];

                  arr[j+1] = arr[j];

                  arr[j] = temp;

              }

           }

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

   

折半查找2
 public static int halfSearch2(int[] arr,int key)//key代表角标
{
    int max,min,mid;
    max=arr.length-1;
    min=0;
   while(min<=max)
    {
     mid=(max+min)/2;
      if(key>arr[mid])
        min=mid+1;
       else if(key<arr[mid])
           max=mid-1;
       else
         return mid;
      }
    return -1;
}

    
    第二种,更加的简单易懂。

   2 十进制转二进制  (先模再除) 用到StringBuffer
  public static  void toBin(int num)
   {
       StringBuffer sb=new StringBuffer();
         while(num>0)
          {
                 sb.append(num%2);
                 
                   num=num/2;
          }
        System.out.println(sb.reverse());
   }
 

   3 十进制转十六进制   

  第二种方法(查表法):public static void toHex(int num)
   {
       char[] chs={'0','1','2','3','4','5','6','7','8',
             '9','A','B','C','D','E','F'};
       StringBuffer sb=new StringBuffer();
      for(int x=0;x<8;x++)
       {
         int temp=num&15;
        sb.append(chs[temp]);

         num=num>>>4; 
        }
    System.out.println(sb.reverse());

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

异常:
 其实就是对不正常情况的描述。
 在描述过程分成两个部分。一部分可以处理,一部分一般情况其不用处理。
 通过向上抽取,形成异常体系。
 Throwable
  |--Error:不需要编写处理代码。需要对程序进行修改。
  |--Exception:可以编写特定的处理代码。
   |--RuntimeException
 
 
 异常在运行时发生,通过特定方式处理:
 try {需要被检测的代码;}catch(异常类 变量){异常处理代码;}finally{一定会被执行的代码;}

 catch的运行:当try中检测到了异常,就会把它丢给catch的引用。
 finally的运行:除了遇到System.exit(0)以外,finally都会被执行。
   通常finally中书写都是关闭资源代码(调用了系统底层资源,关闭数据库资源。)


 在定义功能时,功能因为参数的不同,会引发一些问题,那么需要将这些问题暴露出来,让调用者进行处理,
 因为实际参数是由调用者传入的。
 通过throws关键字将问题声明在函数上。


 如果调用到声明了异常的函数,需要对异常进行处理,两种处理方式:
 1,通过try。
 2,将异常继续向上抛出。如果是主函数在往外抛,
  这时jvm就会用默认的异常处理机制对其进行处理,但在这样会导致程序停止。

 自定义异常:
  在自定义的项目中,会出现项目针对性的问题,那么按照面向对象的思想,
  一样需要对该问题的进行描述。并封装成对象。

  其实和定义其他类一样,都是在描述事物,该描述的类具备可抛性而已。
  

  书写:
   定义一个类,需要继承Exception,目的是让自定的类具备可抛性。
 
 class NoException extends Exception
 {

  NoException()
  {
   super();
  }
  NoException(String message)
  {
   super(message);
  }
 }
 该对象出现的,需要通过throw 关键字手动抛出。
 为了丰富自定义异常的内容比如异常信息。可以在该类中定义一个构造函数接收字符串异常信息。并通过super将该信息向上传递这样就可以通过Throwable的getMessage()方法获取该自定义信息。
 原理参考Day8\MyThrowable.java文件。
 

 throws与throw
 区别:throws用在函数上。后面跟的是异常类名,可以跟多个,通过逗号隔开。
  throw用在函数内,后面跟的异常对象。
 
 通常,函数内出现throw,函数上都需要进行throws的声明否则,编译失败。
 特殊情况,如果函数出现的throw了RuntimeException或者其子类,那么函数上可以不用声明。
 为什么呢?
  在编译时期,RuntimeException不会被检测的。在运行发生,通常又默认的异常处理机制进行处理,让程序停掉,需要调用者对代码进行修正。
   而其他异常,是在编译时期会被检测的。

 技巧:
 如果编译时出现了,某某异常,必须被捕获或者声明以便抛出的提示,
 说明编译错误已经解决到最后了,把该异常问题解决编译搞定。

 原则:
  被调用的功能上声明几个异常,在进行try的时候就书写几个catch要对应。
  如果出现父类catch,一定要往下放。
 
 异常使用注意事项:
  在进行子父类的覆盖时,子类覆盖父类只能抛出父类异常或者异常的子类或者子集。

  如果父类被覆盖功能没有异常抛出,子类也不可以抛。子类中真的出现了问题,必须用try进行处理。

 异常的好处:
  1,对问题进行封装。可以指挥问题做事情。
  2,引起程序的跳转,当出现的问题已经无法进行下面的运算就需通过异常来导致程序的跳转。
  3,将程序正常执行代码与错误处理代码相分离。


 Throwable:
  String getMessage():获取异常信息。
  String toString():获取异常类名以及异常信息。
  void printStackTrace():直接打印异常类名,异常信息以及异常出现的位置。

 特别注意:
 try catch finally
 是三个封闭的代码块 ,也就是说在try中定义的变量,在其他代码块中是无法访问的。

 数据库连接 conn  = null;
 try
 {
  conn  = new 数据库连接();

  code...;  
 }
 catch ()
 {
 }
 finllay
 {
  conn.close();
 }

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
继承:
 1,提高了代码的复用性。
 2,类与类之间产生了关系,关系的出现,就是多态的由来。

 java只支持单继承,不支持不多继承。
 原因:当出现多个类中有相同方法时,子类不确定调用的是哪一个。
  其实就是父类中的方法有方法体。
 
 但是java支持多层继承。在多层继承中,父类定义都是共性成员。
 所体现的内容:
   1,父类是不断向上抽取而来的。
   2,既然父类体现的共性内容,那么在使用一个继承体系时,
  只需要查阅最顶层父类即可了解该体系的基本功能。(查阅API技巧之一)
   3,只要建立最子类的对象即可对该继承体系进行应用。

 子父类的出现,子类因为持有一个父类引用super,可以获取到父类中非私有的成员。
 如同子类中也有一个份一样。

 覆盖(复写)override. 
 对于成员函数,当子父类中出现了一模一样的函数时,会出现一个覆盖操作。
 在运行时,会运行子类中的方法。
 覆盖注意:
    1,子类覆盖父类方法,必须权限大于等于父类。
    2,静态覆盖静态。
    3,覆盖只发生在函数上。

 什么时候使用覆盖呢?
    可以通过覆盖的形式对父类的功能进行重新定义。
    比如:对功能进行修改或者对功能进行升级。
 注意:不要在子类中定义新功能。还要以父类中的声明为主。


 class Demo
 {
  void show()
  {
   System.out.println("Demo show");
  }
 }


 main()
 {
  //Demo d = new Demo();
  SubDemo d = new SubDemo();
  d.show();

 }

 
 为了提高可维护性。
 建立一个子类继承Demo,复写其中的某些需要修改的功能即可。
 class SubDemo extends Demo
 {
  void show()
  {
   System.out.println("subdemo show");
  }
 }


 super关键字:代表的父类应用。super的应用和this的使用完全一样。

 子类的实例化过程:
 子类中所有的构造函数回去访问父类中的空参数构造函数。
 那是因为:每一个子类构造函数中的第一行都有一个句隐式super()语句。
 原理:子类继承父类,获取获取到了父类中的成员,所以子类必须要先明确父类是如何对这些成员进行初始化的。
 如何父类中没有了空参数构造函数,需要在子类的构造函数通过super,或者this语句指定要访问的构造函数。

 
 什么时候使用继承呢?
  当类与类之间出现所属(is a)关系时,就使用继承。
  类中的所有成员是否可以被另一个类所以拥有.
  如果是继承.
  如果不是,看是否具备向上抽取的可能.
 
 class A
 {
  void method(){}
  void function(){}
 }

 有了一个B类,B中也需要一个method()方法。
 这时,是否可以用B继承A来获取这个方法呢?因为这样不是可以提高复用性吗?

 那么判断,B和A之间有所属关系吗?不会判断。
 这时,可以通过另一个方式,B是否应用具备A中所有功能?
 不是。B只需一个method()方法即可。不需要function()。这样就不需要继承。
 但是B中就会重复定义method()方法。
 那么A和B出现了共性的内容,就具备了向上抽取的内容。这时A和B就又出现一个父类C。

 class B
 {
  void method(){}
  void show(){}
 }

 所以最终设计:
 class C
 {
  void method(){}
 }
 class A extends C
 {
  void function(){}
 }
 class B extends C
 {
  void show(){}
 }

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

final 关键字
 1,final可以修饰类,方法,变量。
 2,final修饰类不可以被继承,但是可以继承其他类。
 3,final修饰的方法不可以被覆盖,但可以覆盖父类方法。
 4,final修饰的变量包括成员变量,类变量,局部变量,这些变量只能赋值一次。
 5,内部类在局部时,只可以访问被final修饰的局部变量。
 通常规范中,被final修饰的变量是一个常量,常量名称所有字母大写。

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

抽象类:
 
 分析事物时,发现了共性内容,就出现向上抽取。
 会有这样一种特殊情况,就是功能声明相同,但功能主体不同。
 那么这时也可以抽取,但只抽取方法声明,不抽取方法主体。
 那么该方法就是一个抽象方法。
 抽象方法的表现形式:abstract 返回值类型 函数名称(参数列表);
 抽象方法一定要存放在抽象类中。

 特点:
 抽象类不能用new进行实例化。
 想要创建对象,必须通过子类复写父类中所有的抽象方法后,该子类才可以创建对象。


 抽象类定义时,和一般类一样,都是在描述事物,只不过抽象类可以存放抽象方法,不可以建立对象。

 抽象方法的出现可以强迫子类去做某些事。

 例:学员类的例子。
 学员类的出现其实分析了现实生活中的学生而来的。
 张三:躺着睡觉,学习(总结式)
 李四:躺着睡觉,学习(机械式)

 abstract class 学员
 {
  void 睡觉(){躺着睡觉;}
  abstract void 学习();
 }

--------------------------------------------
接口:
 简单的理解成抽象类的特殊表现形式,当抽象类的方法全都是抽象的,那么这时就用接口来表示。

 特点:
 -- 接口是对外暴露的规则。
 -- 接口是功能的扩展。
 -- 接口的出现降低了耦合性。
 -- 在java中,多继承的机制被java通过另一种形式来体现,就是多现实。
 -- 在java中,一类可以继承一个类的同时,实现多个接口。
 例子:主板的pci接口。插座。笔记本电脑的usb接口。

 interface 抽烟
 {
  抽烟方法;
 }
 class 张三 extends 学员 implements 抽烟
 {
  void 睡觉(){躺着睡觉;}
   void 学习(){}
  抽烟方法{}
 }


 接口中通常的定义的内容:
 1,全局常量。public static final
 2,公有的抽象方法。 public abstract


 类与类之间是继承关系。
 类与接口之间是实现关系。
 接口与接口之间是继承关系,而且,接口之间存在多继承。

子类对象:
 其实就是内部类的简化形式
前提:内部类

  格式
   new

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
匿名内部类

/*
匿名内部类:
其实就是内部的简化形式。
前提:
 内部类必须继承或者实现外部类或接口。

格式:
 new 父类&接口(){};
 其实就是一个子类对象。有点胖。


*/

abstract class Test
{
 abstract void show();
 abstract void show1();
}

class Outer
{
 int x = 3;
 /*
 class Inner extends Test
 {
  void show()
  {
   System.out.println(x);
  }
 }
 */
 public void method()
 {
  //new Inner().show();

  func(new Test()
  {
   void show()
   {
    System.out.println("x="+x);
   }
   void show1()
   {
    System.out.println("x="+x);
   }
   
  });
//  t.show();
//  t.show1();
  
 }
 public void func(Test t)
 {
  t.show();
  t.show1();
 }
}

class  OuterDemo
{
 public static void main(String[] args)
 {
//  new Outer().method();

  function(new Test()
  {
   public void show(){}
   public void show1(){}
  });
 }

 public static void function(Test t)
 {
  t.show();
  t.show1();
 }
}


。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
容器


   

  Collection            0角标和 1角标的 “abc”  
     List:列表:每一个元素都有自己的角标,可以存入重复元素,有序的
                        (存入的顺序和取出顺序是一致的)
           特有:
             添加:add(index,Element)
             获取 get(index)
             修改 set(index,Element)
             删除:remove(index);
      ,
      ArrayList:底层使用的就是数组数据结构。线程不安全的。效率比较好
                      查询速度很快
      ***往集合里存入自定义对象,必须强制转换
          Vector:底层也是使用数组数据结构。线程安全的。被ArrayList替代了。
          LinkedList: 底层是链表数据结构,增删速度很快。查询速度较慢

        
      ................................................

      Set(没有特有方法,同Collection一样):无序的,不可以存入重复元素。

          HashSet:底层哈希表数据结构。通过哈希值来确定元素的位置
                  保证元素唯一性通过hashCode方法,和equals方法。来完成的
             hashCode()判断位置   equals()判断内容
           当哈希值不相同的时候,不需要判断equals方法
          只有当哈希值相同时候,才会判断equals方法。

        (只具备Collection的方法),因此只能进行基本的操作。比如,修改方法
                      就不存在
 
          TreeSet :可以对Set中的元素进行排序,按照
                字符串字典顺序.

   排序方式一:让元素自身具备比较性,需要元素实现Comparable接口,并覆盖
                 compareTo方法。  通过return 0的方式判断元素是否相同,判断
                      元素的唯一性。
    排序方式二:
 当元素自身不具备比较性或者自身具备的比较性并不是所需要的这时,就需要第二种比较方式
 让容器一初始化就具备比较性。 (只具备Collection的方法),因此只能进行基本的操作。比如,修改方法就不存在
 

 1.ArrayList.
import java.util.*;

class ArrayListDemo
{
  public static void main(String[] args)
  {
   //定义一个可以存放对象元素的对象(集合)。
    ArrayList a1=new ArrayList();//能装对象的对象。
      a1.add("zbc");
      a1.add("abc"); //通过add方法往集合中 "存入"元素
      a1.add("wxyz");
      a1.add("dwc");
 //通过list集合特有方法,set修改集合中的元素
   // a1.set(1,"kekeke") //1角标由原来的abc变成 kekeke

 //"指定位置添加"元素
    //a1.add(0,"hahaha"); //0角标位置添加hahaha

 // 通过list集合的特有方法,remove(index)删除一个元素
     //  a1.remove(2);
      
   for(int x=0;x<a1.size();x++)
     {
      //System.out.println(a1.get(x));
     }

 //取出元素,通过get().
    System.out.println(a1.get(0));//取出零角标元素。
    System.out.println(a1.size());//对象长度

    Iterator it=a1.iterator();
  //子类对象
    while(it.hasNext())  //取出对象。
     {                               
       System.out.println(it.next());  // 对元素两种取出方式  迭代器 和get()
     }
开发时候写:  for(Iterator it=a1.iterator();it.hasNext(); )
               {
                 System.out.println(it.next());
               }
  }
  
}

import java.util.*;

class ArrayListDemo
{
   public static void main(String[] args)
   {
     ArrayList a1=new ArrayList();
      a1.add("abc");
      a1.add("nia");
      a1.add("vonf");
      a1.add("finw");

  /* for(int x=0;x<a1.size();x++)
        {
         System.out.println(a1.get(x));
       }
    Iterator it=a1.iterator();
     while(it.hasNext())
       {
          System.out.println(it.next());
       }  */
       for(Iterator it=a1.iterator();it.hasNext(); ) 
         {
            System.out.println(it.next());
         }                 //多行为(查看有元素,再取),需要一封装,变成类。
   }
}
*/
//2.熟悉 Vector的特有方法。

//熟悉 Vector的特有方法。

import java.util.*;
 class VectorDemo
{
   public static void main(String[] args)
    {
      Vector v=new Vector();
 
      v.addElement("kkki");
      v.addElement("wcc");
      v.addElement("haitni");
      v.addElement("daato");

    for(int x=0;x<v.size();x++)
      {
        System.out.println(v.elementAt(x));
      }

    }
}
3.LinkedList

               老师上课视频还没讲

.....................................................

//往集合里存入自定义对象。 重点是,必须要强转 .第一个视频末尾,接着看看!!!!!!!!!!!!!!!

import java.util.*;
class ArrayListTest
{
   public static void main(String[] args)
    {
     ArrayList a1=new ArrayList();
  
      a1.add(new Person("zhangsan",40));//怎么去排序。学生不具备可比较性。
      a1.add(new Person("fengjie",29));
      a1.add(new Person("xili",33));
      a1.add(new Person("lisi",45));

     Iterator it=a1.iterator();


   
      while(it.hasNext())
      {
      
       Object obj=it.next();
      Person p=(Person)obj;   //重要:存储自定义对象,必须要强制转化(强转)
       if(p.getAge()>=30 )    
      // System.out.println(p);// p=p.toString()        
       System.out.println(p.getName());
      }
   }
}
class Person  implements Comparable
{
   private String name;
   private int age;
   Person(String name,int age)
    {
     this.name=name;
     this.age=age;
    }
   public String getName()
    {
       return name;
    }
   public int getAge()
     {
      return age;
     }
    public String toString() //覆盖Object父类方法。
     {
       return "name="+name+",age="+age;
     }
}

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
Map:以键对的形式存入,必须要保证键的唯一性

   添加: put(key,value)
   判断:  containsKey(key),containValue(value)
   删除    remove()
   长度    size()
   取出:  get(key)
   取出所有元素:
      原理:将Map

--HashMap:数据结构是哈希表,线程不安全,可以存入null键null值
--HashTable:数据结构哈希表,线程是安全的,不可以存入null键和null值,被HashMap所取代
--TreeMap:数据结构式二叉树,线程不安全,可以对Map集合中的数进行排序

什么时候使用Map集合呢?
当分析问题时,对象间出现了映射关系时,就要先想到Map集合。

.................................................。。。。。。。。。。。


................................................

                      缓冲区提高了对数据的读写操作缓冲区:
                    ........................................
           反正操作流对象,通常都需要 用到 缓冲区
          字符流的缓冲区:必须要刷新 .flush()
 
 day16内容:读写 复制(数组就是自定义缓冲区)    然后是演示字符写入流的缓冲区 读取流的缓冲区 
 拷贝文件用缓冲区  然后是  装饰设计模式

/*
字符流
Reader Writer

需求:
在硬盘上创建一个文件并写入一些数据:

import java.io.*;
创建FileWriter对象,调用Windows资源,在制定位置创建好了数据存放的目的地。
 如果指定目录下,已存在要创建的文件,那么会被覆盖。

   FileWriter fw=new FileWriter("demo.tet");

  通过流对象write方法将字符串写入到流中
    fw.write(abcde);

  关闭资源,清空它先
     fw.close();

需求,对原有文件进行数据的续写
写入:(Writer)
class FileWriterDemo
{
  public static void main(String[] args)
  {
    FileWriter fw=null;
   
    try
     {
       fw=new FileWriter("demo.txt",true);
        fw.write("wsss\r\name");
     }
    catch(IOException e)
     {
         System.out.println(e.toString());
     }
   finally
     {
        if(fw!=null)
         try
           {
             fw.close();
           }
          catch(IOException e)
          {
              System.out.println("close:"+e.toString());
          }
     }

  }
}
.........................................................
*/
读取1
import java.io.*;
class FileReadDemo
{
   public static void main(String[] args)
    {
       //建议一个字符读取流对象,与指定文件相关联。
      FileReader fr=new FileReader("demo.txt");
      //创建一个字符数组,为了将硬盘上读取的每一个字符存入数组中
       char[] arr=new char[1024];
         int num=0;
       while((num=fr.read(arr))!=-1)
        {

      System.out.println(new String(arr,0,num));

         fr.close();
        }
  read(char[] obuf)   将字符读入数组
                  
    }
}
读取2
import java.io.*
class FileReaderDemo2
{
   public static void main(String[] args)throws IOException
 {
       FileReader fr=new FileReader("demo.txt");

     int ch=0;
    while((ch=fr.read())!=-1)//读一个写一个。
     {
          System.out.println((char)ch);
     }
    fr.close();

 }
read() 读取单个字符


...................................................
/*
练习:将C盘的文件1.txt复制到D盘(本盘)
思路:复制动作,先对C盘的1.txt进行读取,
获取其数据,将获取的数据写入到D(本盘)某一文件中。

*/
import java.io.*;
class CopyText
{
   public static void main(String[] args)throws Exception
    {
        
        FileReader fr=new FileReader("baichichi.java");
        FileWriter fw=new FileWriter("chenyibaichi.txt");
        char[] arr=new char[1024];  一次行写入
        int num=0;
        while((num=fr.read(arr))!=-1)   将字符读入数组。
         {

           fw.write(arr,0,num);
         }
      
        fw.close();  //最后开的最先关
       fr.close(); 
      

    }
}
另一种:读一个写一个

/*
练习:将C盘的文件1.txt复制到D盘(本盘)
 思路:复制动作,先对C盘的1.txt进行读取,
  获取其数据,将获取的数据写入到D(本盘)某一文件中。

*/
import java.io.*;
class CopyText
{
   public static void main(String[] args)//throws Exception
    {
         FileReader fr=null;
         FileWriter fw=null;
      try
      {
        fr=new FileReader("baichichi.java");
       fw=new FileWriter("zchenyishizaa.java");
       
        int ch=0;
       while((ch=fr.read())!=-1)
     {
        fw.write(ch);
     }

    }
    catch(IOException e)  
    {
       System.out.println(e.toString());
    } 
    finally
     {
      if(fw!=null)           //最后开的最先关。
         try
        {
         fw.close();
        }
     catch(IOException e)
       {
        System.out.println(e.toString());
       }
      }
      if(fr!=null)        
         try
        {
         fr.close();
        }
     catch(IOException e)
       {
        System.out.println(e.toString());
       }
    }
}
....................................................

 缓冲区:

反正操作流对象,通常都需要 用到 缓冲区
字符流的缓冲区:必须要刷新 .flush()

 特有方法(跨平台)换行:newLine(),

/*

 演示字符写入流的缓冲区:
*/
import java.io.*;
class BufferedWriterDemo
{
  public static void main(String[] args)throws Exception
  {
    //1先要创建流对象
    FileWriter fw=new FileWriter("zchenyishigebaichichi.txt");
  

//2创建缓冲区,与流对象相关联
  BufferedWriter bufw=new BufferedWriter(fw);
    // bufw.write("abcde");
    // bufw.newLine();//特有方法换行,并且跨平台。
    // bufw.write("kkk");
    // bufw.flush();
  for(int x=0;x<4;x++)
   {

    bufw.write("abcde"+x);
      bufw.newLine();
     bufw.flush();
   }
}
}
............
  或者                  
//演示字符写入流的缓冲区:
import java.io.*;
class BufferedWriterDemo
{
 public static void main(String[] args)throws IOException
  {
    //先要创建流对象
    FileWriter fw=new FileWriter("ahongxiacaidan.txt");
   //创建缓冲区,与流对象相关联

    BufferedWriter bufw=new BufferedWriter(fw);

     for(int x=0;x<4;x++)
      {
      
       bufw.write("abcde"+x);
        bufw.newLine();//特有方法,换行
       bufw.flush(); //写一个刷新一下
       
      }
 
     bufw.close();
  }
}
................................................

//字符读取流缓冲区   BurreredReader
import java.io.*;
class BufferedReaderDemo
{  
    public static void main(String[] args)throws IOException
   { //创建流
    FileReader fr=new FileReader("ahongxiacaidan.txt");
    //缓冲区与流关联。 创建缓冲区
    BufferedReader bufr=new BufferedReader(fr);
    
    String line=null;
   while((line=bufr.readLine())!=null)
   {
      System.out.println(line);
   }

   //String s=bufr.readLine();//readLine()返回值是String.
     // System.out.println(s);
   
    bufr.close();
    }
}

 readLine() 回车符前的数据。abcdnf\r\n
//返回值是String。
//readLine() 读取一个文本行,文本以行存在,一行一行读很高效,
//返回:包含该行内容的字符串,不包含任何终止符,如果已到达流
     //末尾,则返回null.

...............................................................................................
文件缓冲区拷贝
//字符读取流缓冲区  FileReader FileWriter BufferedReader BufferedWriter
import java.io.*;
class BufCopyText
{  
    public static void main(String[] args)//throws IOException
   {

     FileReader fr=null;
     FileWriter fw=null;
     BufferedReader bufr=null;
     BufferedWriter bufw=null;
    try
      {
       fr=new FileReader("chenyishigebaichi.txt");
       fw=new FileWriter("worinimama.txt");
       bufr=new BufferedReader(fr);
       bufw=new BufferedWriter(fw);
         String line=null;
     while((line=bufr.readLine())!=null)
       {
         bufw.write(line);
          bufw.newLine();
          bufw.flush();
       }

      }
    catch(IOException e)
      {
       System.out.println(e.toString());
      }
     finally
       {
          if(bufr!=null)
            try
            {
                 bufr.close();
            }
          catch(IOException e)
           {
                System.out.println(e.toString());
           }
         if(bufw!=null)
            try
            {
                 bufw.close();
            }
          catch(IOException e)
           {
                System.out.println(e.toString());
           }
       }

      }
   }

....................................................................

 装饰设计模式:新的想法就搞一个包装类。创建自己装饰类的对象,并调用新的方法就可以了。

/*
对原有的对象增强功能:装饰设计模式/包装设计模式
*/
class Person
{
  void chifan()
   {
    System.out.println(chifan);
   }
}
 class SuperPerson//增强谁传谁。只为增强人而存在 SuperPersom增强了Person功能
  {                    //SuperPerson就是装饰设计模式,设计出来的一个对象。
   private Person p;
    SuperPerson(Person p)
   {
      this.p=p;
   }
  public void superChifan() 
   {
     System.out.println("开胃酒");
     p.chifan();
     System.out.println("甜点");
     System.out.println("来一根");
    }
 }
class Person
{
  public static void main(String[] args)
   {
    Person p=new Person();  //早期对象不变,方法不用
  //  p.chifan()
    SuperPerson sp=new SuperPerson(p);
     sp.superChifan();
     }
}
装饰设计模式:可以对原有对象的功能进行增强
只要将原有对象作为参数传递给 装饰类的构造函数即可
对外提供增强方法

通过以前所学,继承一样可以解决这个问题,那么装饰可继承有什么区别呢?
  拿I/O流


继承可以完成基本需求,导致了继承体系的臃肿。
而且子类功能的重复。
...................................................

/*

  分析readLine();
  其实用的还是最终流对象的read(),一次读一个,但是将字符进行临时存储
 当读取了结束标记回车符的时候,把临时存储中的数据一次性的返回
*/

装饰类
 
import java.io.*;

 class MyBufferedReader
{
   private FileReader fr;
    MyBufferedReader(FileReader fr)
   {
     this.fr=fr;
   }
  public String myReadLine()throws IOException
    {

     StringBuilder sb=new StringBuilder();//1.5版本开始,所以本机无法运行。本机是1.4版本

       int ch=0;
    while((ch=fr.read())!=-1)
      {
         if(ch=='\r')
             continue; //\r    \n day12System,In那个视频里曾经讲过
         if(ch=='\n')
               return sb.toString();
           else
               sb.append((char)ch);
         
        }
       return null;
    }
  public void myClose()throws IOException
     {
       fr.close();
     }
}
class MyBufferedReadDemo
{
  public static void main(String[] args) throws IOException
 {
    FileReader fr =new FileReader("woxihuandalanqiu");
    
   MyBufferedReader mybufr=new MyBufferedReader(fr);
   
    String line=null;
    while((line=mybufr.myReadLine())!=null)
    {

   System.out.println(line);
    }
  mybufr.myClose();
}

}

 。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
网络编程

(腾讯) udp: 无连接,速度快,不安全
          例如视频会议的时候,无所谓
       因为不重要,不安全没关系。

  TCP:建立连接
      例如:打电话安全
        形成通道,然后进行大数据传输

Socket:建立两个端点:

// 发送端,接收端。应该放两个.java中。  (Udp) 运行哪个先无所谓
import java.net.*;

class  UdpSend
{
 public static void main(String[] args)throws Exception
 {

  //1,建立udp的socket服务。
  DatagramSocket ds = new DatagramSocket();

  //2,将数据封装成数据包。DatagramPacket(byte[] buf, int length, InetAddress address, int port)
  String str = "upd ge men lai le !";

  byte[] bys = str.getBytes();

  InetAddress ip = InetAddress.getByName("192.168.1.255");

  DatagramPacket dp = new DatagramPacket(bys,bys.length,ip,9527);

  //3,通过socket服务的send方法。将数据包仍出去。
  ds.send(dp);

  //4,关闭资源。
  ds.close();

 }
}

class UdpReceive
{
  public static void main(String[] args)throws Exception//接收端

   {   //建立socket服务,监听一个端口
         DatagramSocket ds=new DatagramSocket(9527);

      // 通过socket服务的receive方法,接收数据
          //建立一个数据包,用于存放数据,这样可以通过数据包的方法
                // 方便获取不同的数据信息
 
          byte[] buf=new byte[1024];
          DatagramPacket dp=new DatagramPacket(buf,buf.length);
             ds.receive(dp);

             String ip=dp.getAddress().getHostName();??//dp.getAddress() 返回的是对象InetAddress
          
   String data= new String(dp.getData(),0,dp.getLength()); ??//获取数据信息  第12课,好好研究一下。           
     
      int port=dp.getPort();

        System.out.println(ip+":"+port+"...."+data);
             ds.close();
   }
}


....................................................

 网络地址(网段地址)192.168.1.0
 广播地址:          192.168.1.255      (第二个视频(聊天程序))  结合I/O流 线程 (键盘录入)

                             一个线程负责接收,一个负责发送。同时进行
                             先启动服务端,再启动客户端

(Udp)聊天程序:

import java.net.*;
import java.i0.*;
class Send implements Runnable
{
   private DatagramSocket ds;
   send(DatagramSocket ds)
    {
      this.ds=ds;
    }
  public void run()
   {
       try
      {
        BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));
 
        String line=null;
      while((line=bufr.readLine())!=null)
        {
       if("886".equals(line))
           break;
       byte[] bys=line.getBytes();
       
           Datagram dp=new DatagramPacket(bys,bys.length,InetAddress,getByName("192.168.1.255"),10001);
         ds.send(dp);
        }
        ds.close();
      }
       catch(Exception e)
        {
           System.out.println(e.toString());
        }
    }
}
class Rece implements Runnable
{
     private DatagramSocket ds;
     Rece(DatagramSocket ds)
    {
          this.ds=ds;
    }
   public void run()
  {
        try
          {  
            while(true)
           {
       byte[] buf=new byte[1024];
            DatagramPacket dp=new DatagramPacket(buf,buf.length);

           ds.receive(dp);

          String data=new String(dp.getData(),0,dp.length());
            String ip=dp.getAddress().getHostAddress();

        System.out.println(ip+":::"+data);
           }
      }
    catch(Exception e) 
     {
        System.out.println(e.toString());
     }
   }
}
class ChatDemo
{
  public static void main(String[] args)throws IOException
   {
        DatagramSocket s=new DatagramSocket();
       DatagramSocket r=new DatagramSocket(10001);

        new Thread(new Send(s)).start();
        new Thread(new Rece(r)).start();


   }
}

.....................................................................

 
 tcp:                
import java.net.*;
import java.io.*;

class Client
{
 public static void main(String[] args) throws Exception
 {

  //1,建立客户端socket服务。
  Socket s = new Socket("192.168.1.254",10002);

  //2,获取socket中的输出流。
  OutputStream out = s.getOutputStream();

  out.write("tcp ge men you lai le ".getBytes());


  InputStream in = s.getInputStream();

  byte[] buf = new byte[1024];
  int len = in.read(buf);

  System.out.println(new String(buf,0,len));

  s.close();
 }
}


class  Server
{
 public static void main(String[] args) throws Exception
 {
  //1,建立服务端socket对象,必须要监听一个端口。

  ServerSocket ss = new ServerSocket(10002);

  //2.通过socket服务获取客户端对象通过accept方法。
  Socket s = ss.accept();

  String ip = s.getInetAddress().getHostAddress();
  System.out.println(ip+"....connect");

  //3,通过获取的客户端对象,获取读取流读客户端发来的数据。
  InputStream in = s.getInputStream();

  byte[] buf = new byte[1024];

  int len = in.read(buf);

  System.out.println(new String(buf,0,len));

  OutputStream out = s.getOutputStream();

  out.write("shou dao !".getBytes());  // 参考第二个视频的图15分钟


  s.close();
  ss.close();
 }
}

....................................................................

 udp
网络编程:

   /*

udp的通讯:就好像是邮递包裹,或者步话机,只需要发,只需要收就可以
*/
发送端思路:
1建立UDP的SOCKET服务
2将数据封装成数据包,并在包中指定目的地址和端口
3通过SOCKET服务的SEND方法将数据发出
4关闭SOCKET资源

 DatagramSocket ds=new DatagramSocket();

 byte[] arr="data hen duo".getBytes();

  DatagramPacket dp=new DatagramPacket(arr,arr.length,InetAddress.getByName("192.168.1.254"),10000)

ds.send(dp);

ds.close()

接收端思路:

   1建立UDP的SOCKET服务,并监听一个端口
   2为了获取数据中的分类信息,包括源地址,数据主体
    先定义好了一个数据包,将字节数组作为缓冲区封装到了数据包
  对象中
   3通过SOCKET服务的RECEIVE方法,将收到的数据存入到数据包中
   4通过数据包的方法获取数据包中不同类别的数据
   5关闭资源(视情况而定)

    DatagramSocket ds= new Datagram(10000);

   byte[] buf=new byte[1024];

  DatagramPacket dp=new DatagramPacket(buf,buf.length);

    ds.receive(dp);//接收方法是阻塞式的,(没数据就等)
 
  String ip=dp.getAddress().getHostAddress();

   String data=new String(dp.getData(),0,dp.getLength());

    int port =dp.getPort;

    System.out.println(ip+":"+data);

     ds.close();

..................................................
 
 客户端的思路
1建立客户端的SOCKET服务,通常指定目的地址和端口
2通过建立好的通道中的SOCKET流的读取和写入对象对数据
 进行操作
3关闭客户端

   Socket s=new Socket("192.168.1.254",10002);

    OutputStream out=s.getOutputStream();//给服务端写东西

   out.write(  "tcp....".getBytes());

     InputStream in=s.getInputStream(); //服务端反馈的信息读出来

     byte[] buf=new byte[1024];

      int len=in.read(buf);

    System.out.println(new String(buf,0,len));
     s.close();

.............................

TCP的通讯:相当于打电话。
 服务端的思路
1 建立服务端的socket服务,需要监听一个端口
2通过accept方法获取客户端对象
3通过获取到的客户端对象的读取和写入流对象与
对应的客户端进行通讯
4关闭客户端,在关闭服务端(视情况而定)
   ServerSocket ss=new ServerSocket(10002);
  
    Socket s=ss.accept();
   InputStream in=s.getInputStream();    //读客户端发来的数据
        byte[]buf=new byte[1024];
    int len=in.read(buf);
   System.out.println(new String(buf,0,length));
    
     OutputStream out=s.getOutputStream();//回馈给客户端
       out.write("收到"  .getBytes());
   
    s.close(); //客户端是必须要关的

..............................................
web服务器原理:基于三项技术完成的
1,socket
2 多线程
3 I/O流

 import java.net.*;
class InetAddressDemo      //通过名字获取IP,通过IP获取名字
{
  public static void main(String[] args)throws Exception
  {
    InetAddress ipobj=InetAddress.getByName("192.168.1.254"); //告诉我地址,我告诉你对应的主机名称
    

   System.out.println("hostName"+ipobj.getHostName()); 如果不插网线,运行时,就是192.168.1.254 就不是主机名了

   
 InetAddress ipobj1=InetAddress.getByName("thinkpads1400"); //告诉主机名, 打印出IP地址

     System.out.println("ip:"+ipobj1.getHostAddress());
  }
}

  新浪
 
 InetAddress ipobj1=InetAddress.getByName("www.sina.com.cn"); //告诉主机名, 打印出IP地址
                                 新浪地址
     System.out.println("ip:"+ipobj1.getHostAddress());


Hosts文件配置中 乱配了新浪的IP,就永远到不了新浪了

自动把消息发到DNS服务器,


 System.out.println(InetAddress.getLocalHost()); 主机名和IP地址


...................................................................


/*
客户端发送数据到服务端,服务端将其转换大写发回客户端
*/
/*
将键盘录入的数据,通过socket输出流发送给服务端
同时,通过SOCKET读取流转成大写的数据
*/
import java.io.*;
import java.net.*;
class TransClient  //源是键盘,目的是SOCKET输出流   处理的都是字符
{
   public static void main(String[] agrs)throws Exception
   {
       Socket s=new Socket("192.168.1.168",10003); 

      BufferedReader bufr=new BufferedReader(new InputStreamReader(System.in));  //键盘输入    源
    BufferedWriter buout=new BufferedWriter(new OutputStream(s.getOutputStream()) ); // 输出流发送给服务端,所以目的是SOCKET输出流


   BufferedReader bufin=new BufferedReader(new InputStreamReader(s.getInputStream())); 读取流把服务端发来的数据 变成大写
     String line=null;
      while ((line=bufr.readLine())!=null)
        {
             if("over".equals(line)) //键盘录入定义结束标记,要不停步下来
                break;
         bufw.write(line);
        buout.newLine();
        bufout.flush();

        String bigStr=bufin.readLine();
         System.out.println("big:"+bigStr);

        }
      bufr.close();
       s.close();
   }
}
class TransServer //服务端
{
  public static void main(String[] args)
   {
     ServerSocket ss=new ServerSocket(10003);

      Socket s=ss.accept();
 
      BufferedReader bufin=new BufferedReader(new InputStreamReader(s.getInputStream()));//读一行

    BufferedWriter bufout=new BufferedWriter(new OutputStream(s.getOutputStream())); //读一行后,大写出去

   String line=null;
   while((bufin.readLine())!=null)
   {
         System.out.println("client"+line);
        bufOut.write(line.toUpperCase());
       bufout.newLine();
     bufout.flush();
 
   }

    s.close();
   ss.close();
  }
}
...............................................................................

反射:


   可以动态的获取指定类中的成员,以及建立指定类对象
  好处:提高了程序的扩展性

 张三李四等这些生活中的对象,可以通过Person类的形式对其进行描述

当class文件产生以后,这些class文件也是生活中的事物,那么对这些class

文件也可以进行描述,该描述对应的类就是Class。

在java中,每一个字节码文件都有一个与之对象的Class对象

不仅包括引用数据类型,也包括基本数据类型。int.class

String.class---->Class

Class class1=String.class

String s="abc";

Class class2=s.getClass();

Class class3=Class.forName("java.lang.String");

以上就是获取字节码文件的三种方式

字节码对象。Class

以前操作对象的时候用的是new关键字完成,并通过对象,成员方式进行调用

Person p = new Person();
1》先加载Person.class文件
2》对对象进行初始化
p.method();

现在可以通过字节码对象完成以上动作。
加载Person.class文件 获取 Person.class文件对象的Class对象
Class class = Class.forName("Person");
通过字节码文件对象,对指定类进行对象创建 并初始化
Person p = (Person)class.newInstance();
 
通过对象调用成员

类可以作为参数传递,那么方法也可以作为参数进行传递
因为方法存在于字节码文件内,所以可以通过Class对象获取字节码文件的内容
Method m = Class.getMethod("function",String.class);
m.invoke(p,"heihei");

类或者方法都可以作为参数传递  这样对开发有什么好处呢?

需求:设计一个主板,为了提高后期的扩展性,也就是为了后期提高电脑的功能,
对外提供PCI的接口。以方便电脑功能的扩展。
interface PCI{
 void open();
 void close();

}

class MainBoard{
 public void usePCI(PCI p){
  p.open();
  p.close();
 }
}

class MainBoardDemo{
 public static void main(String[] args){
 MainBoard mb = new MainBoard();
        mb.usePCI(new NetCard);
    }
}
class NetCard implements PCI{
 public void open(){
 System.out,println();
 public void close(){
 System.out,println();
 }
}

那么为了使用网卡,还需要一个步骤买就是在定义好的应用程序中,
建立网卡,并作为参数传入,那么就是对原有的程序进行修改,不利于程序的健壮性
可不可以在不修改原有程序的基础上,运行后期出现的这些子类对象呢?
这样后期的子类就不需要建立对象们只要将子类名称告知即可。
为了获取后期对象并在前期可以使用,就对外提供了一个配置文件,前期程序可以直接操作
该配置文件,后期的子类只要将子类名称存入配置文件即可,
这是就需要动态的获取指定类,并预先创建对象,就用到了反射机制,重新修改一下程序如下:
class MainBoardDemo{
 public static void main(String[] args){
  MainBoard mb  = new MainBoard();
  File f = new File("lianxi.txt");
  BufferedReader br = new BufferedReader(new FileReader(d));
  String s = br.readLine();
  Class c = Class.forName(s);
  PCI p = (PCI)c.newInstence();
  mb.usePCI(p);
}
}

.............................................................................


解析dom节点

1》.读取xml文件节点内容:
package cn.yj3g;
/**
 * <?xml version="1.0" encoding="utf-8" standalone="no"?>
<学生s>
 <学生 性别="男">
  <姓名>李四</姓名>
  <年龄>51</年龄>
 </学生>
 <学生 性别="女">
  <姓名>张三</姓名>
  <年龄>22</年龄>
 </学生>
</学生s>

结果:
begin..
性别: 男
学生名: 李四  年龄: 51
性别: 女
学生名: 张三  年龄: 22

 */
import java.io.*;
import javax.xml.parsers.*; //导入此类,为SUN所提供的XML解析器,包括DOM解析器和SAX解析器的实现
import org.w3c.dom.*; //此包中定义了w3c所制定的DOM接口。

public class TestDomRead {
 public static void main(String[] args) {
  System.out.println("begin..");
  DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); // 利和JAXP,建立一个解析器工厂
  DocumentBuilder db = null;
  try {
   // 利用解析器工厂的newDocumentBuilder方法获得一个DocumentBuilder对象,此对象代表了具体的DOM解析器
   db = dbf.newDocumentBuilder();
  } catch (ParserConfigurationException dbe) {
   System.out.print(dbe);
  }
  Document doc = null;
  try {
   try {
    // 利用解析器对文档进行解析.关联XML文档.返回的Document对象代表了对应在XML树模型
    doc = db.parse("F:\\files\\workspace\\xml\\links.xml");
    doc.normalize();//一个保存和加载的过程
   } catch (org.xml.sax.SAXException ex) {
    System.out.print(ex);
   }
  } catch (IOException e) {
   System.out.print(e);
  }
  try {
   // 利用Document的getElementsByTagName方法返回对应关键字所对应的树干列表
   NodeList nl = doc.getElementsByTagName("学生");//按文档顺序返回包含在文档中且具有给定标记名称的所有 Element 的 NodeList
   for (int i = 0; i < nl.getLength(); i++) {
    Element link = (Element) nl.item(i); // 类似于数组操作取返回列表的每一个值
    System.out.println("性别: "+link.getAttribute("性别"));//getAttribute取属性值
    System.out.print("学生名: " + link.getElementsByTagName("姓名").item(0).getFirstChild().getNodeValue());
//getElementsByTagName 取元素名称
    System.out.println("  年龄: " + link.getElementsByTagName("年龄").item(0).getFirstChild().getNodeValue());
   }
  } catch (Exception e) {
   System.out.print(e);
  }
 }
}

。。。。。。。。。。。。。。。。。。。。。。。

2》.package cn.yj3g;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
/**
 *
 * 在xml文件中添加节点对象
 <?xml version="1.0" encoding="utf-8" standalone="no"?><学生s>
 <学生 性别="男">
  <姓名>李四</姓名>
  <年龄>51</年龄>
 </学生>
 <学生 性别="女">
  <姓名>张三</姓名>
  <年龄>22</年龄>
 </学生>
<学生><姓名>张三</姓名><性别>男</性别></学生></学生s>   //添加的内容
 *
 */
public class TestDomWrite {
 public static void main(String[] args) {
  // 读入XML文件,建立DOCUMENT树
  DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
  DocumentBuilder builder = null;
  try {
   builder = factory.newDocumentBuilder();
  } catch (ParserConfigurationException bde) {
   System.out.println(bde);
  }
  Document doc = null;
  try {
   try {
    doc = builder.parse("F:\\files\\workspace\\xml\\links.xml");
   } catch (org.xml.sax.SAXException doe) {
    System.out.println(doe);
   }
  } catch (IOException e) {
   System.out.println(e);
  }
  doc.normalize();

  // 添加节点
  String text = "张三";
  String sex = "男";
  Text textseg;
  Text sexseg;

  Element link = doc.createElement("学生"); // 创建一个link对象,节点对象

  // 添加“姓名“字段
  Element linktext = doc.createElement("姓名");
  textseg = doc.createTextNode(text);// 创建给定指定字符串的 Text 节点
  linktext.appendChild(textseg);
  link.appendChild(linktext);

  // 添加“性别“字段
  Element linksex = doc.createElement("性别");
  sexseg = doc.createTextNode(sex);
  linksex.appendChild(sexseg);
  link.appendChild(linksex);

  doc.getDocumentElement().appendChild(link); // 把创建好的节点添加到DOM树中
  // 用XSLT把DOM树输出到流(文件)中
  TransformerFactory tFactory = TransformerFactory.newInstance();// 获取 TransformerFactory 的新实例。
  Transformer transformer = null;//Transformer: 将 XML Source 转换为 Result
  try {
   transformer = tFactory.newTransformer();
  } catch (TransformerConfigurationException te) {
   System.out.println(te);
  }
  DOMSource source = new DOMSource(doc);
  StreamResult result = new StreamResult(new File(
    "F:\\files\\workspace\\xml\\links2.xml"));
  try {
   // Transformer类的transfrom方法接受两个参数、一个数据源Source和一个输出目标Result
   transformer.transform(source, result);
  } catch (TransformerException tre) {
   System.out.println(tre);
  }
 }
}

。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

3》.
package cn.yj3g;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

//解析persons.xml生成一个Person类对象的集合
/*
 * <?xml version="1.0" encoding="UTF-8"?>
<persons>
 <person id="23">
  <name>liming</name>
  <age>30</age>
 </person>
 <person id="20">
  <name>zhangxiaoxiao</name>
  <age>25</age>
 </person>
 <person id="25">
  <name>feifei</name>
  <age>21</age>
 </person>
</persons>

结果:
-------startDocument--------
-------startElement--------++--persons
-------characters--------
 
-------startElement--------++--person
-------characters--------
  
-------startElement--------++--name
-------characters--------liming
-------endElement--------++--name
-------characters--------
  
-------startElement--------++--age
-------characters--------30
-------endElement--------++--age
-------characters--------
 
-------endElement--------++--person
-------characters--------
 
-------startElement--------++--person
-------characters--------
  
-------startElement--------++--name
-------characters--------zhangxiaoxiao
-------endElement--------++--name
-------characters--------
  
-------startElement--------++--age
-------characters--------25
-------endElement--------++--age
-------characters--------
 
-------endElement--------++--person
-------characters--------
 
-------startElement--------++--person
-------characters--------
  
-------startElement--------++--name
-------characters--------feifei
-------endElement--------++--name
-------characters--------
  
-------startElement--------++--age
-------characters--------21
-------endElement--------++--age
-------characters--------
 
-------endElement--------++--person
-------characters--------

-------endElement--------++--persons
-------endDocument--------
Person [id=23, name=liming, age=30]
Person [id=20, name=zhangxiaoxiao, age=25]
Person [id=25, name=feifei, age=21]
 */
public class TestSax {

 private static List<Person> list;
 private static Person p;
 private static String currentNode = "";

 public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
  SAXParserFactory factory = SAXParserFactory.newInstance();
  SAXParser parser = factory.newSAXParser();
  parser.parse(new File("F:\\files\\workspace\\xml\\persons.xml"), new MyHandler());
  for(Person p : list) {
   System.out.println(p);
  }
 }

 static class MyHandler extends DefaultHandler {

  @Override
  public void startDocument() throws SAXException {
   System.out.println("-------startDocument--------");//开始接收文档
   list = new ArrayList<Person>();
  }

  @Override
  public void endDocument() throws SAXException {
   System.out.println("-------endDocument--------");// 接收文档结束的通知。
   super.endDocument();
  }

  @Override
  public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
   System.out.println("-------startElement--------" + uri + "++" + localName + "--" + qName);// 接收元素结束的通知
   if ("persons".equals(qName)) {

   } else if ("person".equals(qName)) {
    p = new Person();
    p.setId(Integer.valueOf(attributes.getValue("id")));
   } else if ("name".equals(qName)) {
    currentNode = "name";
   } else if ("age".equals(qName)) {
    currentNode = "age";
   }
   super.startElement(uri, localName, qName, attributes);
  }

  @Override
  public void endElement(String uri, String localName, String qName) throws SAXException {
   System.out.println("-------endElement--------" + uri + "++" + localName + "--" + qName);
   if ("persons".equals(qName)) {
    
   } else if ("person".equals(qName)) {
    list.add(p);
   } else if ("name".equals(qName)) {
    currentNode = "";
   } else if ("age".equals(qName)) {
    currentNode = "";
   }
  }

  @Override
  public void characters(char[] ch, int start, int length) throws SAXException {
   System.out.println("-------characters--------" + new String(ch, start, length));//接收元素中字符数据的通知。
   String s = new String(ch, start, length);
   if (currentNode.equals("name")) {
    p.setName(s);
   } else if (currentNode.equals("age")) {
    p.setAge(new Integer(s));
   }
  }

 }
}

class Person {
 private int id;
 private String name;
 private int age;

 public Person() {
  super();
 }

 public Person(int id, String name, int age) {
  super();
  this.id = id;
  this.name = name;
  this.age = age;
 }

 public int getId() {
  return id;
 }

 public void setId(int id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public int getAge() {
  return age;
 }

 public void setAge(int age) {
  this.age = age;
 }

 @Override
 public String toString() {
  return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
 }
}

原文地址:https://www.cnblogs.com/limingblogs/p/2199193.html