JAVASE高级2

照概述

三元移动今天初步,凡是参加张家界陈峰旅游路套餐都不过享用本客栈免费入住一晚!

咦是反光?

一、省钱

  反射的底概念是发出smith1982年篇糟提出的,zhuy主要是依程序可以看、检测与改动它本身状态或行为的一样种植力量。

1、选择张家界当地自助游,省去层层转包、层层盘扣。

  JAVA反射机制是运转状态被,对于随意一个接近,都能领略是看似的装有属性和法;对于随意一个靶,都能都调用它的随机一个智;

公所当的地方旅行社,实际并无是你们的旅游服务者,简单的说就是一个出游服务中介商,他们同您订旅游服务合同后,一转身就转包给张家界市神州旅行社有限责任公司来具体操作、这个邪是抢手的观光行业潜规则。

这种动态获取之音及动态调用对象的艺术的效能称为Java语言的照机制。

俗话说得好:一分钱一分货,一私分价钱一样私分服务。您当张家界出境游的资费,经地方旅行社的抽成后再变更保约我们张家界之旅行社,价钱压低,服务得是针对顶的。如果直接选择张家界之自助游,省去中间用,同样的价钱,肯定是强格调之劳动。当您在张家界享受旅游服务经常,因中的传言等元素,导致更多单性化服务无法顺利开展,因而起旅游之无开心。

  简单的话,反射机制指的凡先后于运作时能得到自我的音信。在JAVA中,只要吃定类的名,那么即便得经反射机制来抱接近的有所信息。

探望去层层转包的优势:

概括其访问修饰符、父类、实现之接口、属性与法的保有消息,并而当运作时创建对象、修改属性(包括个人的)、调用方法(包括个人的)。

一致的标价:我们再次亲近与宏观

缘何要因此反射机制?直接创建对象不就是足以了么?这就关乎到了动态和静态的概念?

无异于的劳动:我们还规范。

  静态编译:在编译时规定项目,绑定队形,即透过。

亚、品质(真正的享用品质旅游)

       Student stu = new
Student(“zhangsan”,20);

咱懂得,旅游的值为饱满感受为主,物质上面的要求,并无是潜移默化游览品质之机要元素。我们推崇诚信旅游,以信息透明吗核心标准,对游客的吃、住、行、游、购、娱开诚布公、信息透明、自由选择,让游人真正的享受张家界的大格调旅游。

  动态编译:运行时规定项目,绑定对象。动态编译最老限度发挥了java的油滑,体现了多态的运用,用以降低类之间的耦合性。

自恃:明确不同标准的食谱,供游人选择;不限量扣餐饮费,做到菜色荤素搭配合理。

       Class.forName(“com.mysql.jdbc.Driver.class”).newInstance();

停下:明确规范,住宿标准可大可没有,应该肯定信息的措辞,对于酒吧的名目、位置、标准,都使产生显而易见的验证。

  一词话,反射机制的亮点就是是可兑现动态创建对象以及编译,体现出非常特别的八面玲珑,特点是于J2EE的付出被。

执行:绝不做低价竞争、零车费团队,用车正式明显,车容整洁、卫生,高标准。

  它的老毛病是对性能有影响。使用反射基本上是同种植说操作,这仿佛操作总是慢于直接执行的同一操作。

逛:防止行程空虚,杜绝进入大回扣低质量的景。行程安排含金量高,设计极端有价的路线于游人,安排成立、游览时充裕。(比如张家界国家森林公园景点配备,目前之过多集体,只交天子山,不错过袁家界。而袁家界的景物也是全部森林公园名最有特色之。这里没呀门票上的歧异,只是岁月问题。因为健康行程受,要抽出一定的时空安排购物以及自费项目,就减少行程,让远道而来之游客,根本欣赏不顶绝值得看的景致。)

Java反射机制重大提供了以下功能

进:杜绝质量差、品质假、价格虚之小卖部;推荐好东西、好局,货真价实;购物绝不影响健康游览。合同中如随便购物进店说明,绝对无购物!!

  以运作时判断任意一个对象所属之近乎

打:对得地方政府的不竭支持以及包装,地方特色浓郁的,确有价之游玩类,比如达中央春晚的“张家界魅力湘西”以及“天门狐仙”等,都见面以健康诚恳的花样引进给游客,以供自由选择。

  在运转时构建任意一个像样的目标

咱深受你承诺:

  在运转时判断任意一个接近所怀有的积极分子变量和章程

咱们的出境游报价清晰,让您花之每一样私分钱,都亮花在证实地方,在观光路方面我们靠网络优势,将行程细致化,每个景区都配起连锁的图片,任何景观和劳动内容都详细说明,让您明白消费,清楚旅程,开心出游。

  以运作时调用任意一个对象的艺术

张家界陈峰自助游旅游顾问罗阿妹:张家界陈峰自助游俱乐部旅游顾问罗阿妹13907448515,找到了阿妹

Class对象是Reflection故事出自。要想操纵类中的性质和方,都须由落Class对象开始

  类是程序的同一有的,每个接近都出一个Class对象。换言之,每当编写而编译一个新类,就见面出和的相应之一个Class对象。

  Class类没有国有的构造方法。Class对象实际加载类时由JAVA虚拟机以及通过类似加载器中之方式自动构造之,因此不能够显示地声称一个Class对象

取Class对象的办法发出多种

 

图片 1图片 2

 1 package com.ab.tzy;
 2 
 3 public class ClassDemo {
 4 public static void main(String[] args) {
 5     // 对像名.getClass()
 6     // Class<?> getClass() 返回此 Object 的运行时类。 
 7     Employee employee = new Employee("zhangsan",15);
 8     Class<?> classType = employee.getClass();
 9     //String getName() 以 String 的形式返回此 Class 对象所表示的实体(类、接口、数组类、基本类型或 void)名称。 
10     System.out.println(classType.getName());//com.ab.tzy.Employee
11     //Class<? super T> getSuperclass() 返回表示此 Class 所表示的实体(类、接口、基本类型或 void)的超类的 Class。 
12     System.out.println(classType.getSuperclass().getName());//java.lang.Object
13     
14     //类名.class
15     Class<?> classType1 = Employee.class;
16     System.out.println(classType1.getName());//com.ab.tzy.Employee
17     System.out.println(classType1.getSuperclass().getName());//java.lang.Object
18     
19     //使用Class.forName();
20     //static Class<?> forName(String className)  返回与带有给定字符串名的类或接口相关联的 Class 对象。 
21     try {
22         Class<?> classType2=Class.forName("com.ab.tzy.Employee");
23         System.out.println(classType2.getName());//com.ab.tzy.Employee
24         System.out.println(classType2.getSuperclass().getName());//java.lang.Object
25     } catch (ClassNotFoundException e) {
26         e.printStackTrace();
27     }
28     //获取基本数据类型的Class对象
29     Class<?> classType3 = int.class;
30     System.out.println(classType3.getName());//int
31     //System.out.println(classType3.getSuperclass().getName());
32     // java.lang.NullPointerException
33     //通过基本数据类型的包装类来获取对应的基本数据类型所对应的Class对象
34     
35     //static Class<Integer> TYPE  表示基本类型 int 的 Class 实例。 (基本数据类型包装类都有该属性)
36     Class<?> classType4 = Integer.TYPE;
37     System.out.println(classType4.getName());//int
38     //System.out.println(classType4.getSuperclass().getName());
39     // java.lang.NullPointerException
40     
41     Class<?> classType5 = Integer.class;
42     System.out.println(classType5.getName());//java.lang.Integer
43     System.out.println(classType5.getSuperclass().getName());//java.lang.Number(除了character都是)
44     Class<?> classType6 = String.class;
45     System.out.println(classType6.getName());//java.lang.String
46     System.out.println(classType6.getSuperclass().getName());//java.lang.Object
47     Class<?> classType7 = Character.class;
48     System.out.println(classType7.getName());//java.lang.Character
49     System.out.println(classType7.getSuperclass().getName());//java.lang.Object
50     
51 }
52 }
53 
54 
55 class Employee{
56     private String name;
57     private int age;
58     public Employee(String name, int age) {
59         super();
60         this.name = name;
61         this.age = age;
62     }
63     public String getName() {
64         return name;
65     }
66     public void setName(String name) {
67         this.name = name;
68     }
69     public int getAge() {
70         return age;
71     }
72     public void setAge(int age) {
73         this.age = age;
74     }
75     
76 }

照入门

 Java.lang.reflect库

Class类与java.lang.reflect类库一起对准反射的定义进行支持。

Java.lang包下

  Class<T>:表示一个正在运转的Java应用程序中之近乎与接口,是Reflection的来自

Java.lang.reflect包下:

  Field类:代表类的成员变量(成员变量也称为类的性能)。

  Method类:代表类的措施。

  Constructor类:代表类的构造方法.

  Array类:提供了动态创建数组,以及走访数组的要素的静态方法。

经过反射实例化对象

凡情况咱通过new
Object来大成一个类的实例,但有时我们无奈直接new,只能通过反射动态变化。

实例化无参构造函数的目标,两种方法:

  Class.newInstance();

  Class.getConstructor(new Class[]{}).newInstance(new Object[]{})

实例化带参构造函数的靶子

  clazz.getConstructor(Class<?>…parameterTyprs).newInstance(Object…initargs)

透过反射获取并调用方法

取当前仿佛以及超类的public
Method

  Method[] arrMethods = classType.getMethodes();

获当前相仿申明的有着Method

  Method[] arrMethods = classType.getDeclaredMethodes();

抱当前好像及超类指定的public
Method

  Method[] arrMethod = classType.getMethode(String
name,Class<?>…parameterTypes);

落当前看似申明的指定的Method

  Method[] arrMethod = classType.getDeclaredMethode(String
name,Class<?>…parameterTypes);

通过反射动态运行指定Method

  Object obj = method.invoke(Object obj,Object…args);

 通过反射获取并调用属性

赢得当前相仿以及超类的public
Field

  Field[] arrFields = classType.getFields();

获取当前类似申明的具有Field

    Field[] arrFields = classType.getDeclaredFields();

收获当前好像与超类指定的public Field

  Field[] arrField = classType.getField();

得当前相近申明的指定的Field

  Field[] arrField = classType.getDeclaredFields();

透过反射动态设定Field的价值

  Field.set(Object obj,Object value)

 通过反射动态获取Field的价

  Object obj = field.get(Object obj);

