java - day019 - 反射

网络程序,难点在线程

  • 反射 reflect
  • 实用 类对象 来执行反射操作
    • 反射获得一个类的定义信息
    • 反射创建对象
    • 反射调用成员变量, 方法

 

  • 方法
    • 获得类对象的三种方式
    • A.class
    • Class.forName("完整类名");
    • a1.getClass();
  • 类对象的方法
    • c.getPackage().getName();
    • c.getName();
    • c.getSimpleName();
    • 获得成员变量的定义信息
      • getFields();    得到可见的成员变量,即能访问的, 包括继承来的
      • getDeclaredFields(); 本类定义的所有变量, 包括私有变量, 不包括继承的
      • getField(变量名);  得到单个可见的的成员变量
      • getDeclaredField(变量名);
    • 获得构造方法的定义信息
      • getConstructors();  获得可见的构造方法,
      • getDeclaredConstructors(); 获得所有的构造方法
      • getConstructor(参数类型列表); 获得单个可见的的构造方法
      • getDeclaredConstructor(int.class,String.class);
    • 获得方法的定义信息
      • getMethods(); // 可见的方法, 包括继承的方法
      • getDeclaredMethods(); // 本类定义的方法, 包括私有的方法,不包括继承的方法
      • getMethod(方法名,参数类型列表);
      • getDeclaredMethod(方法名,int.class,String.class);
    • package day1901_反射;
      
      import java.lang.reflect.Constructor;
      import java.lang.reflect.Field;
      import java.lang.reflect.Method;
      import java.util.Arrays;
      import java.util.Scanner;
      
      public class Test1 {
          public static void main(String[] args) throws Exception {
              
              System.out.println("输入完整类名");
              
              String s = new Scanner(System.in).nextLine();
              
              // 获得这个类的'类对象'
              
              Class<?> c = Class.forName(s);
              
              // 获得包名, 类名 ,简写类名
              String p = c.getPackage().getName();
              String n = c.getName();
              String sn = c.getSimpleName();
              System.out.println(p);
              System.out.println(n);
              System.out.println(sn);
              
              
              System.out.println("----成员变量------");
              f1(c);
              
              System.out.println("----构造方法------");
              f2(c);
              
              
              System.out.println("----方法------");
              f3(c);
              
              
          }
      
          private static void f3(Class<?> c) {
              /*
               * Method 对象, 封装方法的定义信息
               * public static void f(int i , String s)throws X,Y,Z
               */
              Method[] a = c.getDeclaredMethods();
              for (Method f : a) {
                  String n = f.getName();
                  // 构造方法参数的类型 (int.class, String.class);
                  Class<?>[] p = f.getParameterTypes();
                  System.out.println(n+"("+Arrays.toString(p)+")");
              }
          }
      
          private static void f2(Class<?> c) {
              /*
               * Constructor 构造方法的封装对象
               * 
               * public A(int a, String s) throws X,Y,Z
               * 
               */
              Constructor<?>[] a = c.getConstructors();
              for (Constructor<?> t : a) {
                  String n = c.getSimpleName();
                  // 构造方法参数的类型 (int.class, String.class);
                  Class<?>[] p = t.getParameterTypes();
                  System.out.println(n+"("+Arrays.toString(p)+")");
              }
          }
      
          private static void f1(Class<?> c) {
              /*
               * Field对象
               * 封装了成员变量的定义信息
               * 
               */
              Field[] a = c.getDeclaredFields();
              for (Field f : a) {
                  
                  System.out.println(f.getType().getSimpleName()+f.getName());
              }
              
          }
      }

       

 

 

  • 反射新建对象
    • 通过  类对象  的反射操作
    • 执行 无参构造 方法
      • object obj = c.newInstabce();
    • 执行有参构造
      • 先获得构造方法
      • Constructor  t = c.getConstructor(int.class,String.class);
      • 通过构造方法的反射操作, 来新建对象
      • object obj = t.newInstance(int ,String);
    • package day1901_反射;
      
      import java.lang.reflect.Constructor;
      import java.util.Scanner;
      
      public class Test2 {
          public static void main(String[] args) throws Exception {
      
              System.out.println("输入类名");
              String s = new Scanner(System.in).nextLine();
              Class<?> c = Class.forName(s);
              Object o1 = null;
              Object o2 = null;
              
              /*
               * 新建 o1,执行无参构造
               * 新建 o2,执行有参构造
               */
              
              try {
                  o1 = c.newInstance();
                  System.out.println("o1:"+o1);// 默认执行 o1 的toString
              } catch (Exception e) {
                  // TODO: handle exception
                  System.out.println("o1: 不能执行无参构造");
              }
              
              System.out.println("-----------------------------");
              
              try {
                  Constructor<?> t = c.getConstructor(int.class);
                  o2 = t.newInstance(666);
                  System.out.println("o2: "+o2);
              } catch (Exception e) {
                  // TODO: handle exception
                  System.out.println("o2: 不能执行int参数构造方法");
              }
              
          }
      }

       

 

 

  • 反射调用成员变量,
    • 获得成员变量
    • Field f = c.getDeclaredField("age");
    • 使私有变量也可以访问,
    • f.setAccssible(true);
    • 赋值
    • f.set(对象,21);给指定对象的变量赋值
    • 取值
    •  int i = (int)f.get(对象);
    • package day1901_反射;
      
      
      
      import java.lang.reflect.Field;
      
      import day0802.Student;
      
      /*
       * 跨项目不能直接访问,需要项目关联
       * 左侧选中需要关联项目的项目,右键弹出选中build path 选中项目project,
       */
      public class Test3 {
          public static void main(String[] args) throws Exception, SecurityException {
      
              // 
              Student s = new Student();
              Class<Student> c = Student.class;
              
              // 获得age变量 并赋值
              Field f = c.getDeclaredField("age");
              
              f.setAccessible(true);
              
              f.set(s, 21);
              
              System.out.println(s.getAge());
              
              int a = (int)f.get(s);
              System.out.println(a);
          }
      }

       

 

 

 

 

 

  • 反射调用成员方法
    • 获得方法
    •  Method t =  c.getMethod(方法名,参数类型列表);
    • 使得私有方法允许被调用
    • t.setAccessible(true);
    • 调用方法
    • t.invoke(对象,参数数据);
      • 让指定对象,执行该方法
      • 静态方法,第一个参数传 null
      • 没有返回值得到 null
    • package day1901_反射;
      
      
      
      import java.lang.reflect.Field;
      import java.lang.reflect.Method;
      
      import day0802.Student;
      
      /*
       * 跨项目不能直接访问,需要项目关联
       * 左侧选中需要关联项目的项目,右键弹出选中build path 选中项目project,
       */
      public class Test3 {
          public static void main(String[] args) throws Exception, SecurityException {
      
              // 
              Student s = new Student();
              Class<Student> c = Student.class;
              
              // 获得age变量 并赋值
              Field f = c.getDeclaredField("age");
              
              f.setAccessible(true);
              
              f.set(s, 21);
              
              System.out.println(s.getAge());
              
              int a = (int)f.get(s);
              System.out.println(a);
              
              
              
              // 反射测试方法
              Method gg = c.getMethod("getGender");
              
              Method sg = c.getMethod("setGender", String.class);
              
              sg.invoke(s, "");
              Object r = gg.invoke(s);
              
              System.out.println(r);
              
          }
      }

       

    • 反射的测试应用
    • package day1901_反射;
      
      import java.io.BufferedReader;
      import java.io.FileInputStream;
      import java.io.InputStreamReader;
      import java.lang.reflect.Method;
      import java.util.ArrayList;
      
      public class Runner {
          
          private static ArrayList<String> list = 
                  new ArrayList<String>();
          
          // 静态初始化快
          static {
              try {
                  
                  BufferedReader buf = 
                          new BufferedReader(
                          new InputStreamReader(
                          new FileInputStream(
                          "/Users/dingzhijie/Desktop/file3.txt"),
                          "UTF-8"));
                  
                  String line;
                  while ((line = buf.readLine()) != null) {
                      line = line.replace("\\s+", "");
                      if (line.length()==0) {
                          continue;
                      }
                      list.add(line);
                  }
                  buf.close();
                  
              } catch (Exception e) {
                  // TODO: handle exception
                  throw new RuntimeException(e);
              }
          }
          
          public static void launch() {
              try {
                  for (String s : list) {
                      // 拆分字符串
                      String[] a = s.split(";");
                      // 获得类名
                      Class<?> c = Class.forName(a[0]);
                      Object obj = c.newInstance();
                      
                      // 获得方法名
                      Method m = c.getMethod(a[1]);
                      
                      m.invoke(obj);
                  }
              } catch (Exception e) {
                  // TODO: handle exception
                  System.out.println("执行失败");
                   e.printStackTrace();
              }
          }
          
          public static void main(String[] args) {
              System.out.println("main");
              for (String string : list) {
                  System.out.println(string);
              }
              
              System.out.println("--------------");
              Runner.launch();
          }
      }

       

 

 

  • 反射是框架的底层实现原理
    • SSM

 

 

  • 注解
    • 为其他开发工具,或其他 Java 程序,提供额外的信息
    • @Override
    • public String toString(){  }
      • @Override 由编译器处理,编译器识别改注解,来对方法重新进行语法检查
  • 自定义注解
    • 要自己编写处理代码
    • package day1902_注解;
      
      import java.lang.annotation.ElementType;
      import java.lang.annotation.Retention;
      import java.lang.annotation.RetentionPolicy;
      import java.lang.annotation.Target;
      
      
      @Target(ElementType.METHOD) // 单个
      //@Target({ElementType.METHOD,ElementType.FIELD}) // 多个
      
      @Retention(RetentionPolicy.RUNTIME)
      
      
      /*
       * 元注解
       * 
       * @Target 
       *    设置注解目标: 类, 方法,成员变量, 参数...
       * 
       * @Retention
       * 保留范围: 
       *    源码文件 - 编译时注解信息被丢弃 - 编译器处理
       *    字节码   - 类被加载到内存是丢弃 - 类加载器处理
       *    运行期内存 - 在内存中存在,不会被丢弃 - 自定义注解使用
       * 
       */
      
      //定义注解 @interface
      public @interface Test {
          
          // 注解的属性
          // 如果不指定默认值, 使用时必须赋值
          
          // int id();
          int id() default 0;
          
          // 特殊的属性名, 有特殊待遇
          // 如果单独赋值, 可以不写属性名
          String value() default "";
          
          
          
      }

       

 

 

  • Junit 单元测试框架
    • Junit 第三方开源工具
    • Junit 是 Java 单元测试的事实标准
    • eclipse 集成了Junit, 可以直接在项目中引入 Junit jar 包
    • 还集成了 Junit 的运行器
    • package day1903_Junit;
      
      import org.junit.Test;
      
      /*
       * 引入Junit 开发包
       * 右键点击项目 Build path - library - 
       * add Library - Junit - Junit 4
       * 
       * 
       * 直接运行即可测试
       * 光标定位在测试方法上, 可以只执行单个测试方法
       * 定位在类上是测试单个类的代码
       * 
       */ 
      public class Test1 {
          
          @Test
          public void a(){
              System.out.println("测试a");
          }
          
          public void b(){
              System.out.println("测试b");
          }
          @Test
          public void c(){
              System.out.println("测试c");
          }
          
          @Test
          public void d(){
              System.out.println("测试d");
          }
      }

       

  • 网络爬虫
    • 抓取网页页面内容
    • 常用的网络爬虫工具
      • HttpClient
      • Jsoup
  • Jsoup
    • 第三方的开源 API
    • 需要到官网下载 Jsoup jar 文件
    • 参考官方的使用文档, 示例代码
    • package day1904_网络爬虫;
      
      import java.io.IOException;
      
      import org.jsoup.Jsoup;
      import org.junit.Test;
      
      /*
       * 引入 Jsoup 开发包
       * 右键点击项目 - Build path - add External jar 选中所有文件
       */
      public class Test1 {
          @Test
          public void test1() throws Exception {
              String s = Jsoup.connect("http://www.baidu.com")
              .execute()
              .body();
              
              System.out.println(s);
              
          }
          
          @Test
          public void test2() throws Exception {
              String s = Jsoup.connect("http://www.jd.com/")
                      .execute()
                      .body();
                      
                      System.out.println(s);
          }
      }

       

 

posted @ 2019-08-25 20:18  Dingzhijie  阅读(190)  评论(0编辑  收藏  举报