Z tego co piszesz wynika ze chcesz miec jednoczesnie Klass ladowane poprzez CLASSPATH (twoj przykladowy kod), oraz dynamicznie. Jakos mi to nie pasuje, nie wiem dlaczego tak chcesz robic. Mozesz zaladowac inna wersje Klass tworzac URLClassLoader z nullowym parentem, ale nie bedzie ona kompatybilna z ta ladowana z classpath (nawet jesli jest to bajt w bajt to samo) - dla testu sprobuj wywolac equals() na takich obiektach Class dla tych dwoch klas (wiem, zle to brzmi) - inne classloadery, czyli inne klasy, nie mozesz rzutowac ani przypisac. Zatem, utworzenie takiego obiektu wczytanej dynamicznie klasy, rzutowanie go na Klass (ktora jest z classpath) rzuci ClassCastException (z wiele mowiaca wiadomoscia bledu "Exception in thread "main" java.lang.ClassCastException: test.Klass cannot be cast to test.Klass") - bo inne classloadery je wczytaly, czyli wg javy klasy sa niekompatybilne.
Kod ktory wykonalem zeby rzucic taki wyjatek:
Klass k1 = new Klass(); // wersja z classpath
Klass k2 = (Klass) new URLClassLoader(new URL[] { new File("/home/malamyga/dynamicclasses").toURI().toURL() }, null).loadClass("test.Klass").newInstance(); // wczytana dynamiczniem ale rzutowana na wersje z classpath - wyjatek
Obiekt class ma referencje do classloadera ktory ja zaladowal, a classloader ma referencje do klas ktore byly nim zaladowane, taki cache. Wynika zatem z tego, ze aby "odladowac" klase Klass wczytana z classpath (i zastapic ja inna implementacja) musialbys puscic referencje do tego classloadera, oraz wszystkich klas ktore nim zostaly wczytane - tylko wtedy GC sciagnie smieciory. Nie jestem pewien, ryzykuje stwierdzenie ze nie jest to wykonalne, poniewaz tego classloadera nie tworzysz ty sam, a i nie odladujesz klasy glownej programu, wczytanej wlasnie nim. Dzialajac tak jak zostalo to pokazane we wczesniejszych postach, tracac referencje do URLClassloaderow i obiektow klas nim wczytanych, "odladowujesz" te klasy z pamieci, i mozesz zaladowac inne.
Reasumujac, zdecyduj czy ladujesz dynamicznie czy nie, z classpath, inaczej bedziesz mial ciagle jakies klopoty i dziwne jazdy. A jesli chcesz moc wywolywac metody na jakiejkimkolwiek obiekcie Klass, utworz interfejs i nim sie posluguj (umiesc go w classpath), przypisujac do niego klasy wczytane i utworzone dynamicznie, jak we wczesniejszych przykladach.
Jeszcze jedno - jesli chcesz miec 2 definicje Klass w classpath, to zawsze bedzie brana ta pierwsza z pierwszego jara wyszczegolnionego w classpath wlasnie - no i nigdy nie zostanie wczytana ta druga wersja. Ponadto, jesli raz wczytasz klase, i nastepnie nadpiszesz jara ja zawierajacego, to i tak nie bedzie on czytany (przynajmniej nie gdy wczytana ma byc nowa wersja Klass, jesli chcesz uzyc klasy jeszcze nie wykorzystane wczesniej to oczywiscie jar bedzie dla nich czytany) poniewaz Klass jest wczytana i jest w cache classloadera classpath.
Ma to sens?