图片 3图片 4

  1 package com.ab.tzy;
  2 
  3 import java.lang.reflect.Constructor;
  4 import java.lang.reflect.Field;
  5 import java.lang.reflect.Method;
  6 
  7 public class ReflectionAPIDemo {
  8     public static void main(String[] args) throws Exception {
  9         // 获取Employee这个类所关联的Class对象
 10         Class<?> classType = Class.forName("com.ab.tzy.Employee");
 11         // 通过反射机制来构造一个Employee的实例对象
 12         // T newInstance() 创建此 Class 对象所表示的类的一个新实例。 (Class)
 13         Object newInstance = classType.newInstance();
 14         Employee employee = (Employee) newInstance;
 15         // java.lang.InstantiationException默认调用无参构造方法,如果雇员类里面没有无参就会包实例化异常
 16         System.out.println(employee);// Employee [name=null, age=0]
 17 
 18         // 调用指定的构造方法来构造对象(无参构造方法)
 19         // Constructor<T> getConstructor(Class<?>... parameterTypes)
 20         // 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。 (Class)
 21         Constructor<?> constructor = classType.getConstructor(new Class[] {});
 22         // T newInstance(Object... initargs)
 23         // 使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。
 24         // (Constructor)
 25         Object newInstance2 = constructor.newInstance(new Object[] {});
 26         Employee employee2 = (Employee) newInstance2;
 27         System.out.println(employee2);// Employee [name=null, age=0]
 28 
 29         // 调用指定的构造方法来构造对象(无参构造方法)
 30         // Constructor<T> getConstructor(Class<?>... parameterTypes)
 31         // 返回一个 Constructor 对象,它反映此 Class 对象所表示的类的指定公共构造方法。 (Class)
 32         Constructor<?> constructor3 = classType.getConstructor(new Class[] {String.class,int.class});
 33         // T newInstance(Object... initargs)
 34         // 使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例。
 35         // (Constructor)
 36         Object newInstance3 = constructor3.newInstance(new Object[] {"张三",30});
 37         Employee employee3 = (Employee) newInstance3;
 38         System.out.println(employee3);// Employee [name=张三, age=30]
 39 
 40         //获取Class对象所指定的所有方法,包括私有的
 41         // Method[] getDeclaredMethods() 返回 Method 对象的一个数组,
 42         // 这些对象反映此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。 (Class)
 43         // Method[] getMethods() 返回一个包含某些 Method 对象的数组,这些对象反映此 Class 对象
 44         //所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。  (Class)
 45         System.out.println("*****");
 46         Method[] methods = classType.getDeclaredMethods();
 47         for (Method method : methods) {
 48              //String getName()  以 String 形式返回此 Method 对象表示的方法名称。 
 49             //int getModifiers() 以整数形式返回此 Method 对象所表示方法的 Java 语言修饰符。 
 50             // Class<?> getReturnType()  返回一个 Class 对象,该对象描述了此 Method 对象所表示的方法的正式返回类型。 
 51             System.out.println(method.getName()+"--"+method.getModifiers()+"--"+method.getReturnType());
 52         }
 53                 /*
 54                 toString--1--class java.lang.String
 55                 getName--1--class java.lang.String
 56                 setName--1--void
 57                 eat--2--class java.lang.String
 58                 work--2--void
 59                 setAge--1--void
 60                 getAge--1--int
 61                 work1--0--void
 62                 work2--4--void
 63                 */
 64         System.out.println("*****");
 65         
 66         //获取Class对象所指定的方法,包括私有
 67         // Method getDeclaredMethod(String name, Class<?>... parameterTypes) 
 68         //返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。 (Class)
 69         //获取Class对象所指定的方法,不包括私有
 70         // Method getMethod(String name, Class<?>... parameterTypes) 
 71         //返回一个 Method 对象,它反映此 Class 对象所表示的类或接口的指定公共成员方法。 (Class)
 72         Method method = classType.getMethod("toString", new Class[]{});
 73         //String toString()    返回描述此 Method 的字符串。 (Method)
 74         System.out.println(method);
 75         //public java.lang.String com.ab.tzy.Employee.toString()
 76         //String getName() 以 String 形式返回此 Method 对象表示的方法名称。 (Method)
 77         System.out.println(method.getName());//toString
 78         Object desc = method.invoke(employee3, new Object[]{});
 79         System.out.println(desc);//Employee [name=张三, age=30]
 80         //方法的调用
 81         // Method getDeclaredMethod(String name, Class<?>... parameterTypes) 
 82         //返回一个 Method 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明方法。 (Class)
 83         Method method1 = classType.getDeclaredMethod("eat", new Class[]{String.class});
 84         // Object invoke(Object obj, Object... args) 
 85         //对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。 (Method)
 86         System.out.println(method1.getName());//eat
 87          //void setAccessible(boolean flag) 将此对象的 accessible 标志设置为指示的布尔值。
 88         //(method父类AccessibleObject的方法)
 89         method1.setAccessible(true);
 90         Object desc1 = method1.invoke(employee3, new Object[]{"拉拉"});
 91         System.out.println(desc1);//拉拉
 92         //java.lang.IllegalAccessException非法访问异常  必须要调用一个权限方法设置
 93         
 94         
 95         //获取Class对象所指定的属性,包括私有的
 96         Field field = classType.getDeclaredField("name");
 97         //void setAccessible(boolean flag) 将此对象的 accessible 标志设置为指示的布尔值。
 98         //(field父类AccessibleObject的方法和method共同的父类)
 99         field.setAccessible(true);
100         // void set(Object obj, Object value) 
101         //将指定对象变量上此 Field 对象表示的字段设置为指定的新值。 (Field)
102         field.set(employee3, "李四");
103         // String toString() 返回一个描述此 Field 的字符串。 (Field)
104         System.out.println(field);//private java.lang.String com.ab.tzy.Employee.name
105         // Object get(Object obj) 返回指定对象上此 Field 表示的字段的值。 (Field)
106         System.out.println(field.get(employee3));//李四
107         // Field getDeclaredField(String name) 
108         //返回一个 Field 对象,该对象反映此 Class 对象所表示的类或接口的指定已声明字段。 (Class)
109         
110         // Field[] getDeclaredFields() 
111         //返回 Field 对象的一个数组,这些对象反映此 Class 对象所表示的类或接口所声明的所有字段。 (Class)
112         
113         //  Field getField(String name) 返回一个 Field 对象,它反映此 Class 对象所表
114         //示的类或接口的指定公共成员字段。 (Class)
115         
116         // Field[] getFields()  返回一个包含某些 Field 对象的数组,这些对象反映此 Class 对象所表
117         //示的类或接口的所有可访问公共字段。 (Class)
118         
119     }
120 }
121 
122 class Employee {
123     private String name;
124     private int age;
125 
126     public Employee() {
127         super();
128     }
129 
130     public Employee(String name, int age) {
131         super();
132         this.name = name;
133         this.age = age;
134     }
135 
136     public String getName() {
137         return name;
138     }
139 
140     public void setName(String name) {
141         this.name = name;
142     }
143 
144     public int getAge() {
145         return age;
146     }
147 
148     public void setAge(int age) {
149         this.age = age;
150     }
151 
152     @Override
153     public String toString() {
154         return "Employee [name=" + name + ", age=" + age + "]";
155     }
156     private String eat(String s){
157         return s;
158     }
159     private void work(){
160         System.out.println("我要工作---私有");
161     }
162     void work1(){
163         System.out.println("我要工作---默认");
164     }
165     protected  void work2(){
166         System.out.println("我要工作---保护");
167     }
168 }

照常用

图片 5图片 6

 1 package com.abc.tzy;
 2 
 3 import java.lang.reflect.Array;
 4 
 5 public class ArrayDemo {
 6     public static void main(String[] args) throws Exception {
 7         //创建一个一维数组(String)
 8         Class<?> classType = Class.forName("java.lang.String");
 9         //static Object         newInstance(Class<?> componentType, int length) 
10         //创建一个具有指定的组件类型和长度的新数组。 (Array)
11         Object array = Array.newInstance(classType, 5);
12         //static void             set(Object array, int index, Object value) 
13         //将指定数组对象中索引组件的值设置为指定的新值。 
14         Array.set(array, 3, "abc");
15         //static Object get(Object array, int index) 
16         //返回指定数组对象中索引组件的值。 
17         //System.out.println(Array.get(array, 5));
18         // java.lang.ArrayIndexOutOfBoundsException
19         System.out.println(Array.get(array, 3));//abc
20         
21         //创建一个二维数组(3行3列)
22         //static Object newInstance(Class<?> componentType, int... dimensions) 
23         //创建一个具有指定的组件类型和维度的新数组。 
24         int [] dimens={3,3};
25         Object array1 = Array.newInstance(int.class, dimens);
26         Object arrayobj = Array.get(array1, 2);//获取第三行(就是一个一维数组)
27         //static void setInt(Object array, int index, int i) 
28         //将指定数组对象中索引组件的值设置为指定的 int 值。 (基本数据类型方法相似)
29         Array.setInt(arrayobj, 2, 10);//给指定数组位置的元素赋新值
30         int [] [] arr = (int[][]) array1;
31         for (int[] is : arr) {
32             for (int i : is) {
33                 System.out.print(i+"\t");
34             }
35             System.out.println();
36         }
37         //0       0      0    
38         //0    0    0    
39         //0    0    10    
40 
41     }
42 }

映创建数组

映总结

比方使用反射,先抱Class对象。

从没章程会博得当前接近的超类的private方法以及性,你要通过getSuperclass()找到超类以后还去品味取

通常状态便是当下看似,private属性或方法吗是不能够访问的,你用设置压制权限setAccessible(true)来赢得private的访问权。但说实话,这已损坏了面向对象的规则,

就此除非万不得已,请尽可能少用。

图片 7图片 8

  1 package com.abc.tzy;
  2 
  3 import java.lang.reflect.Field;
  4 import java.lang.reflect.InvocationTargetException;
  5 import java.lang.reflect.Method;
  6 
  7 public class ReflectionDemo {
  8     public static void main(String[] args) {
  9         // 2生成一个学生对象(被赋值的哪个对象,源对象)
 10         Student stu = new Student(1, "张三", 30);
 11         try {
 12             Student copystu = (Student) ObjectCopyUtil.copyObj(stu);
 13             System.out.println("复制对象成功");
 14             System.out.println(copystu);
 15         } catch (InstantiationException e) {
 16             e.printStackTrace();
 17         } catch (IllegalAccessException e) {
 18             e.printStackTrace();
 19         } catch (NoSuchMethodException e) {
 20             e.printStackTrace();
 21         } catch (SecurityException e) {
 22             e.printStackTrace();
 23         } catch (IllegalArgumentException e) {
 24             e.printStackTrace();
 25         } catch (InvocationTargetException e) {
 26             e.printStackTrace();
 27         }
 28     }
 29 }
 30 
 31 //复制对象成功
 32 //Student [id=1, name=张三, age=30]
 33 
 34 
 35 /**
 36  * 这是一个Copy对象的工具类,内部提供了一个Copy对象的方法,接受源对象
 37  * 
 38  * @author Administrator
 39  *
 40  */
 41 class ObjectCopyUtil {
 42     public static Object copyObj(Object obj) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
 43         // 3获取Student对象所对应类型的Class对象(也就是Student这个类所对应的Class对象)
 44         Class<?> classType = obj.getClass();
 45         // 4通过Class对象的newInstance方法构建一个目标对象。
 46         Object objRes = classType.newInstance();
 47         // 5获取Class对象的set和get方法
 48         Field[] fields = classType.getDeclaredFields();
 49         for (Field field : fields) {
 50             
 51             // 得到属性所对应的get和set方法
 52             // String substring(int beginIndex) 返回一个新的字符串,它是此字符串的一个子字符串。
 53             // String substring(int beginIndex, int endIndex)
 54             // 返回一个新字符串,它是此字符串的一个子字符串。
 55             // String toUpperCase() 使用默认语言环境的规则将此 String 中的所有字符都转换为大写。
 56             // String toLowerCase() 使用默认语言环境的规则将此 String 中的所有字符都转换为小写。
 57             String getMethodName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);// 拼接getId
 58             String setMethodName = "set" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);// 拼接SetId
 59             //调用源对象的get方法获取属性值
 60             Method getMethod = classType.getDeclaredMethod(getMethodName, new Class[]{});//方法名 参数
 61             Object value = getMethod.invoke(obj, new Object[]{});
 62             //调用源对象的set方法给属性赋值
 63             // Class<?> getType()  返回一个 Class 对象,它标识了此 Field 对象所表示字段的声明类型。 
 64             Method setMethod = classType.getDeclaredMethod(setMethodName, new Class[]{field.getType()});//参数类型就是属性的类型
 65             setMethod.invoke(objRes, new Object[]{value});
 66             /*
 67             //方法二:
 68             field.setAccessible(true);
 69             // Object get(Object obj) 返回指定对象上此 Field 表示的字段的值。 
 70             Object value1 = field.get(obj);
 71             // void set(Object obj, Object value) 将指定对象变量上此 Field 对象表示的字段设置为指定的新值。 
 72             field.set(objRes, value1);
 73             */
 74         }
 75         return objRes;
 76     }
 77 }
 78 
 79 // 1申明一个学生类
 80 class Student {
 81     private int id;
 82     private String name;
 83     private int age;
 84 
 85     public Student(int id, String name, int age) {
 86         super();
 87         this.id = id;
 88         this.name = name;
 89         this.age = age;
 90     }
 91 
 92     public int getId() {
 93         return id;
 94     }
 95 
 96     public void setId(int id) {
 97         this.id = id;
 98     }
 99 
100     public String getName() {
101         return name;
102     }
103 
104     public void setName(String name) {
105         this.name = name;
106     }
107 
108     public int getAge() {
109         return age;
110     }
111 
112     public void setAge(int age) {
113         this.age = age;
114     }
115 
116     public Student() {
117         super();
118     }
119 
120     @Override
121     public String toString() {
122         return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
123     }
124 
125 }

经过反射赋值对象

 

线程模式

哎呀是次:

  安装于磁盘上之同段落指令集合,它是静态的概念。

嘿是经过:

  它是运作中之主次,是动态的定义。每个过程都发独立的资源空间。

哎呀是线程:

  线程,又称之为轻量级进程,是程序执行流的极度小单元,是次中一个纯的顺序控制流程。线程是过程面临的一个例子,是受网独立调度以及分担的为主单位。

咦是多线程:

  多线程则凭的凡以单个程序中得以运转多单不同的线程执行不一之天职。

差不多线程的特点:

  一个序可以蕴涵一个或多单线程。

  一个程序实现多只代码同时交替运行就待发多独线程。

  线程本身不备系统资源,与同属一个进程的另线程共享所在经过所怀有的资源。

  同一进程被的基本上单线程之间可并作执行。CPU会轻易抽出事件,让咱们的次序一样会做这桩工作,一会举行另外一样桩业务。

大多线程的目的:

  就是“最深限度地采用CPU资源”,当有一样线程的拍卖不欲占用CPU而仅同I/O等资源打交道时,让急需占用CPU资源的其余线程有机遇赢得CPU资源。

从根本上说,这即是多线程编程的目的。

JAVA运行网以博点依赖让线程,所有的类库设计还考虑到几近线程。JAVA是纯面向对象语言,JAVA的线程模型呢是面向对象的。

线程模型

经过持续Thread类创建线程

  普通JAVA类设继续自Thread类,就改为一个线程类,并可通过此类的start方法来启动线程,执行线程代码。

  Thread类的子类可径直实例化,但以子类中得覆盖run方法才会真正运行线程的代码。

图片 9图片 10

 1 package com.abc.tzy;
 2 
 3 public class HelloThreadDemo {
 4 public static void main(String[] args) {
 5     Thread thread1 = new HelloThread("a");
 6     //void setName(String name) 改变线程名称,使之与参数 name 相同。 
 7     //thread1.setName("线程1");
 8     thread1.start();
 9     Thread thread2 = new HelloThread();
10     thread2.setName("线程2");
11     thread2.start();
12 }
13 }
14 
15 
16 class HelloThread extends Thread{
17     public HelloThread(String name){
18         super(name);
19     }
20     public HelloThread(){
21         super();
22     }
23     @Override
24     public void run() {
25         for (int i = 0; i < 5; i++) {
26             // String getName()  返回该线程的名称。 
27             System.out.println(this.getName()+":"+i);
28         }
29     }
30 }

extends—>Thread

通过实现Runnable接口创建线程

  贯彻Runnable借口的接近必须借助Thread类才会创造线程。通过Runnable接口创建线程分为两步:

    创建实现Runnable接口的切近的实例。

    创建一个Thread类对象,将第一步实例化得到的Runnable对象作为参数传入Thread类的构造方法。

  通过Thread类的start方法启动线程

图片 11图片 12

 1 package com.abc.tzy;
 2 
 3 public class RunnableDemo {
 4 public static void main(String[] args) {
 5     HelloRunnable helloRunnable = new HelloRunnable();
 6     Thread t1 = new Thread(helloRunnable,"A");
 7     t1.start();
 8     Thread t2 = new Thread(helloRunnable,"B");
 9     t2.start();
10 }
11 }
12 //避免单继承的局限,一个类可以实现多个接口,但只能继承一个类
13 //适合资源的共享
14 class HelloRunnable implements Runnable{
15 
16     @Override
17     public void run() {
18         for (int i = 0; i < 5; i++) { 
19             //static Thread     currentThread() 返回对当前正在执行的线程对象的引用。 
20             System.out.println(Thread.currentThread().getName()+":"+i);
21         }
22     }
23 }

implements–>Runnable

 

图片 13图片 14

 1 package com.abc.tzy;
 2 
 3 public class SharedDataThreadDemo {
 4 public static void main(String[] args) {
 5     TicketThread s1 = new TicketThread("一号窗口");
 6     s1.start();
 7     TicketThread s2 = new TicketThread("二号窗口");
 8     s2.start();
 9 }
10 }
11 
12 
13 class TicketThread extends Thread{
14     private static int ticket = 5;//加上static变成静态变量就可以实现卖五张
15     public TicketThread(String name){
16         super(name);
17     }
18     @Override
19     public void run() {
20         while(true){
21             System.out.println(this.getName()+":"+(ticket--));
22             if(ticket<1){
23                 break;
24             }
25         }
26     }
27 }

卖票Thread

图片 15图片 16

 1 package com.abc.tzy;
 2 
 3 public class SharedDataThreadDemo {
 4 public static void main(String[] args) {
 5     TicketRunnable run = new TicketRunnable();
 6     Thread t1 = new Thread(run, "一号窗口");
 7     t1.start();
 8     Thread t2 = new Thread(run, "二号窗口");
 9     t2.start();
10     
11 }
12 }
13 
14 //不需要设置静态变量就可以数据共享
15 class TicketRunnable implements Runnable{
16     private int ticket = 5;
17     @Override
18     public void run() {
19         while(true){
20             System.out.println(Thread.currentThread().getName()+":"+(ticket--));
21             if(ticket<1){
22                 break;
23             }
24         }
25     }
26 }

卖票Runnable

 

线程的生命周期

线程状态:

  以及人口的生老病死一样,线程野同样要更新建、就绪、运行(活动)、阻塞与长眠五栽不同之状态。这五栽状态还可以透过Thread类中的主意开展控制。

创并运行线程

  新建状态(New Thread)

    在JAVA语言中采用new操作符创建一个线程后,该线程仅仅是一个拖欠对象,它抱有了线程的片段特性,但这时网尚未啊其分配资源,这时的线程处于创建状态。

    线程处于创建状态时,可经过Thread类的法子来设置线程各种性能,如线程的优先级(setPriority)、线程名(setName)和线程的路(setDaemon)等。

  就绪状态(Runnable)

    使用start()方法启动一个线程后,系统吧该线程分配了除了CPU外之所用资源,使该线程处于就绪状态。此外,如果有线程执行了yield()方法,那么该线程会被临时

    剥夺CPU资源,重新入就绪状态。

  运转状态(Running)

    JAVA运行网经过调度选中一个介乎就绪状态的线程,使该占用CPU并转为运行状态。此时,系统真正实行线程的run()方法。

      可以透过Thread类的isAlive方法来判断线程是否处于就绪/运行状态:当线程处于就绪/运行状态时,isAlive返回true,当isAlive返回false时,可能线程处于阻塞状

      态,也或处于终止状态

  阻塞状态(Blocked)

    一个正周转的线程因某些原因未可知延续运行时,就进去阻塞状态。这个原因包括:

      当行了某个线程对象的sleep()等死类型的方时,该线程对象见面给置入一个绿灯集(Blocked
Pool)内,等待超时而自动苏醒。

      当多独线程试图进入某同步区域(synchronized)时,没能进入该旅区域的线程会吃置入锁定集(Lock
Pool),知道得该联合区域的吊,进入就绪状态。

      当线程执行了某个对象的wait()方法时,线程会于置入该目标的等待集(Wait
Pool)中,知道执行了该对象的notify()方法,wait()/notify()方法的实践要求线程首先取得到拖欠目标的沿

  呜呼状态(Dead)

    线程在run()方法执行了晚上死亡状态。此外,如果线程执行了interrupt()或stop()方法,那么它们为会见坐十分退出的法门上死亡状态。  

停下线程的老三种方法:

  运离标志,使线程正常退出,也就是是当run方法好后线程终止,推荐应用。

  使用stop方法强行终止线程(这个法不推荐下,因为stop和suspend、resume一样,也说不定出不可预料的结果)。

  使用interrupt方法中断线程。

线程同步

胡要共同

  线程同步是为防多单线程访问一个多少对象时,对数据造成损坏

  线程的旅是保险多线程安全访问竞争资源的同等种植手段。

联合同沿

  Java中每个对象还发一个内置锁。

  当程序运行到非静态的synchronized同步方法及经常,自动获得同在履行代码类的脚下实例(this实例)有关的缉;当程序运行到synchronized同步代码块常,自动获得锁定目标的吊。

  获得一个对象的缉也叫获取锁、锁定目标、在靶上锁定或者当靶及同。当程序运行到synchronized同步方法还是代码块常欠对象锁才于作用。

  一个目标仅发一个锁。所以,如果一个线程获得该锁,就没有另外线程可以得到锁,知道第一独线程释放锁。这也象征任何其它线程都不能够进synchronized方法或者代码块,知道该

  锁被放飞。释放锁是负持锁线程退出了synchronized同步方法还是代码块.

对同,一般而言在java代码中待做到两独操作:

  将竞争访问的资源标识为private。

  同步那些访问资源的代码,使用synchronized关键字来修饰方法或者代码块。当synchronized方法执行了要来很时,会自行释放锁。

看一下需:

  某银行卡帐号上生500头条现金。一个人口将在存折去取钱,同时另外一个人以在卡去ATM机上收获钱,各自赢得400处女。

  要求获取钱过程遭到莫可知出现资源竞争:比如400初次让得来片蹩脚、银行卡的账目不能够小于0等.

