Question: Java has 3 class loaders:

* BootStrap,
* Extension and
* System

and they have one role; loading classes from different packages.

But why does Java have 3 different class loaders instead of just one, since one class loader can load all the necessary classes?

Answer: 
The reason for having the three basic class loaders (Bootstrap, extension, system) is mostly security.

Prior to version 1.2 of the JVM, there was just one default class loader, which is what is currently called the "Bootstrap" class loader.

The way classes are loaded by class loaders is that each class loader first calls its parent, and if that parent doesn't find the requested class, the current one is looking for it itself.

A key concept is the fact that the JVM will not grant package access (the access that methods and fields have if you didn't specifically mention `private`, `public` or `protected`) unless the class that asks for this access comes *from the same class loader* that loaded the class it wishes to access.

So, suppose a user calls his class `java.lang.MyClass`. Theoretically, it could get package access to all the fields and methods in the `java.lang` package and change the way they work. The language itself doesn't prevent this. But the JVM will block this, because all the real `java.lang` classes were loaded by bootstrap class loader. Not the same loader = no access.

There are other security features built into the class loaders that make it hard to do certain types of hacking.

So why three class loaders? Because they represent three levels of trust. The classes that are most trusted are the core API classes. Next are installed extensions, and then classes that appear in the classpath, which means they are local to your machine.

For a more extended explanation, refer to [Bill Venners's "Inside the Java Virtual Machine"](http://www.artima.com/insidejvm/ed2/security2.html).
The main usage of class loaders is in application servers. 

You want to be able to start Tomcat (for example). This already needs at least one classloader to run tomcat itself. 

Then you want to be able to deploy an application into Tomcat. So Tomcat itself needs to load an analyze the classes of the application, which didn't even exist when Tomcat was started.

Then you want to be able todeploy another application in Tomcat. Maybe this second application uses a library that the first one also uses, but in a different version. So you want each app to have its own isolated class loader, otherwise the classes of app 2 might interfere badly with the classes from app 1.

Then you want to be able to undeploy one of the webapps. So its class loader must be destroyed and garbage-collected, to avoid a huge memory leak.

There are of course many other usages, but that's the one that is the most commonly used (in my experience).