Reflection(反射)是被視爲動態語言的關鍵,反射機制容許程序在執行期 藉助於Reflection API取得任何類的內部信息,並能直接操做任意對象的內 部屬性及方法。java
加載完類以後,在堆內存的方法區中就產生了一個Class類型的對象(一個類只有一個Class對象),這個對象就包含了完整的類的結構信息。咱們能夠經過這個對象看到類的結構。這個對象就像一面鏡子,透過這個鏡子看到類的結構,因此,咱們形象的稱之爲:反射。mysql
正常方式: 引入須要的包名稱 → 經過new實例化對象 → 取得實例化對象
反射方式: 經過實例化對象 → getClass()方法 → 獲得完整的包名稱面試
Java反射機制提供的功能算法
在運行時判斷任意一個對象所屬的類。
在運行時構造任意一個類的對象。
在運行時判斷任意一個類所具備的成員變量和方法。
在運行時獲取泛型信息。
在運行時調用任意一個對象的成員變量和方法。
在運行時處理註解。
生成動態代理。spring
public class Person { private String name; public int age; public void show() { System.out.println("您好!世界"); } private String showNation(String nation){ System.out.println("個人國際是:" + nation); return nation; } private Person(String name) { this.name = name; } ..... } public void test2() throws Exception { Class clazz = Person.class; // 1.經過反射,建立Person類的對象 Constructor cons = clazz.getConstructor(String.class, int.class); Object obj = cons.newInstance("Tom", 12); Person p = (Person) obj; System.out.println(p.toString()); // 2.經過反射,調用指定的屬性、方法、對象 // 調屬性 Field age = clazz.getDeclaredField("age"); age.set(p,10); System.out.println(p.toString()); // 調方法 Method method = clazz.getDeclaredMethod("show"); method.invoke(p); // 經過反射是能夠調用私有的屬性、方法、構造器 // 調用私有構造器 Constructor cons1 = clazz.getDeclaredConstructor(String.class); cons1.setAccessible(true); Person p1 = (Person) cons1.newInstance("Jerry"); System.out.println(p1); // 調用私有方法 Field name = clazz.getDeclaredField("name"); name.setAccessible(true); name.set(p1,"Han"); System.out.println(p1); // 調用私有方法 Method method1 = clazz.getDeclaredMethod("showNation", String.class); method1.setAccessible(true); String invoke = (String) method1.invoke(p1, "中國"); System.out.println(invoke); }./*歡迎加入java交流Q君樣:909038429一塊兒吹水聊天
java.lang.Class類的理解
類的加載過程:程序通過java.exe命令之後,會生成一個或多個字節碼文件(.class),接着使用java.exe命令對字節碼進行解釋運行。至關與將某個字節碼文件加載到內存中,此過程稱爲類的加載。加載到內存中的類,咱們稱之爲運行時類,此運行時類,就做爲Class的一個實例。
Class的實例就是對應着一個運行時類。
加載到內存中的運行時類,會緩存必定的時間。在此時間以內,咱們能夠經過不一樣方式來獲取從運行時類。sql
// 獲取Class的實例的方法 public void test3() throws ClassNotFoundException { // 方式一:調用運行時類的屬性.class Class clazz1 = Person.class; // 方式二:經過運行時類的對象 Person person = new Person(); Class clazz2 = person.getClass(); // 方法三:調用Class的靜態方法forName(String classPath) Class clazz3 = Class.forName("com.tyt.java.Person"); // 方式四:類的加載器 ClassLoader ClassLoader classLoader = ReflectionTest.class.getClassLoader(); Class clazz4 = classLoader.loadClass("com.tyt.java.Person"); System.out.println(clazz1 == clazz2); System.out.println(clazz2 == clazz3); System.out.println(clazz3 == clazz4); }
Class實例能夠是那些結構的說明:數組
public void test5() { Class c1 = Object.class; Class c2 = Comparable.class; Class c3 = String[].class; Class c4 = int[][].class; Class c5 = ElementType.class; Class c6 = Override.class; Class c7 = int.class; Class c8 = void.class; Class c9 = Class.class; int[] a = new int[10]; int[] b = new int[100]; Class c10 = a.getClass(); Class c11 = b.getClass(); // 只要數組元素類型與維度同樣,就是同一個Class System.out.println(c10 == c11);// true }
使用Properties:用於讀取配置文件。緩存
// 目錄結構 // |--module // |---stc // |----com.tyt.java // |-----PropertiesTest.java // |-----jdbc1.properties // |--jdbc.properties public void test2() { String user = null; String passwored = null; FileInputStream inputStream = null; try { Properties properties = new Properties(); // 讀取配置方式一: // inputStream = new FileInputStream("jdbc.properties"); // properties.load(inputStream); // 讀取配置方式二:使用ClassLoader // 配置文件默認識別爲:當前module的src下 ClassLoader classLoader = ClassLoaderTest.class.getClassLoader(); InputStream inputStream1 = classLoader.getResourceAsStream("jdbc1.properties"); properties.load(inputStream1); user = properties.getProperty("user"); passwored = properties.getProperty("passwored"); System.out.println("user = " + user + ",passwored = " + passwored); } catch (IOException e) { e.printStackTrace(); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } }
最新2020整理收集的一些高頻面試題(都整理成文檔),有不少乾貨,包含mysql,netty,spring,線程,spring cloud、jvm、源碼、算法等詳細講解,也有詳細的學習規劃圖,面試題整理等,須要獲取這些內容的朋友請加Q君樣:909038429
/./*歡迎加入java交流Q君樣:909038429一塊兒吹水聊天jvm