Jenkins配合gitlab實現程式碼提交觸發構建
阿新 • • 發佈:2020-08-18
反射:框架設計的靈魂
名詞解釋: * 框架:半成品軟體。可以在框架的基礎上進行軟體開發,簡化編碼 * 反射:將類的各個組成部分封裝為其他物件,這就是反射機制
使用反射優點: 1. 可以在程式執行過程中,操作這些物件。 2. 可以解耦,提高程式的可擴充套件性。
獲取Class物件的方式
1. Class.forName("全類名"):將位元組碼檔案載入進記憶體,返回Class物件 * 多用於配置檔案,將類名定義在配置檔案中。讀取檔案,載入類 2. 類名.class:通過類名的屬性class獲取 * 多用於引數的傳遞3. 物件.getClass():getClass()方法在Object類中定義著。 * 多用於物件的獲取位元組碼的方式
三種方式獲取Class物件程式碼
1 package demo14.reflect; 2 3 public class demo01 { 4 public static void main(String[] args) throws ClassNotFoundException { 5 // 1 Class.forName("全類名") 6 Class aClass = Class.forName("demo14.reflect.Person");7 System.out.println(aClass); 8 9 // 2 類名.class 10 Class bClass = Person.class; 11 System.out.println(bClass); 12 13 // 3 物件.getClass() 14 Person person = new Person(); 15 Class cClass = person.getClass(); 16 System.out.println(cClass);17 18 //檢查三種方式獲取的Class物件是否一致 19 System.out.println(aClass == bClass); 20 System.out.println(bClass == cClass); 21 22 } 23 }
執行結果
# 注:同一個位元組碼檔案(*.class)在一次程式執行過程中,只會被載入一次,不論通過哪一種方式獲取的Class物件都是同一個。
Class物件功能
1. 獲取成員變數們 * Field[] getFields() :獲取所有public修飾的成員變數 * Field getField(String name) 獲取指定名稱的 public修飾的成員變數 * Field[] getDeclaredFields() 獲取所有的成員變數,不考慮修飾符 * Field getDeclaredField(String name) 2. 獲取構造方法們 * Constructor<?>[] getConstructors() * Constructor<T> getConstructor(類<?>... parameterTypes) * Constructor<T> getDeclaredConstructor(類<?>... parameterTypes) * Constructor<?>[] getDeclaredConstructors() 3. 獲取成員方法們: * Method[] getMethods() * Method getMethod(String name, 類<?>... parameterTypes) * Method[] getDeclaredMethods() * Method getDeclaredMethod(String name, 類<?>... parameterTypes) 4. 獲取全類名 * String getName()
Field:成員變數 * 操作: 1. 設定值 * void set(Object obj, Object value) 2. 獲取值 * get(Object obj) 3. 忽略訪問許可權修飾符的安全檢查 * setAccessible(true):暴力反射 Constructor:構造方法 * 建立物件: * T newInstance(Object... initargs) * 如果使用空引數構造方法建立物件,操作可以簡化:Class物件的newInstance方法 Method:方法物件 * 執行方法: * Object invoke(Object obj, Object... args) * 獲取方法名稱: * String getName:獲取方法名
Class物件獲取成員變數、對成員變數值進行獲取與設定程式碼示例
1 package demo14.reflect; 2 3 import java.lang.reflect.Field; 4 5 public class demo02 { 6 public static void main(String[] args) throws Exception { 7 /* 8 * Field[] getFields() :獲取所有public修飾的成員變數 9 * Field getField(String name) 獲取指定名稱的 public修飾的成員變數 10 11 * Field[] getDeclaredFields() 獲取所有的成員變數,不考慮修飾符 12 * Field getDeclaredField(String name) 獲取指定名稱的成員變數 不考慮修飾符 13 */ 14 15 // 1 獲取Class物件 16 Class cls = Class.forName("demo14.reflect.Person"); 17 18 // 2 獲取成員變數方法 19 // 2.1 獲取所有的public修飾的成員變數 20 Field[] fields = cls.getFields(); 21 for (Field field : fields) { 22 System.out.println(field); 23 } 24 // 2.2 獲取指定的public修飾的成員變數 25 Field a = cls.getField("a"); 26 System.out.println(a); 27 //2.2.1獲取和設定Field值 28 Person person = new Person(); 29 Object o = a.get(person); 30 System.out.println(o); 31 a.set(person, "kelvin"); 32 System.out.println(person); 33 34 // 2.3 獲取所有的成員變數 35 Field[] declaredFields = cls.getDeclaredFields(); 36 for (Field field : declaredFields) { 37 System.out.println(field); 38 } 39 40 // 2.4 獲取指定的成員變數 41 Field d = cls.getDeclaredField("d"); 42 System.out.println(d); 43 //忽略訪問許可權修飾符的安全檢查(暴力反射) 44 d.setAccessible(true); 45 //2.4.1獲取和設定非public修飾的Field值 46 Person person1=new Person(); 47 Object o1 = d.get(person1); 48 System.out.println(o1); 49 d.set(person1,"jack"); 50 System.out.println(person1); 51 } 52 }
Class物件獲取構造方法,並根據構造方法建立物件
1 package demo14.reflect; 2 3 import java.lang.reflect.Constructor; 4 import java.util.Arrays; 5 6 public class demo03 { 7 public static void main(String[] args) throws Exception { 8 /* 9 Constructor<?>[] getConstructors() 10 Constructor<T> getConstructor(類<?>... parameterTypes) 11 12 Constructor<T> getDeclaredConstructor(類<?>... parameterTypes) 13 Constructor<?>[] getDeclaredConstructors() 14 15 建立物件: 16 T newInstance(Object... initargs) 17 如果使用空引數構造方法建立物件,操作可以簡化:Class物件的newInstance方法 18 19 */ 20 21 Class cls = Class.forName("demo14.reflect.Person"); 22 // 1 獲取所有public修飾的構造方法 23 Constructor[] constructors = cls.getConstructors(); 24 System.out.println(Arrays.toString(constructors)); 25 26 // 2 獲取指定的引數的構造方法 27 Constructor constructor = cls.getConstructor(String.class, int.class); 28 System.out.println(constructor); 29 // 2.1 使用有參構造方法建立物件 30 Object kelvin = constructor.newInstance("kelvin", 23); 31 System.out.println(kelvin); 32 33 // 3 獲取無參構造方法 34 Constructor constructor1 = cls.getConstructor(); 35 System.out.println(constructor1); 36 // 3.1 使用無參構造方法建立物件 37 // 方式一 38 Object o = constructor1.newInstance(); 39 System.out.println(o); 40 // 方式二 41 Object o1 = cls.newInstance(); 42 System.out.println(o1); 43 44 45 } 46 }
Class獲取成員方法並執行
1 package demo14.reflect; 2 3 import java.lang.reflect.Method; 4 import java.util.Arrays; 5 6 public class demo04 { 7 public static void main(String[] args) throws Exception { 8 /* 9 Method[] getMethods() 10 Method getMethod(String name, 類<?>... parameterTypes) 11 12 Method[] getDeclaredMethods() 13 Method getDeclaredMethod(String name, 類<?>... parameterTypes) 14 15 執行方法: 16 Object invoke(Object obj, Object... args) 17 獲取方法名稱: 18 String getName:獲取方法名 19 20 */ 21 Class cls = Class.forName("demo14.reflect.Person"); 22 23 // 1 獲取所有的public成員方法 24 Method[] methods = cls.getMethods(); 25 System.out.println(Arrays.toString(methods)); 26 // 2 獲取指定的public成員帶參方法 27 Person person = new Person(); 28 Method run = cls.getMethod("run", String.class); 29 run.invoke(person, "kelvin"); 30 // 3 獲取指定的public修飾無參成員方法 31 Method run1 = cls.getMethod("run"); 32 run1.invoke(person); 33 34 // 4 獲取private修飾的成員方法 35 Method eat = cls.getDeclaredMethod("eat"); 36 // 暴力反射 37 eat.setAccessible(true); 38 eat.invoke(person); 39 } 40 }
反射應用例項
藉助配置檔案,配置檔案可以配置類和方法。
1 package demo14.reflect; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.lang.reflect.Method; 6 import java.util.Properties; 7 8 public class demotest { 9 /* 10 不能改變該類的任何程式碼。可以建立任意類的物件,可以執行任意方法 11 */ 12 public static void main(String[] args) throws Exception { 13 Properties pro = new Properties(); 14 15 ClassLoader classLoader = demotest.class.getClassLoader(); 16 InputStream resourceAsStream = classLoader.getResourceAsStream("demo14/reflect/pro.properties"); 17 pro.load(resourceAsStream); 18 19 String className = pro.getProperty("className"); 20 String classMethod = pro.getProperty("classMethod"); 21 22 Class cls = Class.forName(className); 23 Method method = cls.getMethod(classMethod); 24 25 Object o = cls.newInstance(); 26 method.invoke(o); 27 } 28 }
配置檔案
className=demo14.reflect.Student
classMethod=study