图片 17图片 18

 1 package com.abc.tzy;
 2 
 3 public class BankDemo {
 4     public static void main(String[] args) {
 5         Bank bank = new Bank();
 6         BankThread p1 = new BankThread(bank, "取钱人1");
 7         p1.start();// 柜台取钱
 8         BankThread p2 = new BankThread(bank, "取钱人2");
 9         p2.start();// ATM取钱
10 
11     }
12 }
13 
14 class BankThread extends Thread {
15     private Bank bank = null;
16 
17     public BankThread(Bank bank, String name) {
18         super(name);
19         this.bank = bank;
20     }
21 
22     @Override
23     public void run() {
24             System.out.println(this.getName()+"取钱:" + bank.getMoney(300));
25     }
26 
27 }
28 
29 class Bank {
30     private int money = 500;
31 
32     // 取钱的方法,返回取钱的数目
33     // 当一个线程去调用同步方法的时候,这个线程就获取了当前对象的锁。
34     // 其他线程当调用同步方法的时候,只能等待,因为无法获取对象的锁。
35     // 只有等第一个线程释放对象的锁方可进入.
36     //this 位置上可以换成任何对象,获取哪个对象的锁不影响
37     public /* synchronized */ int getMoney(int number) {
38         synchronized (this) {
39             if (number < 0) {
40                 return -1;
41             } else if (money < 0) {
42                 return -2;
43             } else if (money < number) {
44                 return -3;
45             } else {
46                 try {
47                     // static void sleep(long millis)
48                     // 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响。
49                     Thread.sleep(1000);// 模拟取钱的时间
50                 } catch (InterruptedException e) {
51                     e.printStackTrace();
52                 }
53                 money -= number;
54                 System.out.println("余额:" + money);
55             }
56             return number;
57         }
58     }
59 }

案例

 

合产生死锁的原故

  当一个线程已获得了对象1的沿,同时以想博得对象2底锁。而此时另一个线程当前一度怀有了靶二底锁,而以想取得对象1之沿。这种互动等待对方释放锁的长河,会导致死锁。

图片 19图片 20

 1 package com.abc.tzy;
 2 
 3 public class DieThreadDemo {
 4 public static void main(String[] args) {
 5     Example ex = new Example();
 6     DieThread1 die1 = new DieThread1(ex);
 7     die1.start();
 8     DieThread2 die2 = new DieThread2(ex);
 9     die2.start();
10 }
11 }
12 
13 class DieThread1 extends Thread{
14     private Example example = null;
15 
16     public DieThread1(Example example) {
17         super();
18         this.example = example;
19     }
20     @Override
21     public void run() {
22         example.method1();
23     }
24 }
25 class DieThread2 extends Thread{
26     private Example example = null;
27 
28     public DieThread2(Example example) {
29         super();
30         this.example = example;
31     }
32     @Override
33     public void run() {
34         example.method2();
35     }
36 }
37 
38 
39 class Example{
40     private Object obj1 = new Object();
41     private Object obj2 = new Object();
42     public void method1(){
43         synchronized (obj1){
44             try {
45                 Thread.sleep(1000);
46             } catch (InterruptedException e) {
47                 e.printStackTrace();
48             }
49             synchronized (obj2){
50                 System.out.println("method1");
51             }
52         }
53     }
54     public void method2(){
55         synchronized (obj2){
56             try {
57                 Thread.sleep(1000);
58             } catch (InterruptedException e) {
59                 e.printStackTrace();
60             }
61             synchronized (obj1){
62                 System.out.println("method2");
63             }
64         }
65     }
66 }

死锁

 线程通信

  Java提供了3独至关重要之方式巧妙的解决线程间的通信问题。这3只法子分别是:wait()、notify()、notifyAll()。(Object类)

  调用wait()方法可假设调用该办法的线程释放共享资源的锁,然后打运行状态退出,进入等列队,直到于重复提醒。

  调用notify()方法可以唤起等待队列中首先只待同一共享资源的线程,并而该线程退出等队列,进入可运行态。

  调用notifyAll()方法可以假设拥有在守候列队中一律共享资源的线程从等待状态退出,进入可运行状态,此时,优先级最高的那个线程可能会见最先执行。

 

图片 21图片 22

  1 package com.abc.tzy;
  2 
  3 import java.util.LinkedList;
  4 
  5 public class ProductorConsumerDemo {
  6 
  7     public static void main(String[] args) {
  8 
  9         Basket basket = new Basket();
 10         Productor productor = new Productor(basket);
 11         Consumer consumer = new Consumer(basket);
 12         productor.start();
 13         consumer.start();
 14     }
 15 
 16 }
 17 class Productor extends Thread{
 18     private Basket basket = null;
 19 
 20     public Productor(Basket basket) {
 21         super();
 22         this.basket = basket;
 23     }
 24     @Override
 25     public void run() {
 26         basket.pushApple();
 27     }
 28 }
 29 class Consumer extends Thread{
 30     private Basket basket = null;
 31 
 32     public Consumer(Basket basket) {
 33         super();
 34         this.basket = basket;
 35     }
 36     @Override
 37     public void run() {
 38         basket.popApple();
 39     }
 40 }
 41 //篮子类
 42 class Basket{
 43     private LinkedList<Apple> basket = new LinkedList<Apple>();
 44     //放4轮苹果
 45     public synchronized void pushApple(){
 46         for (int i = 0; i < 20; i++) {
 47             Apple apple = new Apple(i);
 48             push(apple);
 49         }
 50     }
 51     //吃4轮苹果
 52         public synchronized void popApple(){
 53             for (int i = 0; i < 20; i++) {
 54                 pop();
 55             }
 56         }
 57     //向篮子放苹果
 58     private void push(Apple apple){
 59         if(basket.size()==5){
 60             try {
 61                 wait();
 62             } catch (InterruptedException e) {
 63                 e.printStackTrace();
 64             }//等待并释放当前对象的锁
 65         }
 66         try {
 67             Thread.sleep(500);
 68         } catch (InterruptedException e) {
 69             e.printStackTrace();
 70         }
 71         basket.addFirst(apple);
 72         System.out.println("存放"+apple.toString());
 73         notify();//通知消费者来消费
 74     }
 75     //向篮子取苹果
 76         private void pop(){
 77             //当篮子中苹果数为0的时候就等待并通知生产者来生产
 78             if(basket.size()==0){
 79                 try {
 80                     wait();
 81                 } catch (InterruptedException e) {
 82                     e.printStackTrace();
 83                 }//等待并释放当前对象的锁
 84             }
 85             try {
 86                 Thread.sleep(500);
 87             } catch (InterruptedException e) {
 88                 e.printStackTrace();
 89             }
 90             Apple apple = basket.removeFirst();
 91             System.out.println("吃掉"+apple.toString());
 92             notify();//通知消费者来消费
 93         }
 94     
 95 }
 96 //苹果类
 97 class Apple{
 98     private int id;
 99     public Apple(int id){
100         this.id=id;
101     }
102     @Override
103     public String toString() {
104         return "苹果 :" + (id+1)+"号";
105     }
106     
107 }

劳动者消费者

 

IO框架

IO(Input/Output)是电脑输入/输出的接口。JAVA的主导库java.io提供了全方面的IO接口,包括:文件系统的操作,文件读写,标准配备出口等等

      java.io

    /   |   \

  File InputStream Reader

    ||  OutputStream  Writer  

  文件以及目录类      ||                ||

      字节约流读写类  字符流读写类

File类及下
一个File类的对象,表示了磁盘上的文书要目录。

File类提供了与平台无关之道来针对磁盘上之文书要目录进行操作。

File类直接处理公事以及文件系统。比如删除文件,获取文件长度大小相等信息。

File没有提供方从文本读取或为文件储存信息。

构造方法:File(String
directoryPath)  文件所在路径  File(String directoryPath,String
filename)  文件所在路径,文件名 File(File dirObj,String filename)   
  文件所在路径封装,文件称

图片 23图片 24

 1 package com.abc.tzy;
 2 
 3 import java.io.File;
 4 import java.io.FileFilter;
 5 import java.io.FilenameFilter;
 6 import java.io.IOException;
 7 
 8 public class FileDemo {
 9     public static void main(String[] args) throws IOException {
10         File file = new File("d:\\qq");// "d:/qq"
11         // File getAbsoluteFile() 返回此抽象路径名的绝对路径名形式。
12         System.out.println(file.getAbsolutePath());// d:\qq
13         // String getParent() 返回此抽象路径名父目录的路径名字符串;如果此路径名没有指定父目录,则返回 null
14         System.out.println(file.getParent());// d:\
15         // boolean isDirectory() 测试此抽象路径名表示的文件是否是一个目录。
16         System.out.println(file.isDirectory());// true
17         // boolean isFile() 测试此抽象路径名表示的文件是否是一个标准文件。
18         System.out.println(file.isFile());// false
19         // boolean exists() 测试此抽象路径名表示的文件或目录是否存在。
20         System.out.println(file.exists());// true
21         // boolean delete() 删除此抽象路径名表示的文件或目录。
22         System.out.println(file.delete());// false
23         File myFile = new File("d:\\zhangsan");
24         // boolean mkdir() 创建此抽象路径名指定的目录。
25         System.out.println(myFile.mkdir());// 没有时true 有了就是false
26         File myFile2 = new File("d:/zhangsan/tzy.txt");
27         // boolean createNewFile() 当且仅当不存在具有此抽象路径名指定名称的文件时,不可分地创建一个新的空文件。
28         System.out.println(myFile2.createNewFile());// 没有时true 有了就是false
29         // String[] list() 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中的文件和目录。
30         /*
31         String[] files = file.list();
32         for (String f : files) {
33             System.out.println(f);
34         }
35         System.out.println("*************");
36         */
37         // String[] list(FilenameFilter filter)
38         // 返回一个字符串数组,这些字符串指定此抽象路径名表示的目录中满足指定过滤器的文件和目录。
39         /*
40         String[] list = file.list(new FilenameFilter() {
41 
42             @Override
43             public boolean accept(File dir, String name) {
44                 // boolean endsWith(String suffix) 测试此字符串是否以指定的后缀结束。 (String)
45                 return name.endsWith(".exe");
46             }
47         });
48         for (String f : list) {
49             System.out.println(f);
50         }
51         */
52         //File[] listFiles()  返回一个抽象路径名数组,这些路径名表示此抽象路径名表示的目录中的文件。
53         /*
54         File[] listFiles = file.listFiles();
55         for (File f : listFiles) {
56             // String getName() 返回由此抽象路径名表示的文件或目录的名称。 
57             //long length()  返回由此抽象路径名表示的文件的长度。 
58             System.out.println(f.getName()+"---"+f.length());
59         }
60         */
61         //public interface FileFilter用于抽象路径名的过滤器。
62         //File[] listFiles(FilenameFilter filter)  返回抽象路径名数组,
63         //这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。 
64          /*
65         File[] listFiles = file.listFiles(new FilenameFilter() {
66             
67             @Override
68             public boolean accept(File dir, String name) {
69                 return name.endsWith(".exe");
70             }
71         });
72          for (File f : listFiles) {
73              System.out.println(f.getName()+"---"+f.length());
74         }
75         */
76         //File[] listFiles(FileFilter filter) 
77         //返回抽象路径名数组,这些路径名表示此抽象路径名表示的目录中满足指定过滤器的文件和目录。 
78         File[] listFiles = file.listFiles(new FileFilter() {
79             
80             @Override
81             public boolean accept(File pathname) {
82                 return pathname.getName().endsWith(".exe");
83             }
84         });
85          for (File f : listFiles) {
86              System.out.println(f.getName()+"---"+f.length());
87         }
88     }
89 }

File测试

