简体   繁体   English

Java / android的新功能:类加载器与导入

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

if i understand class loaders correctly, it is loading a class from a jar file at runtime. 如果我正确理解类加载器,则它是在运行时从jar文件加载类。 IF that is true, I thought we can easily do this without class loaders, with the import statement (after including the jar file in the build path). 如果是这样,我想我们可以使用import语句(在将jar文件包含在构建路径中之后)而无需类加载器轻松地完成此操作。 Here is an example: 这是一个例子:

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

Therefore I don't understand what is the purpose of class loaders. 因此,我不明白类加载器的目的是什么。 can someone explain ? 有人可以解释吗?

import is for proper compilation of code. import用于正确编译代码。 Suppose you are using an ArrayList, you have to tell the compiler which ArrayList you are using by specifying import java.util.ArrayList; 假设您正在使用ArrayList,则必须通过指定import java.util.ArrayList;来告诉编译器您正在使用哪个ArrayList import java.util.ArrayList; or you can directly use 或者你可以直接使用

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

Without importing anything. 无需导入任何内容。

ClassLoaders are used at runtime. ClassLoader在运行时使用。 If a class is needed during runtime, then it is loaded into the runtime environment(JVM) by ClassLoaders 如果在运行时需要一个类,则由ClassLoaders将其加载到运行时环境(JVM)中

Note : The import statement says - I am using this class to the compiler. 注意:import语句说- 在编译器中使用此类 ClassLoaders are used to dynamically load the class (ArrayList or any other class) into the JVM. ClassLoader用于将类(ArrayList或任何其他类)动态加载到JVM中。

Edit : 编辑:

Assume you have 2 shirts (shirts =classes) one red with black stripes and another red with white stripes. 假设您有2件衬衫(衬衫=类),一件红色带黑色条纹,另一件红色带白色条纹。 Now, you tell your mom (compiler) , please iron the red shirt, your mom asks which red shirt you tell - the red shirt with white stripes . 现在,您告诉您的妈妈(编译器),请熨烫红色衬衫,您的妈妈问您告诉哪一件 红色衬衫-带有白色条纹的红色衬衫 Note that you are not actually using the shirt, you are merely telling which red shirt you will use. 请注意,您实际上并没有使用衬衫,只是在告诉您要使用哪种红色衬衫。 The next day, you need to go to college so you tell your dad get me the red-shirt with white stripes (dad is like ClassLoader) and you wear the shirt. 第二天,你需要上大学,然后告诉爸爸让我给我穿上白色条纹的红色衬衫(爸爸就像ClassLoader一样),然后穿上这件衬衫。 (class is loaded and being used) (类已加载并正在使用)

You cannot use import statements to load classes. 您不能使用import语句加载类。 In fact, import statements don't do anything, they are merely syntactic sugar so that you can omit the package when referring to a class in your code. 实际上,import语句不执行任何操作,它们只是语法上的糖,因此在引用代码中的类时,您可以省略包。

Example: 例:

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();

Every class that is used by a program has to be loaded by a class loader. 程序使用的每个类都必须由类加载器加载。 The java rumtime environment provides a default class loader that is normally used. Java rumtime环境提供了通常使用的默认类加载器。 So, the first time the code encounters a statement to create a new ArrayList, it will get the class definition from the class loader. 因此,代码第一次遇到创建新ArrayList的语句时,它将从类加载器获取类定义。

Class loader can also load classes dynamically, using just the full class name (for example "java.util.ArrayList" ). 类加载器还可以仅使用完整的类名(例如"java.util.ArrayList" )动态地加载类。 And if you instantiate additional class loaders you can get each of them to load classes with the same name. 而且,如果您实例化其他类加载器,则可以让它们各自加载具有相同名称的类。 That means that if a class changes you can load a new version of it in a new class loader. 这意味着,如果类发生更改,则可以在新的类加载器中加载它的新版本。

The technique to load several versions of the same class is used by application servers (like GlassFish or JBoss) so that you can redeploy your application without restarting the application server. 应用程序服务器(例如GlassFish或JBoss)使用了加载同一类的多个版本的技术,因此您可以重新部署应用程序而无需重新启动应用程序服务器。 Also, different applications in the same application server can use different versions of a class. 同样,同一应用程序服务器中的不同应用程序可以使用类的不同版本。

Example: 例:

Let's say you have developed a User class that is used by 2 different applications deployed in the same application server. 假设您已经开发了一个User类,供同一应用程序服务器中部署的2个不同应用程序使用。 You want to deploy a new version of application 1, that uses a new version of the User class. 您想要部署使用User类的新版本的应用程序1的新版本。

TheLostMind gives a good description of import statements. TheLostMind很好地描述了import语句。

To expand on class loaders a bit, imagine that you had a class 稍微扩展一下类加载器,想象一下您有一个类

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

At runtime, when foo() is called, it implicitly uses its own class loader to load other classes. 在运行时,调用foo()时,它将隐式使用其自己的类加载器加载其他类。 Note that the ArrayList class is not actually loaded into memory until the application actually uses it at runtime! 请注意,直到应用程序在运行时实际使用ArrayList类时,它才真正加载到内存中! So it is equivalent to the following code that uses refection: 因此,它等效于以下使用refection的代码:

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

Any time you use reflection (eg in deserialization libraries and SPI factories), you have to be explicit about which class loader to use. 每当使用反射时(例如在反序列化库和SPI工厂中),都必须明确说明要使用的类加载器。

Most people don't use multiple class loaders, because the SystemClassLoader that loaded your class is also able to load all your dependencies (as long as your java CLASSPATH contains the same libraries you used at compile time in the javac CLASSPATH). 大多数人不使用多个类加载器,因为加载您的类的SystemClassLoader也能够加载您的所有依赖项(只要您的java CLASSPATH包含与您在javac CLASSPATH编译时使用的库相同)。 People use class loaders to create applications that allow plugins to be loaded at runtime (such as Eclipse, which uses OSGi modules) and frameworks that allow applications to be loaded at runtime (such as Java EE and servlets). 人们使用类加载器来创建允许在运行时加载插件的应用程序(例如使用OSGi模块的Eclipse)和允许在运行时加载应用程序的框架(例如Java EE和servlet)。 Using multiple class loaders is also sometimes necessary in Android for large applications; 对于大型应用程序,有时在Android中还需要使用多个类加载器; see Custom Class Loading in Dalvik . 请参阅Dalvik中的自定义类加载

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM