mysql索引學習
1. 類載入器
1.1 類載入
類載入的描述:
當程式要使用某個類時,如果該類還未被載入到記憶體中,則系統會通過類的載入,類的連線,類的初始化這三個步驟來對類進行初始化。如果不出現意外情況,JVM將會連續完成這三個步驟,所以有時也把這三個步驟統稱為類載入或者類初始化
類的載入:
就是指將class檔案讀入記憶體,併為之建立一個 java.lang.Class 物件
任何類被使用時,系統都會為之建立一個 java.lang.Class 物件
類的連線:
驗證階段:用於檢驗被載入的類是否有正確的內部結構,並和其他類協調一致
準備階段:負責為類的類變數分配記憶體,並設定預設初始化值
解析階段:將類的二進位制資料中的符號引用替換為直接引用類的初始化,在該階段,主要就是對類變數進行初始化
類的初始化步驟:
假如類還未被載入和連線,則程式先載入並連線該類
假如該類的直接父類還未被初始化,則先初始化其直接父類
假如類中有初始化語句,則系統依次執行這些初始化語句
注意:在執行第2個步驟的時候,系統對直接父類的初始化步驟也遵循初始化步驟1-3
類的初始化時機:
建立類的例項
呼叫類的類方法
訪問類或者介面的類變數,或者為該類變數賦值
使用反射方式來強制建立某個類或介面對應的java.lang.Class物件
初始化某個類的子類
直接使用java.exe命令來執行某個主類
1.2 類載入器
1.2.1 類載入器的作用
負責將.class檔案載入到記憶體中,併為之生成對應的 java.lang.Class 物件。雖然我們不用過分關心類載入機制,但是瞭解這個機制我們就能更好的理解程式的執行!
1.2.2 JVM的類載入機制
全盤負責:
就是當一個類載入器負責載入某個Class時,該Class所依賴的和引用的其他Class也將由該類載入器負責載入,除非顯式使用另外一個類載入器來載入
父類委託:
就是當一個類載入器負責載入某個Class時,先讓父類載入器試圖載入該Class,只有在父類載入器無法載入該類時才嘗試從自己的類路徑中載入該類
快取機制:
保證所有載入過的Class都會被快取,當程式需要使用某個Class物件時,類載入器先從快取區中搜索該Class,只有當快取區中不存在該Class物件時,系統才會讀取該類對應的二進位制資料,並將其轉換成Class物件,儲存到快取區
1.2.3 Java中的內建類載入器
Bootstrap class loader:它是虛擬機器的內建類載入器,通常表示為null ,並且沒有父null
Platform class loader:平臺類載入器可以看到所有平臺類 ,平臺類包括由平臺類載入器或其祖先定義的JavaSE平臺API,其實現類和JDK特定的執行時類
System class loader:它也被稱為應用程式類載入器 ,與平臺類載入器不同。 系統類載入器通常用於定義應用程式類路徑,模組路徑和JDK特定工具上的類類載入器的繼承關係:System的父載入器為Platform,而Platform的父載入器為Bootstrap
1.2.4 ClassLoader 中的兩個方法
方法分類:
1 static ClassLoader getSystemClassLoader() 返回用於委派的系統類載入器
1 ClassLoader getParent() 返回父類載入器進行委派
1 public class ClassLoaderDemo { 2 public static void main(String[] args) { 3 //static ClassLoader getSystemClassLoader() 返回用於委派的系統類載入器 4 ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); 5 6 //ClassLoader getParent() 返回父類載入器進行委派 7 ClassLoader parent = systemClassLoader.getParent(); 8 System.out.println(parent); //PlatformClassLoader@7c30a502 9 10 ClassLoader parent2 = parent.getParent(); 11 System.out.println(parent2); //null 12 } 13 }
2. 反射
2.1 反射的概述
是指在執行時去獲取一個類的變數和方法資訊。然後通過獲取到的資訊來建立物件,呼叫方法的一種機制。
由於這種動態性,可以極大的增強程式的靈活性,程式不用在編譯期就完成確定,在執行期仍然可以擴充套件
2.2 獲取Class類物件的三種方式
三種方式分類:
(1)類名.class屬性
(2)物件名.getClass()方法
(3)Class.forName(全類名)方法
1 示例: 2 public class ReflectDemo { 3 public static void main(String[] args) throws ClassNotFoundException { 4 //1.使用類的class屬性來獲取該類對應的Class物件 5 Class<Student> c1 = Student.class; 6 System.out.println(c1); //class com.itheima_02.Student 7 8 Class<Student> c2 = Student.class; 9 System.out.println(c1==c2); 10 System.out.println("--------"); 11 12 13 //2.呼叫物件的getClass()方法,返回該物件所屬類對應的Class物件 14 Student s=new Student(); 15 Class<? extends Student> c3 = s.getClass(); 16 System.out.println(c3==c1); 17 System.out.println("--------"); 18 19 //3.使用Class類中的靜態方法forName(String className) 20 Class<?> c4 = Class.forName("com.itheima_02.Student"); 21 System.out.println(c4==c1); 22 } 23 }
2.3 反射獲取構造方法並使用
2.3.1 Class類獲取構造方法物件的方法
方法分類:
1 Constructor<?>[] getConstructors() 返回所有公共構造方法物件的陣列 2 3 Constructor<?>[] getDeclaredConstructors() 返回所有構造方法物件的陣列 4 5 Constructor getConstructor(Class<?>... parameterTypes) 返回單個公共構造方法物件 6 7 Constructor getDeclaredConstructor(Class<?>...parameterTypes) 返回單個構造方法物件
2.3.2 Constructor類用於建立物件的方法
1 T newInstance(Object...initargs) 根據指定的構造方法建立物件
1 學生類: 2 public class Student { 3 //成員變數:1個私有、1個預設、1個公共 4 private String name; 5 int age; 6 public String address; 7 8 //構造方法:1個私有、1個預設、2個公共 9 public Student() { 10 } 11 12 private Student(String name) { 13 this.name = name; 14 } 15 16 Student(String name, int age) { 17 this.name = name; 18 this.age = age; 19 } 20 21 public Student(String name, int age, String address) { 22 this.name = name; 23 this.age = age; 24 this.address = address; 25 } 26 27 //成員方法:1個私有,4個公共 28 private void function() { 29 System.out.println("function"); 30 } 31 32 public void method1() { 33 System.out.println("method"); 34 } 35 36 public void method2(String s) { 37 System.out.println("method:" + s); 38 } 39 40 public String method3(String s, int i) { 41 return s + "," + i; 42 } 43 44 @Override 45 public String toString() { 46 return "Student{" + 47 "name='" + name + '\'' + 48 ", age=" + age + 49 ", address='" + address + '\'' + 50 '}'; 51 } 52 }
1 示例: 2 import java.lang.reflect.Constructor; 3 import java.lang.reflect.InvocationTargetException; 4 5 public class ReflectDemo { 6 public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { 7 //獲取Class類物件 8 Class<?> c = Class.forName("com.itheima_02.Student"); 9 10 // 1. Constructor<?>[] getConstructors() 返回所有公共構造方法物件的陣列 11 //Constructor<?>[] cons = c.getConstructors(); 12 13 //遍歷----所有公共構造方法物件的陣列: 14 //public com.itheima_02.Student(java.lang.String,int,java.lang.String) 15 //public com.itheima_02.Student() 16 17 18 // 2. Constructor<?>[] getDeclaredConstructors() 返回所有構造方法物件的陣列 19 //Constructor<?>[] cons = c.getDeclaredConstructors(); 20 21 //遍歷----所有構造方法物件的陣列: 22 //public com.itheima_02.Student(java.lang.String,int,java.lang.String) 3引數 23 //com.itheima_02.Student(java.lang.String,int) 2引數 24 //private com.itheima_02.Student(java.lang.String) 1引數 25 //public com.itheima_02.Student() 無參 26 27 //遍歷: 28 /*for (Constructor<?> con:cons) { 29 System.out.println(con); 30 }*/ 31 32 // 3. Constructor getConstructor(Class<?>... parameterTypes) 返回單個公共構造方法物件 33 // 4. Constructor getDeclaredConstructor(Class<?>...parameterTypes) 返回單個構造方法物件 34 //引數:你要獲取的構造方法的引數的個數和資料型別對應的位元組碼檔案物件 35 Constructor<?> con = c.getConstructor(); //獲取單個公共無參構造方法 36 37 // T newInstance(Object...initargs) 根據指定的構造方法建立物件 38 Object obj = con.newInstance(); 39 System.out.println(obj); //com.itheima_02.Student@7c30a502 40 } 41 }
2.4 反射獲取構造方法並使用練習1
1 學生類: 2 public class Student { 3 //成員變數:1個私有、1個預設、1個公共 4 private String name; 5 int age; 6 public String address; 7 8 //構造方法:1個私有、1個預設、2個公共 9 public Student() { 10 } 11 12 private Student(String name) { 13 this.name = name; 14 } 15 16 Student(String name, int age) { 17 this.name = name; 18 this.age = age; 19 } 20 21 public Student(String name, int age, String address) { 22 this.name = name; 23 this.age = age; 24 this.address = address; 25 } 26 27 //成員方法:1個私有,4個公共 28 private void function() { 29 System.out.println("function"); 30 } 31 32 public void method1() { 33 System.out.println("method"); 34 } 35 36 public void method2(String s) { 37 System.out.println("method:" + s); 38 } 39 40 public String method3(String s, int i) { 41 return s + "," + i; 42 } 43 44 @Override 45 public String toString() { 46 return "Student{" + 47 "name='" + name + '\'' + 48 ", age=" + age + 49 ", address='" + address + '\'' + 50 '}'; 51 } 52 }
1 案例需求: 2 通過反射獲取公共的構造方法並建立物件 3 4 import java.lang.reflect.Constructor; 5 import java.lang.reflect.InvocationTargetException; 6 7 public class ReflectDemo01 { 8 public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { 9 //獲取Class類 10 Class<?> c = Class.forName("com.itheima_02.Student"); 11 12 //獲取指定的公共構造方法(指定有3個引數的構造方法) 13 //基本資料型別也可以通過.class得到對應的Class型別 14 Constructor<?> con = c.getConstructor(String.class,int.class,String.class); 15 16 //用指定的構造方法建立物件 17 Object obj = con.newInstance("令狐沖",23,"華山"); 18 System.out.println(obj); 19 } 20 }
2.5 反射獲取構造方法並使用練習2
1 案例需求: 2 通過反射獲取私有構造方法並建立物件 3 4 import java.lang.reflect.Constructor; 5 import java.lang.reflect.InvocationTargetException; 6 7 public class ReflectDemo04 { 8 public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { 9 //獲取Class類 10 Class<?> c = Class.forName("com.itheima_02.Student"); 11 12 //獲取指定私有構造方法 13 Constructor<?> con = c.getDeclaredConstructor(String.class); 14 15 //暴力反射: 16 //public void setAccessible(boolean flag): 值為true,取消訪問檢查 17 con.setAccessible(true); 18 19 //使用私有構造方法建立物件 20 Object obj = con.newInstance("令狐沖"); 21 System.out.println(obj); //Student{name='令狐沖', age=0, address='null'} 22 } 23 }
2.6 反射獲取成員變數並使用
2.6.1 Class類獲取成員變數物件的方法
方法分類:
1 Field[] getFields() 返回所有公共成員變數物件的陣列 2 3 Field[] getDeclaredFields() 返回所有成員變數物件的陣列 4 5 Field getField(String name) 返回單個公共成員變數物件 6 7 Field getDeclaredField(String name) 返回單個成員變數物件
2.6.2 Field類用於給成員變數賦值的方法
1 void set(Object obj,Object value) 給obj物件的成員變數賦值為value
1 示例: 2 import java.lang.reflect.Constructor; 3 import java.lang.reflect.Field; 4 import java.lang.reflect.InvocationTargetException; 5 6 public class ReflectDemo03 { 7 public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { 8 9 //獲取Class類物件 10 Class<?> c = Class.forName("com.itheima_02.Student"); 11 12 //1. Field[] getFields() 返回所有公共成員變數物件的陣列 13 //Field[] fields = c.getFields(); 14 15 //2. Field[] getDeclaredFields() 返回所有成員變數物件的陣列 16 Field[] fields = c.getDeclaredFields(); 17 18 for (Field field:fields) { 19 System.out.println(field); 20 } 21 System.out.println("--------"); 22 //3. Field getField(String name) 返回單個公共成員變數物件 23 //4. Field getDeclaredField(String name) 返回單個成員變數物件 24 Field addressField = c.getField("address"); 25 26 //獲取無參構造方法,建立物件 27 Constructor<?> con = c.getConstructor(); 28 Object obj = con.newInstance(); 29 30 addressField.set(obj,"西安"); //給obj的成員變數addressField賦值為西安 31 System.out.println(obj); 32 } 33 }
2.7 反射獲取成員變數並使用練習
1 案例需求: 2 通過反射獲取成員變數並賦值 3 4 import java.lang.reflect.Constructor; 5 import java.lang.reflect.Field; 6 import java.lang.reflect.InvocationTargetException; 7 8 public class ReflectDemo04 { 9 public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException { 10 //獲取Class類 11 Class<?> c = Class.forName("com.itheima_02.Student"); 12 13 //獲取無參構造方法 14 Constructor<?> con = c.getConstructor(); 15 //使用無參構造方法,建立物件 16 Object obj = con.newInstance(); 17 18 //獲取成員變數,並賦值 19 20 //s.name="令狐沖"; 21 Field nameField = c.getDeclaredField("name"); 22 nameField.setAccessible(true); 23 nameField.set(obj,"令狐沖"); 24 System.out.println(obj); 25 26 //s.age=23; 27 Field ageField = c.getDeclaredField("age"); 28 ageField.setAccessible(true); 29 ageField.set(obj,23); 30 System.out.println(obj); 31 32 //s.address="華山" 33 Field addressField = c.getDeclaredField("address"); 34 addressField.setAccessible(true); 35 addressField.set(obj,"華山"); 36 System.out.println(obj); 37 } 38 }
2.8 反射獲取成員方法並使用
2.8.1 Class類獲取成員方法物件的方法
方法分類:
1 Method[] getMethods() 返回所有公共成員方法物件的陣列,包括繼承的 2 3 Method[] getDeclaredMethods() 返回所有成員方法物件的陣列,不包括繼承的 4 5 Method getMethod(String name, Class<?>...parameterTypes) 返回單個公共成員方法物件 6 7 Method getDeclaredMethod(String name, Class<?>...parameterTypes) 返回單個成員方法物件
2.8.2 Method類用於執行方法的方法
1 Object invoke(Object obj,Object... args) 呼叫obj物件的成員方法,引數是args,返回值是Object型別
1 示例: 2 import java.lang.reflect.Constructor; 3 import java.lang.reflect.InvocationTargetException; 4 import java.lang.reflect.Method; 5 6 public class ReflectDemo05 { 7 public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { 8 //獲取Class類 9 Class<?> c = Class.forName("com.itheima_02.Student"); 10 11 //獲取無參構造方法,建立物件 12 Constructor<?> con = c.getDeclaredConstructor(); 13 Object obj = con.newInstance(); 14 15 16 //1. Method[] getMethods() 返回所有公共成員方法物件的陣列,包括繼承的 17 //Method[] methods = c.getMethods(); 18 19 //2. Method[] getDeclaredMethods() 返回所有成員方法物件的陣列,不包括繼承的 20 Method[] methods = c.getDeclaredMethods(); 21 22 for (Method method:methods) { 23 System.out.println(method); 24 } 25 System.out.println("--------"); 26 27 //3. Method getMethod(String name, Class<?>...parameterTypes) 返回單個公共成員方法物件 28 //4. Method getDeclaredMethod(String name, Class<?>...parameterTypes) 返回單個成員方法物件 29 Method m = c.getMethod("method1"); 30 31 32 //在類或介面上提供有關單一方法的資訊和訪問許可權 33 //Object invoke(Object obj,Object... args) 呼叫obj物件的成員方法,引數是args,返回值是Object型別 34 35 //Object:返回值型別 36 // obj:呼叫方法的物件 37 // args:方法需要的引數 38 m.invoke(obj); 39 } 40 }
2.9 反射獲取成員方法並使用練習
1 案例需求: 2 通過反射獲取成員方法並呼叫 3 4 import java.lang.reflect.Constructor; 5 import java.lang.reflect.InvocationTargetException; 6 import java.lang.reflect.Method; 7 8 public class ReflectDemo06 { 9 public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { 10 //獲取Class類 11 Class<?> c = Class.forName("com.itheima_02.Student"); 12 13 //獲取無參構造方法,建立物件 14 Constructor<?> con = c.getDeclaredConstructor(); 15 Object obj = con.newInstance(); 16 17 //s.method1(); 18 Method m1 = c.getMethod("method1"); 19 m1.invoke(obj); 20 21 //s.method2(); 22 Method m2 = c.getMethod("method2",String.class); 23 m2.invoke(obj,"令狐沖"); 24 25 //s.method3(); //該方法有返回值 26 Method m3= c.getMethod("method3",String.class,int.class); 27 Object o = m3.invoke(obj, "令狐沖", 23); 28 System.out.println(o); 29 30 //s.function(); 31 Method f = c.getDeclaredMethod("function"); 32 f.setAccessible(true); 33 f.invoke(obj); 34 } 35 }
2.10 反射的案例
2.10.1 反射練習之越過泛型檢查
1 public void test() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException { 2 System.out.println("ok"); 3 4 ArrayList<Integer> array = new ArrayList<>(); 5 6 Class<? extends ArrayList> arrayClass = array.getClass(); 7 8 Method add = arrayClass.getMethod("add", Object.class); 9 10 add.invoke(array, "hello"); 11 add.invoke(array, "world"); 12 13 System.out.println(array); 14 15 System.out.println("--------"); 16 17 ArrayList<Integer> arrayList = new ArrayList<>(); 18 19 Class<? extends ArrayList> c = arrayList.getClass(); 20 21 //獲取構造方法,建立物件 22 Constructor<?> con = c.getDeclaredConstructor(); 23 Object obj = con.newInstance(); 24 25 Method m = c.getMethod("add",Object.class); 26 m.setAccessible(true); 27 m.invoke(obj,"Hello"); 28 m.invoke(obj,"World"); 29 m.invoke(obj,"java"); 30 31 System.out.println(obj); 32 33 }
2.10.2 執行配置檔案中指定類的指定方法
1 學生類: 2 public class Student { 3 public void study() { 4 System.out.println("青出於藍而勝於藍"); 5 } 6 }
1 教師類: 2 public class Teacher { 3 public void teach() { 4 System.out.println("師者傳道受業解惑也"); 5 } 6 }
1 案例需求: 2 通過反射執行配置檔案中指定類的指定方法 3 4 import java.io.FileReader; 5 import java.io.IOException; 6 import java.lang.reflect.Constructor; 7 import java.lang.reflect.InvocationTargetException; 8 import java.lang.reflect.Method; 9 import java.util.Properties; 10 11 //通過反射執行配置檔案中指定類的指定方法 12 public class ReflectDemo { 13 public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException { 14 //建立Properties物件 15 Properties pre = new Properties(); 16 //建立輸入流物件 17 FileReader fr = new FileReader("myreflect\\Class.txt"); 18 //檔案載入到集合 19 pre.load(fr); 20 fr.close(); 21 22 /*Class.txt檔案內的內容: 23 className=com.itheima_04.Student 24 methodName=study 25 //教師類同理,只需要修改Class.txt檔案內的資料 26 */ 27 28 29 //通過鍵獲取值 30 String className = pre.getProperty("className"); 31 String methodName = pre.getProperty("methodName"); 32 33 //通過反射來使用 34 Class<?> c = Class.forName(className); //com.itheima_04.Student 35 36 Constructor<?> con = c.getConstructor(); 37 Object obj = con.newInstance(); 38 39 Method m = c.getDeclaredMethod(methodName);//study 40 m.invoke(obj); 41 } 42 }