图片 25图片 26

 1 package com.abc.tzy;
 2 
 3 import java.io.File;
 4 import java.util.ArrayList;
 5 import java.util.List;
 6 
 7 public class IteratorDirDemo {
 8     public static void main(String[] args) {
 9         IteratorUtil.IteratorDir(new File("d:\\qq"));
10     }
11 
12 }
13 
14 class IteratorUtil{
15     private static int level = 0;//层级数
16     public static void IteratorDir(File file){
17         if(file!=null){
18             //找出递归的出口
19             //假设是文件或者时空文件夹
20             if(file.isFile()||file.listFiles().length==0){
21                 return;
22             }else{
23                 File[] files = file.listFiles();
24                 //要求时先输出文件夹再输出文件
25                  files = sort(files);
26                  for (File f : files) {
27                      //这是一个动态字符串
28                     StringBuilder sb = new StringBuilder();
29                     if(f.isFile()){
30                         sb.append(getTab(level));
31                         sb.append(f.getName());
32                     }else{
33                         sb.append(getTab(level));
34                         sb.append(f.getName());
35                         sb.append("\\");
36                     }
37                     System.out.println(sb.toString());
38                     //加入是文件夹
39                     if(f.isDirectory()){
40                         level++;//进入目录遍历,层级+1;
41                         IteratorDir(f);//递归调用遍历目录的方法
42                         level--;//目录层级减一,退回上一级目录继续打印输出
43                     }
44                 }
45                 
46             }
47         }
48     }
49     /**
50      * 对File类型的数组进行先目录后文件的排列
51      * @param files
52      * @return
53      */
54     private static File[] sort(File[] files){
55         List<File> fList = new ArrayList<File>();
56         //先存放文件夹
57         for (File f : files) {
58             if(f.isDirectory()){
59                 fList.add(f);
60             }
61         }
62         //再存放文件
63         for (File f : files) {
64             if(f.isFile()){
65                 fList.add(f);
66             }
67         }
68         //<T> T[]  toArray(T[] a) 按适当顺序(从第一个到最后一个元素)
69         //返回包含此列表中所有元素的数组;返回数组的运行时类型是指定数组的运行时类型。 (ArrayList)
70         return fList.toArray(new File[fList.size()]);
71     }
72     //根据层级数来得到\t的个数
73     private static String getTab(int level){
74         StringBuilder sb = new StringBuilder();
75         for (int i = 0; i < level; i++) {
76             sb.append("\t");
77         }
78         return sb.toString();
79     }
80 }

递归打印文件夹及文件

横流的概念与分类

流时一个杀像之概念,当次用读取数据的时候,就见面打开一个往数据源的流动,这个数据源可以是文件,内存,或是网络连接。类似之,当次要写副数据的时光,就会开启

一个通往目的地之流动。这时候若就是好想像数据类在当下间流动一样。

注的归类:

  流按那流向分为“输入流”和“输出流”

  流按数量传单位分成“字节流”和“字符流”

    “字节流”用来读写8号二进制的字节;(MP3,MP4,图片视频等多媒体文件)

    “字符流”用来读写16个二进制字符;(文本文件)

  流按功能分为“节点流”和“过滤流”

    “节点流”用于直操作目标设备的流动。例如:磁盘或同等片内存区域

    “过滤流”时对一个已经是的流淌的连日和包裹,通过对数码进行拍卖,为序提供功能强大、灵活的读写功能。

InputStream抽象类

  字节约流类用于向许节约流读写8号二进制的字节。一般的,字节约流类主要用以读写诸如图或声音相当之二进制数据。

  字节约流类以InputStream和OutputStream为到层类。它们都是抽象类。

  InputStream是概念了字节输入流的抽象类

Outputstream抽象类

  Outputstream是概念了字节输出流的抽象类

  该类所有术返回void值,在阴差阳错情况下抛IOException异常

InputStream和Outputstream**

  每个抽象类都有差不多独实际的子类,这些子类对不同之外设进行处理,例如磁盘文件,网络连接,甚至是外存缓冲区。

  FileInputStream类表示能起文本读取字节的InputStream类

  常用构造: FileInputstream(String
filepath)  FileInputStream(File fileObj)

  FileOutStream代表能于文件写副字节的OutputStream类

  常用构造:FileOutStream(String
filepath)  FileOutStream(File fileObj)  FileOutStream(String
filepath,boolean append)

 

图片 27图片 28

 1 package com.abc.tzy;
 2 
 3 import java.io.File;
 4 import java.io.FileInputStream;
 5 import java.io.FileNotFoundException;
 6 import java.io.FileOutputStream;
 7 import java.io.IOException;
 8 
 9 public class FileInputStreamOutputStreamDemo {
10 
11     public static void main(String[] args) {
12         try {
13             FilecopyUtil.copyFile(new File("D:\\oo\\photo02.jpg"), new File("D:\\oo\\photo01.jpg"));
14         } catch (IOException e) {
15             e.printStackTrace();
16         }
17     }
18 
19 }
20 
21 class FilecopyUtil{
22     public static void copyFile(File src,File dst) throws IOException{
23         FileInputStream fis = new FileInputStream(src);
24         FileOutputStream fos = new FileOutputStream(dst);
25         long t1 = System.currentTimeMillis();
26         int data = -1;
27         int count=0;
28         while((data=fis.read())!=-1){
29             fos.write(data);
30             count++;
31         }
32         fos.close();
33         fis.close();
34         long t2 = System.currentTimeMillis();
35         System.out.println("复制完成花费:"+(t2-t1)+"毫秒,读了"+count+"次");
36     }
37     
38 }

字节流复制图片

 

 

    图片 29

 

图片 30图片 31

 1 package com.abc.tzy;
 2 
 3 import java.io.File;
 4 import java.io.FileInputStream;
 5 import java.io.FileNotFoundException;
 6 import java.io.FileOutputStream;
 7 import java.io.IOException;
 8 
 9 public class FileInputStreamOutputStreamDemo {
10 
11     public static void main(String[] args) {
12         try {
13             FilecopyUtil.copyFile(new File("D:\\oo\\photo02.jpg"), new File("D:\\oo\\photo01.jpg"));
14         } catch (IOException e) {
15             e.printStackTrace();
16         }
17     }
18 
19 }
20 
21 class FilecopyUtil{
22     public static void copyFile(File src,File dst) throws IOException{
23         FileInputStream fis = new FileInputStream(src);
24         FileOutputStream fos = new FileOutputStream(dst);
25         
26 
27         int count=0;
28         int len = 0;//*****为什么需要这个变量****
29         //因为下面的read(buf)是将文件以8位二进制形式(也就是1b即一字节)装入byte数组作为一个元素.那么当数组读到最后一次时肯定时读不满的,
30         //故要将最后一次装入的---元素的个数---统计出来。
31         byte [] buf = new byte[1024];//创建一个1kb大小的缓冲区,用来存放输入流中的字符数
32         long t1 = System.currentTimeMillis();
33         // int read()   从此输入流中读取一个数据字节。 
34         // int read(byte[] b) 从此输入流中将最多 b.length 个字节的数据读入一个 byte 数组中。 
35         // int read(byte[] b, int off, int len)  从此输入流中将最多 len 个字节的数据读入一个 byte 数组中 
36         
37         // void write(int b) 将指定字节写入此文件输出流。 
38         // void write(byte[] b)  将 b.length 个字节从指定 byte 数组写入此文件输出流中。
39         //write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此文件输出流。
40         while((len=fis.read(buf))!=-1){
41             fos.write(buf, 0, len);
42             count++;
43         }
44         fos.close();
45         fis.close();
46         long t2 = System.currentTimeMillis();
47         System.out.println("复制完成花费:"+(t2-t1)+"毫秒,读了"+count+"次");
48     }
49     
50 }

字节流–数组–读取与读来-内存解析

总:输入流其实就是文本读入内存的桥接,输出流就是内存读出至文件的桥接.

 ByteArrayInputStream/OutputStream

  ByteArrayInputStream是把字节数组当成源的输入流

  两只构造方法,每个都亟待一个字节数组提供数据源

    ByteArratInputStream(byte array[])

    ByteArrayInputStream(byte array[],int start,int numBytes)

  ByteArrayOutStream是把字节数组当作目标的输出源

  两只构造方法:

    ByteArrayOutStream()创建一个新的byte数组输出流

    ByteArrayOutStream(int
numBytes)创建一个新的byte数组输出流,具有制定大小的缓冲区(字节为单位)

图片 32图片 33

 1 package com.abc.tzy;
 2 
 3 import java.io.ByteArrayInputStream;
 4 import java.io.ByteArrayOutputStream;
 5 import java.io.FileOutputStream;
 6 import java.io.IOException;
 7 
 8 public class ByteArrayInputStreamOutputStreamDemo {
 9 public static void main(String[] args) throws IOException {
10     String str = "hello,shanghai";
11     ByteArrayInputStream bis = new ByteArrayInputStream(str.getBytes());
12     int data = 0;
13     while((data=bis.read())!=-1){
14         System.out.println((char)data);
15     }
16     System.out.println("******");
17     ByteArrayOutputStream bos = new ByteArrayOutputStream();//默认32位长度
18     bos.write(97);
19     bos.write(65);
20     bos.write("hello,world".getBytes());
21     byte[] buff = bos.toByteArray();
22     for (byte b : buff) {
23         System.out.println((char)b);
24     }
25     System.out.println("********");
26     FileOutputStream fos = new FileOutputStream("d://aa.txt",false);//false不覆盖
27     bos.writeTo(fos);//把ByteArrayOutputStream内部缓冲区的数据写到对应文件输出流中
28     fos.close();
29     
30 }
31 }

ByteArrayInput/OutputStream

 过滤流介绍

过滤流(filtered
Stream)仅仅是吗底色透明地提供扩展功能的输入流(输出流)的卷入。这些流动一般由普通类的不二法门(即过滤流的一个父类)访问。

过滤字节流FilterInputStream和FilterOutputStream.构造方法:FilterOutStream(OutputStream
os)         FilterInputStream(InputStream is)

这些看似提供的办法与InputStream及OutputStream类的点子一致

常用的过滤流BufferedInputStream和BuffOutputStream,DataInputStream和DataOutputStream

图片 34图片 35

 1 package com.abc.tzy;
 2 
 3 import java.io.BufferedInputStream;
 4 import java.io.BufferedOutputStream;
 5 import java.io.File;
 6 import java.io.FileInputStream;
 7 import java.io.FileOutputStream;
 8 import java.io.IOException;
 9 
10 public class BufferedInputStreamOutputStreamDemo {
11 
12     public static void main(String[] args) {
13         try {
14             FilecopyUtil1.copyFile(new File("D:\\oo\\photo02.jpg"), new File("D:\\oo\\photo01.jpg"));
15         } catch (IOException e) {
16             e.printStackTrace();
17         }
18     }
19 
20 }
21 
22 class FilecopyUtil1 {
23     public static void copyFile(File src, File dst) throws IOException {
24         FileInputStream fis = new FileInputStream(src);
25         FileOutputStream fos = new FileOutputStream(dst);
26         BufferedInputStream bis = new BufferedInputStream(fis);
27         BufferedOutputStream bos = new BufferedOutputStream(fos);
28         int data = 0;
29         long time1 = System.currentTimeMillis();
30         while ((data = bis.read()) != -1) {
31             bos.write(data);
32         }
33         bos.close();
34         bis.close();
35         long time2 = System.currentTimeMillis();
36         System.out.println("复制完成,共花费"+(time2-time1)+"毫秒");
37     }
38 }

