簡體   English   中英

Java / android的新功能:類加載器與導入

[英]new to java/ android: class loaders vs import

如果我正確理解類加載器,則它是在運行時從jar文件加載類。 如果是這樣,我想我們可以使用import語句(在將jar文件包含在構建路徑中之后)而無需類加載器輕松地完成此操作。 這是一個例子:

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;

因此,我不明白類加載器的目的是什么。 有人可以解釋嗎?

import用於正確編譯代碼。 假設您正在使用ArrayList,則必須通過指定import java.util.ArrayList;來告訴編譯器您正在使用哪個ArrayList import java.util.ArrayList; 或者你可以直接使用

java.util.ArrayList al = new java.util.ArrayList(); 

無需導入任何內容。

ClassLoader在運行時使用。 如果在運行時需要一個類,則由ClassLoaders將其加載到運行時環境(JVM)中

注意:import語句說- 在編譯器中使用此類 ClassLoader用於將類(ArrayList或任何其他類)動態加載到JVM中。

編輯:

假設您有2件襯衫(襯衫=類),一件紅色帶黑色條紋,另一件紅色帶白色條紋。 現在,您告訴您的媽媽(編譯器),請熨燙紅色襯衫,您的媽媽問您告訴哪一件 紅色襯衫-帶有白色條紋的紅色襯衫 請注意,您實際上並沒有使用襯衫,只是在告訴您要使用哪種紅色襯衫。 第二天,你需要上大學,然后告訴爸爸讓我給我穿上白色條紋的紅色襯衫(爸爸就像ClassLoader一樣),然后穿上這件襯衫。 (類已加載並正在使用)

您不能使用import語句加載類。 實際上,import語句不執行任何操作,它們只是語法上的糖,因此在引用代碼中的類時,您可以省略包。

例:

import java.util.ArrayList;  // ArrayList will now refer to java.util.ArrayList in this code file.

// Using the shorthand provided by the import statement:
ArrayList myList1 = new ArrayList();

// Without using the shorthand provided by the import statement:
java.util.ArrayList myList2 = new java.util.ArrayList();

程序使用的每個類都必須由類加載器加載。 Java rumtime環境提供了通常使用的默認類加載器。 因此,代碼第一次遇到創建新ArrayList的語句時,它將從類加載器獲取類定義。

類加載器還可以僅使用完整的類名(例如"java.util.ArrayList" )動態地加載類。 而且,如果您實例化其他類加載器,則可以讓它們各自加載具有相同名稱的類。 這意味着,如果類發生更改,則可以在新的類加載器中加載它的新版本。

應用程序服務器(例如GlassFish或JBoss)使用了加載同一類的多個版本的技術,因此您可以重新部署應用程序而無需重新啟動應用程序服務器。 同樣,同一應用程序服務器中的不同應用程序可以使用類的不同版本。

例:

假設您已經開發了一個User類,供同一應用程序服務器中部署的2個不同應用程序使用。 您想要部署使用User類的新版本的應用程序1的新版本。

TheLostMind很好地描述了import語句。

稍微擴展一下類加載器,想象一下您有一個類

class Foo {
    static Object foo() {
        return new java.util.ArrayList();
    }
}

在運行時,調用foo()時,它將隱式使用其自己的類加載器加載其他類。 請注意,直到應用程序在運行時實際使用ArrayList類時,它才真正加載到內存中! 因此,它等效於以下使用refection的代碼:

public class Foo {
    static Object foo() throws ReflectiveOperationException {
        Class<?> arrayListClass = Class.forName("java.util.ArrayList", false, Foo.class.getClassLoader());
        return arrayListClass.getConstructor().newInstance();
    }
}

每當使用反射時(例如在反序列化庫和SPI工廠中),都必須明確說明要使用的類加載器。

大多數人不使用多個類加載器,因為加載您的類的SystemClassLoader也能夠加載您的所有依賴項(只要您的java CLASSPATH包含與您在javac CLASSPATH編譯時使用的庫相同)。 人們使用類加載器來創建允許在運行時加載插件的應用程序(例如使用OSGi模塊的Eclipse)和允許在運行時加載應用程序的框架(例如Java EE和servlet)。 對於大型應用程序,有時在Android中還需要使用多個類加載器; 請參閱Dalvik中的自定義類加載

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM