java - day019 - 反射

網絡程序,難點在線程css

  • 反射 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); } }
相關文章
相關標籤/搜索