过滤流Buffered

图片 36图片 37

 1 package com.abc.tzy;
 2 
 3 import java.io.DataInputStream;
 4 import java.io.DataOutputStream;
 5 import java.io.FileInputStream;
 6 import java.io.FileNotFoundException;
 7 import java.io.FileOutputStream;
 8 import java.io.IOException;
 9 
10 public class DataInputOutputStreamDemo {
11     public static void main(String[] args) throws IOException {
12         String name = "zhangsan";
13         int age = 10;
14         boolean flag = true;
15         char sex = '男';
16         double money = 100.56;
17         DataOutputStream dos = new DataOutputStream(new FileOutputStream("d:\\b.txt"));
18         dos.writeUTF(name);
19         dos.writeInt(age);
20         dos.writeBoolean(flag);
21         dos.writeChar(sex);
22         dos.writeDouble(money);
23         dos.close();
24         
25         DataInputStream dis = new DataInputStream(new FileInputStream("d:\\b.txt"));
26         //读写顺序必须一致
27         System.out.println(dis.readUTF());
28         System.out.println(dis.readInt());
29         System.out.println(dis.readBoolean());
30         System.out.println(dis.readChar());
31         System.out.println(dis.readDouble());
32         
33     }
34 }

过滤流Data

  BufferedInputStream和BuffOutputStream

    需要动用已存在的节点流来构造,提供带缓冲区的读写,提高了读写的效率

      文件–>从文本中收获输入字节(FileInputStream)–>增加字节缓冲区功能(BufferedInputStream)–>数据

      数据–>提供数据写副到缓存区
(
FileOutputStream)–>将数据因字节写副到文件中–>文件

  DataInputStream和DataOutputStream

    数据输入输出流允许应用程序读写基本Java数据类型。应用程序可以运用数据输出流写副小晚由数量输入流读取。读写顺序要保持一致。

图片 38图片 39

 1 package com.asd.tzy;
 2 
 3 import java.io.File;
 4 import java.io.FileInputStream;
 5 import java.io.FileNotFoundException;
 6 import java.io.FileOutputStream;
 7 import java.io.IOException;
 8 
 9 public class CopyDirDemo {
10 
11     public static void main(String[] args) {
12         try {
13             CopyDirUtil.copyDir(new File("D:\\xmind"), new File("D:\\xmind2"));
14             System.out.println("拷贝成功");
15         } catch (IOException e) {
16             e.printStackTrace();
17         }
18     }
19 
20 }
21 
22 class CopyDirUtil{
23     public static void copyDir(File src,File dst) throws IOException{
24         dst.mkdirs();//d:\\zz\\bb创建目标文件夹
25         if(src!=null){
26             File[] files = src.listFiles();//遍历源文件夹中的所有文件或目录
27             for (File f : files) {
28                 if(f.isFile()){
29                     //是文件就复制
30                     FileInputStream fis = new FileInputStream(f);
31                     FileOutputStream fos = new FileOutputStream(dst.getAbsolutePath()+"\\"+f.getName());
32                     byte [] buff = new byte[1024*1024];//1M
33                     int len = 0 ;//保存的时读到的字节个数
34                     while((len=fis.read(buff))!=-1){
35                         fos.write(buff,0,len);
36                     }
37                     fos.close();
38                     fis.close();
39                 }else{
40                     copyDir(f,new File(dst.getAbsolutePath()+"\\"+f.getName()));
41                 }
42             }
43         }
44     }
45 }

运用字节流复制一个文本夹

 Reader和Writer抽象类

字节流提供处理外类型输入输出操作的足足功能,但切莫能够直接操作Unicode字符(比如中文2字节),因而要字符流

字符流层次结构的顶层是Reader和Writer抽象类

Reader是定义Java的流式字符输入模式的抽象类

Writer是概念流式字符输出的泛类:该类的法都回到void值并于错条件下丢来IOException异常

 FileReader和FileWriter

FileReader类表示可以读取文件内容的Reader类

构造方法:FileReader(String
filePath)  FileReader(File fileObj)

FileWriter表示足形容文件的Writer类

构造方法:FileWriter(String
filePath)  FileWriter(String filePath,boolean
append)  FileWriter(File fileObj)

图片 40图片 41

 1 package com.asd.tzy;
 2 
 3 import java.io.FileNotFoundException;
 4 import java.io.FileReader;
 5 import java.io.FileWriter;
 6 import java.io.IOException;
 7 
 8 public class FileReaderWriterDemo {
 9 
10     public static void main(String[] args) throws IOException {
11         FileReader fr = new FileReader("d:\\tzy.txt");
12         FileWriter fw = new FileWriter("d:\\tzy1.txt");
13         char[] buff = new char[100];
14         int len = 0;//实际读取的字符个数
15         while((len=fr.read(buff))!=-1){
16             fw.write(buff,0,len);
17         }
18         fw.close();//如果不关闭 那么缓冲区文件不会被读出来,可以使用fw.flush()强制清空缓存区
19         fr.close();
20     }
21 
22 }

字符流复制文件

BufferedReader和BufferedWriter

BufferedReader通过缓冲输入提高性能

构造方法:BufferedReader(Reader
inputStream)  BufferedReader(Reader inputStream,int bufSize)

BufferedWriter通过缓冲输出提供性

构造方法:BufferedWriter(Writer
outputStream)  BufferedWriter(Writer outputStream,int bufSize)

图片 42图片 43

 1 package com.asd.tzy;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.BufferedWriter;
 5 import java.io.FileNotFoundException;
 6 import java.io.FileReader;
 7 import java.io.FileWriter;
 8 import java.io.IOException;
 9 
10 public class BufferedReaderWriterDemo {
11 
12     public static void main(String[] args) throws IOException {
13         FileReader fr = new FileReader("d:\\tzy.txt");
14         BufferedReader br = new BufferedReader(fr);
15         FileWriter fw = new FileWriter("d:\\tzy2.txt");
16         BufferedWriter bw = new BufferedWriter(fw);
17         String line = null;
18         while((line=br.readLine())!=null){
19             System.out.println(line);
20             bw.write(line);
21             bw.newLine();//使文件换行
22             bw.flush();
23         }
24         bw.close();
25         br.close();
26     }
27 
28 }

苏冲字符流复制文件

ObjectInputStream/ObjectOutputStream

ObjectOutputStream和ObjectInputStream分别同FileOutStream和FileInputStream一起行使,可以呢应用程序提供针对性目标的持久储存。我们将目标为某种特定得到编码格式写入

称为序列化。把写副的编码格式内容还原成对象称之为反序列化

序列化的目标要兑现Serializable接口

图片 44图片 45

 1 package com.asd.tzy;
 2 
 3 import java.io.FileInputStream;
 4 import java.io.FileNotFoundException;
 5 import java.io.FileOutputStream;
 6 import java.io.IOException;
 7 import java.io.ObjectInputStream;
 8 import java.io.ObjectOutputStream;
 9 import java.io.Serializable;
10 
11 public class ObjectInputOutputDemo {
12 
13     public static void main(String[] args) throws IOException {
14         Stduent st = new Stduent("张三", 30);
15         FileOutputStream fos = new FileOutputStream("d:\\tzy.txt");
16         ObjectOutputStream oos = new ObjectOutputStream(fos);
17         oos.writeObject(st);//把对象序列化到制定文件输出流中
18 //         java.io.NotSerializableException
19         ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:\\tzy.txt"));
20         try {
21             Stduent stu = (Stduent) ois.readObject();
22             System.out.println(stu);
23         } catch (ClassNotFoundException e) {
24             e.printStackTrace();
25         }finally{
26             ois.close();
27         }
28     }
29 
30 }
31 
32 class Stduent implements Serializable{
33     /**
34      * 
35      */
36     private static final long serialVersionUID = 7425793184115828439L;
37     private String name;
38     private int age;
39     private String address;
40     public Stduent(String name, int age) {
41         super();
42         this.name = name;
43         this.age = age;
44     }
45     public String getName() {
46         return name;
47     }
48     public void setName(String name) {
49         this.name = name;
50     }
51     public int getAge() {
52         return age;
53     }
54     public void setAge(int age) {
55         this.age = age;
56     }
57     @Override
58     public String toString() {
59         return "Stduent [name=" + name + ", age=" + age + "]";
60     }
61     
62 }

序列化及反序列化对象

 InputStreamReader,OutputStreamWrite

转换流是因用字节流与字符流之间的变。

转换流的起有利于了针对文件的读写,它以字符流和字节流之间架从了平栋桥,使原先无关联的少数栽流操作能够进行中转,提高了程序的油滑。

字节流中的数据都是字符时,转成为字符流操作更作笑。

一经应用非默认编码保存文件或者读取文件时,需要用转换流,因为字节流的重载构造方法中右制定编码格式的参数,而FileReader和FileWriter是默认编码的文书文件。

广大的编码表:

  ASCLL:美国专业信息交换码。用一个字节的7位可表示

  ISO8859-1:拉丁码表,欧洲码。用一个字节的8各代表

  GB2312:中国之国语编码表

  GBK:中国的汉语编码表升级,融合了重复多的国语文标记。

  Unicode:国际标准码,融合了强字。所有文字都用2个字节来表示,Java语言应用的就算是Unicode

  UTF-8:最多为此3个字节来表示一个字符。

 

图片 46图片 47

 1 package com.asd.tzy;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.BufferedWriter;
 5 import java.io.FileInputStream;
 6 import java.io.FileNotFoundException;
 7 import java.io.FileOutputStream;
 8 import java.io.IOException;
 9 import java.io.InputStreamReader;
10 import java.io.ObjectInputStream;
11 import java.io.ObjectOutputStream;
12 import java.io.OutputStreamWriter;
13 import java.io.Serializable;
14 
15 public class InputOutputStreamReaderWriterDemo {
16 
17     public static void main(String[] args) throws IOException {
18         FileOutputStream fos = new FileOutputStream("d:\\tzy.txt");
19         OutputStreamWriter oos = new OutputStreamWriter(fos, "utf-8");
20         BufferedWriter osw = new BufferedWriter(oos);
21         osw.write("我是谁");//在utf-8里中文占3个字节 如果直接用FileReader读,那么用的是默认编码读的是2个字节,所以读出来是乱码
22         osw.newLine();//换行
23         osw.write("我时你");
24         osw.flush();//
25         osw.close();
26         BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("d:\\tzy.txt"), "utf-8"));
27         String line = null;
28         while((line=br.readLine())!=null){
29             System.out.println(line);
30         }
31     }
32 
33 }

转换流对指定编码文件读写

 RandomAccessFile随机访问文件

支撑对擅自访问文件的读写及写入

随意走访文件的行事看似存储于文件系统中之一个巨型byte数组。存在对该隐含数组的光标或索引,称为文件指针

输入操作由文本指针开始读取字节,随着对字节的读取而眼前更换此文件指针

设任意访问文件为读取/写副模式创造,则输出操作也可用;输出操作自文本指针开始勾画副字节,随着对字节的勾副如果前换此文件指针

形容副隐含数组末尾之后的输出操作造成该数组扩展。

拖欠文件指针可以通过getFilePointer方法读取,通过seek方法设置

