生活随笔
收集整理的這篇文章主要介紹了
Java基础day24
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Java基礎day24
- Java基礎day24-類加載器&反射&模塊化
- 1.類加載器
- 1.1類加載
- 1.2類加載器
- 1.2.1類加載器的作用
- 1.2.2JVM的類加載機制
- 1.2.3Java中的內置類加載器
- 2.反射
- 2.1反射的概述【理解】
- 2.2獲取Class類對象的三種方式【應用】
- 2.3反射獲取構造方法并使用
- 2.3.1Class類獲取構造方法對象的方法
- 2.3.2Constructor類用于創建對象的方法
- 2.4反射獲取構造方法并使用練習1【應用】
- 2.5反射獲取構造方法并使用練習2
- 2.6反射獲取成員變量并使用
- 2.6.1Class類獲取成員變量對象的方法
- 2.6.2Field類用于給成員變量賦值的方法
- 2.7反射獲取成員變量并使用練習
- 2.8反射獲取成員方法并使用
- 2.8.1Class類獲取成員方法對象的方法
- 2.8.2Method類用于執行方法的方法
- 2.9反射獲取成員方法并使用練習
- 2.10反射的案例
- 2.10.1反射練習之越過泛型檢查
- 2.10.2運行配置文件中指定類的指定方法
- 3.模塊化
- 3.1模塊化概述
- 3.2模塊的基本使用
- 3.3模塊服務的基本使用
Java基礎day24-類加載器&反射&模塊化
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.2JVM的類加載機制
- 全盤負責:就是當一個類加載器負責加載某個Class時,該Class所依賴的和引用的其他Class也將由該類加載器負責載入,除非顯示使用另外一個類加載器來載入
- 父類委托:就是當一個類加載器負責加載某個Class時,先讓父類加載器試圖加載該Class,只有在父類加載器無法加載該類時才嘗試從自己的類路徑中加載該類
- 緩存機制:保證所有加載過的Class都會被緩存,當程序需要使用某個Class對象時,類加載器先從緩存區中搜索該Class,只有當緩存區中不存在該Class對象時,系統才會讀取該類對應的二進制數據,并將其轉換成Class對象,存儲到緩存區
1.2.3Java中的內置類加載器
- Bootstrap class loader:它是虛擬機的內置類加載器,通常表示為null ,并且沒有父null
- Platform class loader:平臺類加載器可以看到所有平臺類 ,平臺類包括由平臺類加載器或其祖先定義的JavaSE平臺API,其實現類和JDK特定的運行時類
- System class loader:它也被稱為應用程序類加載器 ,與平臺類加載器不同。 系統類加載器通常用于定義應用程序類路徑,模塊路徑和JDK特定工具上的類
- 類加載器的繼承關系:System的父加載器為Platform,而Platform的父加載器為Bootstrap
1.2.4ClassLoader 中的兩個方法
方法名說明
| static ClassLoader getSystemClassLoader() | 返回用于委派的系統類加載器 |
| ClassLoader getParent() | 返回父類加載器進行委派 |
public class ClassLoaderDemo {public static void main(String
[] args
) {ClassLoader c
= ClassLoader
.getSystemClassLoader();System
.out
.println(c
);ClassLoader c2
= c
.getParent();System
.out
.println(c2
);ClassLoader c3
= c2
.getParent();System
.out
.println(c3
);}
}
2.反射
2.1反射的概述【理解】
- 是指在運行時去獲取一個類的變量和方法信息。然后通過獲取到的信息來創建對象,調用方法的一種機制。由于這種動態性,可以極大的增強程序的靈活性,程序不用在編譯期就完成確定,在運行期仍然可以擴展
2.2獲取Class類對象的三種方式【應用】
2.2.1三種方式分類
- 類名.class屬性
- 對象名.getClass()方法
- Class.forName(全類名)方法
2.2.2示例代碼
public class ReflectDemo {public static void main(String
[] args
) throws ClassNotFoundException
{Class
<Student> c1
= Student
.class;System
.out
.println(c1
);Class
<Student> c2
= Student
.class;System
.out
.println(c1
== c2
);System
.out
.println("--------");Student s
= new Student();Class
<? extends Student> c3
= s
.getClass();System
.out
.println(c1
== c3
);System
.out
.println("--------");Class
<?> c4
= Class
.forName("src.day25.Student");System
.out
.println(c1
== c4
);}
}
2.3反射獲取構造方法并使用
2.3.1Class類獲取構造方法對象的方法
方法名說明
| Constructor<?>[] getConstructors() | 返回所有公共構造方法對象的數組 |
| Constructor<?>[] getDeclaredConstructors() | 返回所有構造方法對象的數組 |
| Constructor getConstructor(Class<?>… parameterTypes) | 返回單個公共構造方法對象 |
| Constructor getDeclaredConstructor(Class<?>…parameterTypes) | 返回單個構造方法對象 |
import java
.lang
.reflect
.Constructor
;
import java
.lang
.reflect
.InvocationTargetException
;
import static java
.lang
.Class
.forName
;public class ReflectDemo01 {public static void main(String
[] args
) throws ClassNotFoundException
, NoSuchMethodException
, IllegalAccessException
, InvocationTargetException
, InstantiationException
{Class
<?> c
= forName("src.day25.Student");Constructor
<?>[] cons
= c
.getConstructors();for (Constructor con
:cons
){System
.out
.println(con
);}System
.out
.println("--------");Constructor
<?> con
= c
.getConstructor();Object obj
= con
.newInstance();System
.out
.println(obj
);}
}
2.3.2Constructor類用于創建對象的方法
方法名說明
| T newInstance(Object…initargs) | 根據指定的構造方法創建對象 |
2.4反射獲取構造方法并使用練習1【應用】
- 案例需求
通過反射獲取公共的構造方法并創建對象 - 代碼實現
public class Student {private String name
;private int age
;public String address
;public Student() {}private Student(String name
) {this.name
= name
;}Student(String name
, int age
) {this.name
= name
;this.age
= age
;}public Student(String name
, int age
, String address
) {this.name
= name
;this.age
= age
;this.address
= address
;}private void function(){System
.out
.println("function");}public void method1(){System
.out
.println("method");}public void method2(String s
){System
.out
.println("method:"+s
);}public void method3(String s
,int i
){System
.out
.println(s
+"."+i
);}@Overridepublic String
toString() {return "Student{" +"name='" + name
+ '\'' +", age=" + age
+", address='" + address
+ '\'' +'}';}
}import java
.lang
.reflect
.Constructor
;
import java
.lang
.reflect
.InvocationTargetException
;public class ReflectDemo02 {public static void main(String
[] args
) throws ClassNotFoundException
, NoSuchMethodException
, IllegalAccessException
, InvocationTargetException
, InstantiationException
{Class
<?> c
= Class
.forName("src.day25.Student");Constructor
<?> con
= c
.getConstructor(String
.class, int.class, String
.class);Object obj
= con
.newInstance("林青霞", 30, "西安");System
.out
.println(obj
);}
}
2.5反射獲取構造方法并使用練習2
- 案例需求
通過反射獲取私有構造方法并創建對象 - 代碼實現
學生類:參見上方學生類
測試類
import java
.lang
.reflect
.Constructor
;
import java
.lang
.reflect
.InvocationTargetException
;public class ReflectDemo03 {public static void main(String
[] args
) throws NoSuchMethodException
, ClassNotFoundException
, IllegalAccessException
, InvocationTargetException
, InstantiationException
{Class
<?> c
= Class
.forName("src.day25.Student");Constructor
<?> con
= c
.getDeclaredConstructor(String
.class);con
.setAccessible(true);Object o
= con
.newInstance("林青霞");System
.out
.println(o
);}
2.6反射獲取成員變量并使用
2.6.1Class類獲取成員變量對象的方法
方法名說明
| Field[] getFields() | 返回所有公共成員變量對象的數組 |
| Field[] getDeclaredFields() | 返回所有成員變量對象的數組 |
| Field getField(String name) | 返回單個公共成員變量對象 |
| Field getDeclaredField(String name) | 返回單個成員變量對象 |
import src
.day25
.Student
;import java
.lang
.reflect
.Constructor
;
import java
.lang
.reflect
.Field
;
import java
.lang
.reflect
.InvocationTargetException
;import static java
.lang
.Class
.forName
;public class ReflectDemo01 {public static void main(String
[] args
) throws ClassNotFoundException
, NoSuchFieldException
, NoSuchMethodException
, IllegalAccessException
, InvocationTargetException
, InstantiationException
{Class
<?> c
= forName("src.day25.Student");Field
[] fields
= c
.getDeclaredFields();for (Field field
: fields
) {System
.out
.println(field
);}System
.out
.println("--------");Field addressField
= c
.getField("address");Constructor
<?> con
= c
.getConstructor();Object obj
= con
.newInstance();addressField
.set(obj
,"西安");System
.out
.println(obj
);Student s
= new Student();s
.address
= "西安";System
.out
.println(s
);}
}
2.6.2Field類用于給成員變量賦值的方法
方法名說明
| voidset(Object obj,Object value) | 給obj對象的成員變量賦值為value |
2.7反射獲取成員變量并使用練習
- 案例需求
通過反射獲取成員變量并賦值 - 代碼實現
學生類:參見上方學生類
測試類
import java
.lang
.reflect
.Constructor
;
import java
.lang
.reflect
.Field
;
import java
.lang
.reflect
.InvocationTargetException
;public class ReflectDemo02 {public static void main(String
[] args
) throws ClassNotFoundException
, NoSuchMethodException
, IllegalAccessException
, InvocationTargetException
, InstantiationException
, NoSuchFieldException
{Class
<?> c
= Class
.forName("src.day25.Student");Constructor
<?> con
= c
.getConstructor();Object obj
= con
.newInstance();System
.out
.println(obj
);Field nameField
= c
.getDeclaredField("name");nameField
.setAccessible(true);nameField
.set(obj
, "林青霞");System
.out
.println(obj
);Field ageField
= c
.getDeclaredField("age");ageField
.setAccessible(true);ageField
.set(obj
,30);System
.out
.println(obj
);Field addressField
= c
.getDeclaredField("address");addressField
.setAccessible(true);addressField
.set(obj
,"西安");System
.out
.println(obj
);}
}
2.8反射獲取成員方法并使用
2.8.1Class類獲取成員方法對象的方法
方法名說明
| Method[] getMethods() | 返回所有公共成員方法對象的數組,包括繼承的 |
| Method[] getDeclaredMethods() | 返回所有成員方法對象的數組,不包括繼承的 |
| Method getMethod(String name, Class<?>…parameterTypes) | 返回單個公共成員方法對象 |
| Method getDeclaredMethod(String name, Class<?>…parameterTypes) | 返回單個成員方法對象 |
import java
.lang
.reflect
.Constructor
;
import java
.lang
.reflect
.InvocationTargetException
;
import java
.lang
.reflect
.Method
;public class ReflectDemo01 {public static void main(String
[] args
) throws ClassNotFoundException
, NoSuchMethodException
, IllegalAccessException
, InvocationTargetException
, InstantiationException
{Class
<?> c
= Class
.forName("src.day25.Student");Method
[] methods
= c
.getDeclaredMethods();for (Method method
: methods
) {System
.out
.println(method
);}System
.out
.println("--------");Method m
= c
.getMethod("method1");Constructor
<?> con
= c
.getConstructor();Object obj
= con
.newInstance();m
.invoke(obj
);}
}
2.8.2Method類用于執行方法的方法
方法名說明
| Objectinvoke(Object obj,Object… args) | 調用obj對象的成員方法,參數是args,返回值是Object類型 |
2.9反射獲取成員方法并使用練習
- 案例需求
通過反射獲取成員方法并調用 - 代碼實現
學生類:參見上方學生類
測試類
import src
.day25
.Student
;import java
.lang
.reflect
.Constructor
;
import java
.lang
.reflect
.InvocationTargetException
;
import java
.lang
.reflect
.Method
;public class ReflectDemo02 {public static void main(String
[] args
) throws ClassNotFoundException
, NoSuchMethodException
, IllegalAccessException
, InvocationTargetException
, InstantiationException
{Class
<?> c
= Class
.forName("src.day25.Student");Student s
= new Student();Constructor
<?> con
= c
.getConstructor();Object obj
= con
.newInstance();Method m1
= c
.getMethod("method1");m1
.invoke(obj
);Method m2
= c
.getMethod("method2", String
.class);m2
.invoke(obj
,"林青霞");Method m3
= c
.getMethod("method3", String
.class, int.class);Object o
= m3
.invoke(obj
,"林青霞", 30);System
.out
.println(o
);Method m4
= c
.getDeclaredMethod("function");m4
.setAccessible(true);m4
.invoke(obj
);}
}
2.10反射的案例
2.10.1反射練習之越過泛型檢查
- 案例需求
通過反射技術,向一個泛型為Integer的集合中添加一些字符串數據 - 代碼實現
import java
.lang
.reflect
.InvocationTargetException
;
import java
.lang
.reflect
.Method
;
import java
.util
.ArrayList
;public class ReflectTest01 {public static void main(String
[] args
) throws NoSuchMethodException
, InvocationTargetException
, IllegalAccessException
{ArrayList
<Integer> array
= new ArrayList<Integer>();Class
<? extends ArrayList> c
= array
.getClass();Method m
= c
.getMethod("add", Object
.class);m
.invoke(array
,"hello");m
.invoke(array
,10);m
.invoke(array
,"world");System
.out
.println(array
);}
}
2.10.2運行配置文件中指定類的指定方法
- 案例需求
通過反射運行配置文件中指定類的指定方法 - 代碼實現
import java
.io
.FileReader
;
import java
.io
.IOException
;
import java
.lang
.reflect
.Constructor
;
import java
.lang
.reflect
.InvocationTargetException
;
import java
.lang
.reflect
.Method
;
import java
.util
.Properties
;public class ReflectTest02 {public static void main(String
[] args
) throws IOException
, ClassNotFoundException
, NoSuchMethodException
, IllegalAccessException
, InvocationTargetException
, InstantiationException
{Properties prop
= new Properties();FileReader fr
= new FileReader("src\\class.txt");prop
.load(fr
);fr
.close();String className
= prop
.getProperty("className");String methodName
= prop
.getProperty("methodName");Class
<?> c
= Class
.forName(className
);Constructor
<?> con
= c
.getConstructor();Object obj
= con
.newInstance();Method m
= c
.getMethod(methodName
);m
.invoke(obj
);}
}
3.模塊化
3.1模塊化概述
Java語言隨著這些年的發展已經成為了一門影響深遠的編程語言,無數平臺,系統都采用Java語言編寫。但是,伴隨著發展,Java也越來越龐大,逐漸發展成為一門“臃腫” 的語言。而且,無論是運行一個大型的軟件系統,還是運行一個小的程序,即使程序只需要使用Java的部分核心功能, JVM也要加載整個JRE環境。 為了給Java“瘦身”,讓Java實現輕量化,Java 9正式的推出了模塊化系統。Java被拆分為N多個模塊,并允許Java程序可以根據需要選擇加載程序必須的Java模塊,這樣就可以讓Java以輕量化的方式來運行
其實,Java 7的時候已經提出了模塊化的概念,但由于其過于復雜,Java 7,Java 8都一直未能真正推出,直到Java9才真正成熟起來。對于Java語言來說,模塊化系統是一次真正的自我革新,這種革新使得“古老而龐大”的Java語言重新煥發年輕的活力
3.2模塊的基本使用
3.3模塊服務的基本使用
總結
以上是生活随笔為你收集整理的Java基础day24的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。