简体   繁体   中英

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. 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). 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. Suppose you are using an ArrayList, you have to tell the compiler which ArrayList you are using by specifying 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. If a class is needed during runtime, then it is loaded into the runtime environment(JVM) by ClassLoaders

Note : The import statement says - I am using this class to the compiler. ClassLoaders are used to dynamically load the class (ArrayList or any other class) into the JVM.

Edit :

Assume you have 2 shirts (shirts =classes) one red with black stripes and another red with white stripes. 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. (class is loaded and being used)

You cannot use import statements to load classes. 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.

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. So, the first time the code encounters a statement to create a new ArrayList, it will get the class definition from the class loader.

Class loader can also load classes dynamically, using just the full class name (for example "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. 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. You want to deploy a new version of application 1, that uses a new version of the User class.

TheLostMind gives a good description of import statements.

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. Note that the ArrayList class is not actually loaded into memory until the application actually uses it at runtime! So it is equivalent to the following code that uses 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.

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). 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). Using multiple class loaders is also sometimes necessary in Android for large applications; see Custom Class Loading in Dalvik .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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