图片 48图片 49

 1 package com.asd.tzy;
 2 
 3 import java.io.FileNotFoundException;
 4 import java.io.IOException;
 5 import java.io.RandomAccessFile;
 6 import java.util.Scanner;
 7 
 8 public class RandomAccessFileDemo {
 9     public static void main(String[] args) throws IOException {
10         Person[] persons = { new Person("zhangsan", 90), new Person("justin", 30), new Person("bush", 88),
11                 new Person("lisi", 20) };
12         RandomAccessFile randomAccessFile = new RandomAccessFile("d:\\tzy.txt", "rw");// r只读// rw可读可写
13         //写入数据到RandomAccessFile
14         for (int i = 0; i < persons.length; i++) {
15             randomAccessFile.writeChars(persons[i].getName());
16             randomAccessFile.writeInt(persons[i].getAge());//按4个字节写入数字
17         }
18         //读取指定位置上的Person对象
19         Scanner sc = new Scanner(System.in);
20         System.out.println("读取第几个Person对象数据");
21         int num = sc.nextInt();
22         //使用seek方法来操作存取位置
23         randomAccessFile.seek((num-1)*Person.size());//跳过多少字节读
24         Person person = new Person();
25         person.setName(readName(randomAccessFile));
26         person.setAge(randomAccessFile.readInt());
27         System.out.println("姓名:"+person.getName()+";年龄:"+person.getAge());
28         randomAccessFile.close();
29         
30     }
31     private static String readName(RandomAccessFile randomAccessFile) throws IOException{
32         char [] name = new char[15];
33         for (int i = 0; i < name.length; i++) {
34             name[i]=randomAccessFile.readChar();
35         }
36         return new String(name).replace("\u0000", "");
37     }
38 }
39 
40 class Person {
41     private String name;
42     private int age;
43 
44     public Person(String name, int age) {
45         StringBuilder builder = null;
46         if (name != null) {
47             builder = new StringBuilder(name);// 默认为16长度+传入字符串长度的字符串
48 
49         } else {
50             builder = new StringBuilder(15);// 制定为15长度的字符串
51         }
52         builder.setLength(15);// 固定长度15个字符,占了30个字节的大小
53         this.name = builder.toString();
54         this.age = age;
55     }
56 
57     public Person() {
58         super();
59     }
60 
61     public String getName() {
62         return name;
63     }
64 
65     public void setName(String name) {
66         this.name = name;
67     }
68 
69     public int getAge() {
70         return age;
71     }
72 
73     public void setAge(int age) {
74         this.age = age;
75     }
76 
77     // 每个对象所占的字节数
78     public static int size() {
79         return 34;
80     }
81 }

RandomAccessFile读写对象

 网络基础知识

电脑网络

  计算机网络,就是把分布在不同地理区域之微机和专程的外部设备通信线路互联成一个范畴颇,功能强的大网体系,从而使许多底处理器可以方便地互相传递细心,共享硬件、

  软件、数据信息相当资源。

网络体系结构

  网络体系结构定义计算机设备和任何装置哪连接于一块儿因为形成一个兴用户共享信息及资源的通信系统。

  国际标准化组织IOS于1978年提出“开放系统相互连参考模型”,即著名的OSI模型。OSI模型保证了各项设施生产厂家的出品相当新。

  该型将电脑网络分成物理层、数据链路层、网络层、传输层、会话层、表示层、应用层等七层

OSI模型分层的好处

  不同厂商生产的配备都可以彼此配合。 

  设备可小心让某个同重叠的机能,如交换机工作在次叠,路由器工作于第三层。

  方便网络故障排错

  不用过多着想情理接口等这些物理层的物

TCP/IP是同组用于落实网络互联的通信协议。Internet网络体系结构以TCP/IP为核心。基于TCP/IP的参考模型将协商分成四独层次,它们各自是接口层、网络层、传输层、和应用层。

纱编程的目的

  网络编程的目的就是赖直接或者简介地通过网络协议与外电脑进行报道。网络编程中起半点独至关重要的题材,一个凡是怎规范之稳定网络达到的相同大抑多高主机,

  另一个不怕是找到主机后

  如何可靠高效的开展数据传。

纱通训要素

  IP地址;端口号;传输协议

IP地址

  网络中每令主机都必须出一个唯一的IP地址。

  因特网上的IP地址有世界唯一性。

  IP地址由32各类2进制组成,占4单字节,常用十进制的格式表示,

  例如:192.168.0.5

  对应的类-InetAddress

端口号

  端口号用来代表该处理器及的应用程序,代表者应用程序逻辑地址。

  端口号下一个16号的数字来代表,它的克是0~65535,1024之下的端口号保留给预定义的劳务。例如http使用80端口。

商概念

  为计算机网络中展开数据交换而建立之规则、标准还是预约的成团。

大的传输协议

  TCP是同种植面向连接的管教保险传输的协商。通过TCP协议传输,得到的凡一个相继的无差错的数据流

  UDP是同等种植无连接的协议,每个数据包都是一个单身的信,包括总体的源地址或目的地址,它当网及因为另外可能的路径传往目的地,因此能否上目的地,

  到达目的地之风波与内容的科学都是不克叫包的。

Socket

  时较为流行的纱编程模型是客户机/服务器通信模式(C/S架构:客户机上面要安装客户端 
        B/S架构:只要发生浏览器就可了,不需装客户端)

    客户过程向服务器进程来要求某种服务之乞求,服务器进程响应该请。通常,一个服务器进程会又也多个客户过程服务

  所谓的socket通常为称“套接字”,用于描述IP地址和端口,是一个通信链句柄。应用程序通常通过“套接字”向网发出请求或者对网络要。。

  Socket是接连运行于网络直达之蝇头单程序中的双向通许的端点。

  网络通许其实指的即是Socket间的报导。

  通讯的双方都生Socket,数据以简单只Socket之间通过IO来进行传输。

  使用Socket进行网络通信的进程

    服务器程序将一个仿照接字绑定到一个特定的端口,并由此此套接字等待与监听客户之总是要。

    客户程序根据服务器程序所当的主机名与端口号发出连要。

    如果一切正常,服务器接受请求。并取一个新的绑定到不同端口地址的套接字。

    客户及服务器通过读、写套接字进行报道。

  创建TCP服务器的步骤

    创建一个ServerSocket对象

    调用accept()方法接受客户端请求

    从Socket中获取IO流

    对IO流进行读写操作,完成及客户端的互交。

    关闭IO流和Socket

  创建TCP客户端步骤

    创建一个Socket对象

    从Socket中获取IO流

    对IO流进行读写操作,完成和服务器的互相。

    关闭IO流和Socket

 1 package com.asd.tzy;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.BufferedWriter;
 5 import java.io.IOException;
 6 import java.io.InputStreamReader;
 7 import java.io.OutputStreamWriter;
 8 import java.io.PrintWriter;
 9 import java.net.ServerSocket;
10 import java.net.Socket;
11 
12 public class TCPServer {
13 
14     public static void main(String[] args) throws IOException {
15         // 创建一个ServerSocket对象(服务器)
16         ServerSocket serverSocket = new ServerSocket(8888);
17         // 调用accept()方法来接受客户端的请求;
18         // Socket accept() 侦听并接受到此套接字的连接。
19         Socket socket = serverSocket.accept();
20         // InetAddress getInetAddress() 返回套接字连接的地址。
21         // String getHostAddress() 返回 IP 地址字符串(以文本表现形式)。
22         // String getHostName() 获取此 IP 地址的主机名
23         System.out.println("主机名" + socket.getInetAddress().getHostName() + "IP地址"
24                 + socket.getInetAddress().getHostAddress() + "连接成功");
25         // 获取socket对象的输入输出流
26         // InputStream getInputStream() 返回此套接字的输入流。
27         BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
28         //BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
29         PrintWriter pw = new PrintWriter(socket.getOutputStream(),true);
30         String line = null;
31         //读取客户端传过来的数据
32         while ((line = br.readLine()) != null) {
33             if (line.trim().equals("over")) {
34                 break;
35             } else {
36                 System.out.println(line);
37                 //bw.write(line.toUpperCase());//转换成大写的传给客户端
38                 //bw.newLine();
39                 //bw.flush();
40                 pw.println(line.toUpperCase());
41             }
42         }
43         //bw.close();
44         pw.close();
45         br.close();
46         socket.close();
47         System.out.println("主机名" + socket.getInetAddress().getHostName() + "IP地址"
48                 + socket.getInetAddress().getHostAddress() + "连接断开");
49     }
50 
51 }

TCPServer

 1 package com.asd.tzy;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.BufferedWriter;
 5 import java.io.IOException;
 6 import java.io.InputStreamReader;
 7 import java.io.OutputStreamWriter;
 8 import java.net.Socket;
 9 import java.net.UnknownHostException;
10 
11 public class TCPClient {
12 
13     public static void main(String[] args) throws UnknownHostException, IOException {
14         Socket socket = new Socket("localhost", 8888);
15         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
16         BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
17         BufferedReader br1 = new BufferedReader(new InputStreamReader(socket.getInputStream()));
18         while(true){
19             String line = br.readLine();//获取键盘输入的字符串
20             bw.write(line);
21             bw.newLine();//要加换行 服务器才知道读了一行
22             bw.flush();
23             if(line.trim().equals("over")){
24                 break;
25             }
26             System.out.println(br1.readLine());//获取服务端传来的大写字符串
27         }
28         br1.close();
29         bw.close();
30         br.close();
31         socket.close();
32     }
33 
34 }

TCPClient

 基于UDP协议的Socket编程

创立发送端

  创建DatagramSocket对象。
该断点建立,系统会自由分配一个端口。如果不思量随机配置,可以手动指定。

  将数据进行packet包之卷入,必须使指定目的地
地址及端口

  通过socket服务之send方法将该包发出。

  将socket关闭

创建接受端

  建立DatagramSocket对象。要监听一个端口。

  透过socket的receive方法将数据存入数据包中。

  通过数据包dp的艺术getData(),getAddredss(),getPort()等艺术取得包吃之指定信息。

  将socket关闭

 1 package com.asd.tzy;
 2 
 3 import java.io.IOException;
 4 import java.net.DatagramPacket;
 5 import java.net.DatagramSocket;
 6 import java.net.InetAddress;
 7 import java.net.SocketException;
 8 
 9 public class UDPDemo2 {
10 public static void main(String[] args) throws IOException {
11     DatagramSocket socket = new DatagramSocket(8000);
12     byte [] buff = new byte[100];
13     DatagramPacket packet = new DatagramPacket(buff, 100);
14     socket.receive(packet);//接受传来的数据包
15     System.out.println(new String(packet.getData()));
16     String str = "me too!";
17     DatagramPacket packet2 = new DatagramPacket(str.getBytes(), 0, str.length(), packet.getAddress(), packet.getPort());
18     socket.send(packet2);
19     socket.close();
20 }
21 }

UDPDemo2 先启动

 1 package com.asd.tzy;
 2 
 3 import java.io.IOException;
 4 import java.net.DatagramPacket;
 5 import java.net.DatagramSocket;
 6 import java.net.InetAddress;
 7 import java.net.SocketException;
 8 import java.net.UnknownHostException;
 9 
