一、Java執行Class的概述
Java是一種面向對象的編程語言,它的核心思想之一就是通過Class來實現面向對象的編程。在Java中,每個類都是由一個或多個Class組成的,Class代表了一個Java類或者介面的元信息。Java程序在執行時需要載入和連接Class,然後才能夠對其進行實例化和調用操作。因此,在Java中,以Java執行Class為中心是非常重要的。
二、Java執行Class的分類
Java執行Class可以分為以下三種類型:
1.系統類
系統類是由Java虛擬機(JVM)提供的類,例如java.lang.Object、java.lang.String等。這些類通常位於JVM的class路徑下,可以被整個JVM使用。
public class SystemClass { public static void main(String[] args) { Object obj = new Object(); String str = new String("Java"); System.out.println(obj.getClass()); System.out.println(str.getClass()); } }
2.應用類
應用類是用戶自定義的類,它們通常被應用程序開發者編寫並打包成jar文件,然後在應用程序中進行使用。應用類可以通過Java的類載入機制進行載入。
public class ApplicationClass { public static void main(String[] args) { MyClass myClass = new MyClass(); System.out.println(myClass.getClass()); } } class MyClass { // some code... }
3.擴展類
擴展類是由JVM擴展提供的類,例如javax.swing.JFrame、javax.swing.JButton等。這些類通常位於JRE的擴展目錄下,可以被整個JVM使用。擴展類也可以通過Java的類載入機制進行載入。
public class ExtensionClass { public static void main(String[] args) { JFrame frame = new JFrame(); JButton button = new JButton("Click me"); frame.add(button); frame.setSize(300, 200); frame.setVisible(true); System.out.println(frame.getClass()); System.out.println(button.getClass()); } }
三、Java執行Class的載入
Java程序在執行時,需要從磁碟、網路等地方獲取Class位元組碼並將其載入到內存中,然後才能夠對其進行實例化和調用操作。Java使用類載入器來完成Class的載入任務。類載入器可以分為以下三種:
1.引導類載入器
引導類載入器是虛擬機自身的一部分,它負責載入JVM需要的基礎類,如java.lang.Object、java.lang.String等。這些類在整個Java應用程序中都是可以被訪問的。
2.擴展類載入器
擴展類載入器負責載入JRE擴展目錄下的Class,例如javax.swing.JFrame等。這些類在整個Java應用程序中都是可以被訪問的。
3.應用程序類載入器
應用程序類載入器負責載入應用程序的Class,例如用戶自定義的Class。這些類只在應用程序內部被訪問。
public class ClassLoaderDemo { public static void main(String[] args) { // 獲取當前線程的類載入器 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); // 載入org.springframework.jdbc.core.JdbcTemplate類 try { Class clazz = classLoader.loadClass("org.springframework.jdbc.core.JdbcTemplate"); System.out.println(clazz); } catch (ClassNotFoundException e) { e.printStackTrace(); } } }
四、Java執行Class的鏈接
Java程序在載入完Class之後,需要進行鏈接操作,包括驗證、準備和解析三個步驟。
1.驗證
驗證步驟用來確保所載入的Class是符合Java規範的,包括格式檢查、語義檢查、位元組碼檢查等。
2.準備
準備步驟用來分配所載入的Class所需的空間,並設置默認值。例如,對於一個int型的成員變數,它將會被分配4個位元組的空間,並設置為0。
3.解析
解析步驟用來將被載入的Class中的符號引用解析為實際引用,並進行相關的鏈接處理,如常量池解析、類或介面的解析等。
public class LinkageDemo { public static void main(String[] args) { LinkageDemo demo = new LinkageDemo(); demo.sayHello(); } public void sayHello() { System.out.println("Hello, World!"); } }
五、Java執行Class的初始化
Java程序在鏈接完Class之後,還需要進行初始化操作,包括靜態變數賦值、靜態代碼塊調用等。Java採用了Lazyloading的思想,即在第一次使用該Class時才會進行初始化。
public class InitializationDemo { static { System.out.println("InitializationDemo被初始化了"); } public static void main(String[] args) { // 輸出InitializationDemo被初始化了 System.out.println("Hello, World!"); } }
六、Java執行Class的卸載
Java程序在執行時,如果某一個Class已經不再使用,那麼它將會被JVM的垃圾回收器回收。當一個Class被回收之後,可以對其進行重新載入和執行操作。
public class UnloadingDemo { public static void main(String[] args) throws ClassNotFoundException { // 創建一個自定義類載入器 MyClassLoader loader = new MyClassLoader(); // 載入並執行HelloWorld類 Class clazz = loader.loadClass("HelloWorld"); try { clazz.getMethod("sayHello").invoke(clazz.newInstance()); } catch (Exception e) { e.printStackTrace(); } // 卸載HelloWorld類 ((MyClassLoader) clazz.getClassLoader()).unloadClass("HelloWorld"); } } class MyClassLoader extends ClassLoader { private Map<String, Class> classes = new HashMap(); @Override protected Class findClass(String name) throws ClassNotFoundException { byte[] classBytes = getClassBytes(name); Class clazz = defineClass(name, classBytes, 0, classBytes.length); classes.put(name, clazz); return clazz; } private byte[] getClassBytes(String name) throws ClassNotFoundException { try { InputStream is = ClassLoader.getSystemResourceAsStream(name.replace(".", "/") + ".class"); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); byte[] buff = new byte[2048]; int len = 0; while ((len = is.read(buff)) != -1) { outputStream.write(buff, 0, len); } return outputStream.toByteArray(); } catch (Exception e) { throw new ClassNotFoundException(name); } } public void unloadClass(String name) { classes.remove(name); } } class HelloWorld { public void sayHello() { System.out.println("Hello, World!"); } }
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/155206.html