Here's a short and sweet answer: Custom class loader allows you to control how Java classes are loaded in the JVM, based on your application specific needs. For example, JBoss' hot deployment (other containers support this functionality too) uses custom class loaders to swap out classes, head over to this if you want to know more
or http://tomcat.apache.org/tomcat-6.0-doc/class-loader-howto.html
EDIT
As ask by OP, here's a small example with code snippet to just give an idea about custom class loader.
Relying on JVM’s class loader one cannot load two different versions of the same JDBC driver. So how to get around this problem? The answer lies in making a custom class loader and loading classes directly from JAR archives.
import java.net.*;
URL url=new URL("jar:file:/c:myJarsmyJar1.jar!/");
URLClassLoader ucl = URLClassLoader(new URL[] { url });
Object myClassObject = Class.forName("MyClass", true, ucl).newInstance();
Above example illustrates how to load java classes from their respective jar files using URLClassLoader, there are other ways and API's also available to do that like JARClassLoader etc.