10 public class UDPDemo1 {
11 
12     public static void main(String[] args) throws IOException {
13         DatagramSocket socket = new DatagramSocket();
14         String str = "i love you!";
15         //把数据进行封装,封装到数据报 包中;
16         DatagramPacket packet = new DatagramPacket(str.getBytes(), 0, str.length(), InetAddress.getByName("localhost"), 8000);
17         socket.send(packet);//发送
18         byte [] buff = new byte[100];
19         DatagramPacket packet2 = new DatagramPacket(buff, 100);
20         socket.receive(packet2);
21         System.out.println(new String(packet2.getData()));
22         socket.close();
23     }
24 
25 }

UDPDemo1后启动

 多线程Socket

 1 package com.asd.tzy;
 2 
 3 import java.io.IOException;
 4 import java.net.ServerSocket;
 5 import java.net.Socket;
 6 
 7 public class ChatServer {
 8 
 9     public static void main(String[] args) throws IOException {
10         ServerSocket serverSocket = new ServerSocket(9999);
11         int number = 1;//保存客户端个数
12         while(true){
13             Socket socket = serverSocket.accept();
14             System.out.println("客户端"+number+"连接成功");
15             //服务端开启一个独立的线程来对客户端进行读写操作
16             new Thread(new ServerStream(socket, number)).start();;
17             number++;
18         }
19     }
20 
21 }

服务器端

 1 package com.asd.tzy;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.IOException;
 5 import java.io.InputStreamReader;
 6 import java.io.PrintWriter;
 7 import java.net.Socket;
 8 
 9 public class ServerStream implements Runnable {
10     private Socket socket = null;
11     private int number;
12     
13     public ServerStream(Socket socket, int number) {
14         super();
15         this.socket = socket;
16         this.number = number;
17     }
18 
19     @Override
20     public void run() {
21         try {
22             BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
23             PrintWriter pw  = new PrintWriter(socket.getOutputStream(),true);
24             while(true){
25                 String line = br.readLine();
26                 System.out.println("客户端"+number+":"+line);
27                 pw.println(line.toUpperCase());
28                 if(line.trim().equals("bye")){
29                     System.out.println("客户端:"+number+"断开连接");
30                     break;
31                 }
32             }
33             br.close();
34             pw.close();
35         } catch (IOException e) {
36             e.printStackTrace();
37         }
38         
39     }
40 
41 
42 }

服务器读写

 1 package com.asd.tzy;
 2 
 3 import java.io.IOException;
 4 import java.net.Socket;
 5 import java.net.UnknownHostException;
 6 
 7 public class ChatClient {
 8 
 9     public static void main(String[] args) throws UnknownHostException, IOException {
10         Socket socket = new Socket("127.0.0.1", 9999);
11         new Thread(new ClirentOutputStream(socket)).start();
12         new Thread(new ClientInputStream(socket)).start();
13     
14     }
15 
16 }

客户端

 1 package com.asd.tzy;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.IOException;
 5 import java.io.InputStreamReader;
 6 import java.io.PrintWriter;
 7 import java.net.Socket;
 8 
 9 public class ClirentOutputStream implements Runnable{
10     private Socket socket = null;
11     
12     public ClirentOutputStream(Socket socket) {
13         super();
14         this.socket = socket;
15     }
16 
17     @Override
18     public void run() {
19         try {
20             BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
21             PrintWriter pw = new PrintWriter(socket.getOutputStream(),true);
22             while(true){
23                 String line = br.readLine();
24                 pw.println(line);
25                 if(line.trim().equals("bye")){
26                     break;
27                 }
28             }
29             br.close();
30             pw.close();
31             socket.close();
32         } catch (IOException e) {
33             e.printStackTrace();
34         }
35     }
36 
37 
38 
39 }

客户端读

 1 package com.asd.tzy;
 2 
 3 import java.io.BufferedReader;
 4 import java.io.IOException;
 5 import java.io.InputStreamReader;
 6 import java.net.Socket;
 7 import java.net.SocketException;
 8 
 9 public class ClientInputStream implements Runnable {
10 private Socket socket = null;
11 
12     public ClientInputStream(Socket socket) {
13     super();
14     this.socket = socket;
15 }
16 
17     @Override
18     public void run() {
19         try {
20             BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
21             while(true){
22                 try {
23                     String line = br.readLine();
24                     System.out.println(line);
25                 } catch (SocketException e) {
26                     break;
27                 }
28             }
29             br.close();
30         } catch (IOException e) {
31             e.printStackTrace();
32         }
33     }
34 
35 }

客户端写

 URL类

URL是合资源定位器的简称,它表示Internet上某资源的地点。通过URL我们好看internet上的各种网络资源,比如大规模的www,FPT站点。浏览器通过分析给定的

URL可以于网络上搜索相应的文本或者另资源。

URL的中心结构由5有构成:

  <传输协议>://<主机名>:<端口号>/<文件名>#<引用>

  http://www.comcat.com:80/Gamelan/network.html\#BOTTOM

为表示URL,java.net包吃实现了仿佛URL。我们可以经过下的构造方法来初始化一个URL对象  

落URL对象的性  

 

 boolean equals(Object obj)
          比较此 URL 是否等于另一个对象。
 String getAuthority()
          获取此 URL 的授权部分。
 Object getContent()
          获取此 URL 的内容。
 Object getContent(Class[] classes)
          获取此 URL 的内容。
 int getDefaultPort()
          获取与此 URL 关联协议的默认端口号。
 String getFile()
          获取此 URL 的文件名。
 String getHost()
          获取此 URL 的主机名(如果适用)。
 String getPath()
          获取此 URL 的路径部分。
 int getPort()
          获取此 URL 的端口号。
 String getProtocol()
          获取此 URL 的协议名称。
 String getQuery()
          获取此 URL 的查询部分。
 String getRef()
          获取此 URL 的锚点(也称为“引用”)。
 String getUserInfo()
          获取此 URL 的 userInfo 部分。
 int hashCode()
          创建一个适合哈希表索引的整数。
 URLConnection openConnection()
          返回一个 URLConnection 对象,它表示到 URL 所引用的远程对象的连接。
 URLConnection openConnection(Proxy proxy)
          与 openConnection() 类似,所不同是连接通过指定的代理建立;不支持代理方式的协议处理程序将忽略该代理参数并建立正常的连接。
 InputStream openStream()
          打开到此 URL 的连接并返回一个用于从该连接读入的 InputStream
 boolean sameFile(URL other)
          比较两个 URL,不包括片段部分。
protected
 void
set(String protocol, String host,
int port, String file, String ref)

          设置 URL 的字段。
protected
 void
set(String protocol, String host,
int port, String authority, String userInfo, String path, String query, String ref)

          设置 URL 的指定的 8 个字段。
static void setURLStreamHandlerFactory(URLStreamHandlerFactory fac)
          设置应用程序的 URLStreamHandlerFactory
 String toExternalForm()
          构造此 URL 的字符串表示形式。
 String toString()
          构造此 URL 的字符串表示形式。
 URI toURI()
          返回与此 URL 等效的 URI

 URL右两种植办法好看Internet上资源

图片 50图片 51

 1 package com.asd.tzy;
 2 
 3 import java.io.File;
 4 import java.io.FileOutputStream;
 5 import java.io.IOException;
 6 import java.io.InputStream;
 7 import java.io.OutputStream;
 8 import java.net.MalformedURLException;
 9 import java.net.URL;
10 import java.net.URLConnection;
11 
12 public class URLDemo {
13 
14     public static void main(String[] args) {
15         try {
16             DownloadUtil.download("http://scimg.jb51.net/allimg/121209/2-1212091UH0339.jpg", "my.jpg", "d:\\abcimage");
17         } catch (IOException e) {
18             e.printStackTrace();
19         }
20     }
21 
22 }
23 
24 
25 class DownloadUtil{
26     public static void download(String urlString,String fileName,String savePath) throws IOException{
27         URL url = new URL(urlString);
28         //URLConnection conn = url.openConnection();
29         //InputStream is = conn.getInputStream();
30         InputStream is = url.openStream();
31         byte[] buff = new byte[1024];
32         int len = 0;
33         File file = new File(savePath);
34         if(!file.exists()){
35             file.mkdirs();
36         }
37         OutputStream os = new FileOutputStream(file.getAbsolutePath()+"\\"+fileName);
38         while((len=is.read(buff))!=-1){
39             os.write(buff, 0, len);
40         }
41         //施放资源
42         os.close();
43         is.close();
44     }
45 }

URL网页下载图片

 XML定义

XML指只是扩大标记语言,适合Wed传输,类似HTML,不同之是她的筹划宗旨是传输数据,而休显示数据。(不是亮数据)

XML提供统一之不二法门来讲述和交换独立于应用程序或供应商之结构化数据。XML标签没有被预定义,开发者需要活动定义标签。XML被设计吧拥有自身描述性,

是W3C的引进标准。

XML文档结构

  XML申明:<?xml version=”1.0″
standalone=”yes” encoding=”UTF-8″?>

  XML清素定义:XML文档的树形结构要求必须有一个根元素。根元素的苗子标记要放在有其他元素起始标记之前,

  根元素的毕标记放在另具有因素的结标记后。

  XML元素:元素的骨干结构由
开始标记,数据内容,结束标记组成

  XML中的注解:<!–this is
comment–>

XML的语法规则

  所有的XML元素都必有关闭标签

  XML标签对大小写敏感

  XML必须是嵌套

  XML文档必须发根元素

  XML的习性为名值对艺术做,值需加引号

  在XML中,空格会被封存,文档中的空格不会见受删节

SAX解析器

  SAX(Simple API For
XML)是一个公家的依据事件的XML文档解析标准,能够通过一个简易的、快速的不二法门来针对XML文档进行拍卖,和DOM相比其所占据的

系统资源更不见

  SAX即是一个接口,也是一个软件包。作为接口,SAX是事件驱动型XML解析的一个标准接口,对文档进行依次扫描,当扫描到文档(document)开始、

素(element)开始与了、文档结束等地方经常通报事件处理函数,由事件处理函数做相应动作,然后继续同的扫描,直至文档结束。

SAX解析器API

  大多数SAX会产生以下种类的波

    在文档的开端和终结时点文档处理事件

    在文档内各一个XML元素接受解析的上下触发元素事件

    在任元数据一般由单独的数量来拍卖

  举例:

      <doc>

        <para>Hello,tom<para>

      <doc>

      其分析过程:1:satrt document 2:start
element:doc.. 3:start:element:para.. 4:characters:Hello… 5:end
element:para… 6:end element:doc 7:end document

  解析步骤:

    创建事件处理程序(即编写ContentHandler的落实类似,一般持续自DefaultHandler类,采用adapter模式)

    创建SAX解析器

    将事件处理程序分配至解析器

    对文档进行剖析,将每个事件发送给事件处理程序

  常用接口:ContentHandler 接口

    ContentHandler是JAVA类保险被一个非正规的SAX接口

    该接口封装了有些针对事件处理的法门,当XML解析器开始解析XML输入文档时,它见面逢一些特殊之轩然大波,比如文档的启幕和了、元素的初始和终结、一级

    元素中的字符数据等事件。当遇到这些事件不时,XML解析器会调用ContentHandler接口中相应的不二法门来响应事件

    ContentHander接口常用方法:

      void
startDocument()//文档解析初步之处理

      void
endDocument()//文档解析了之处理

      void startElement(String
uri,String localName,String qName,Attributes
atts)//ElementNode开始的处理

      void endElement(String
uri,String localName,String qName)//ElementNode结束的拍卖

      void characters(char[] ch,
int start,int lenght)//具体在某平等节点中的拍卖