Hello, I'm working on a specific classloader for my application, but I'm having trouble getting the Generics to work the way I would like them too. I have the following:

public interface Loader<E extends GEObject>{
// methods
}

public class GEClassLoader<E extends GEObject> extends URLClassLoader implements Loader<E>{
// methods
}

GEObject is the base class for all objects in my application. The loader is supposed to search the supplied directory for the classes that extend E (where E is an interface/abstract class that inherits GEObject). When I load a class, I want to check its class against that of E.
So, I have to following, but it doesn't work due to the above reasons: It's complaining about the if(o instanceof E) line...

try{
    Class c = loadClass(pkg+name, true);
    try{
        Object o = c.newInstance();
        E e = null;
        if(o instanceof E){            
            e = (E)o;
            cis.add((E)ci); // list of classes loaded
        }
     }catch(Exception e){
         // Handle exception
     }
}catch(ClassNotFoundException cnfe){
    System.out.println("Couldn't find Class "+pkg+name);
}

Note, If I could use 1.6 for this project, I would, but I'm stuck with 1.5...  1.6 would make this much easier....

Edited 6 Years Ago by llemes4011: n/a

Since E extends GEObject, therefore anything which answers true to being an instanceof E will also be an instanceof GEObject. So why don't you just change that line to

if (o instanceof GEObject)

Also, what are you actually trying to accomplish here (code like yours is seldom necessary - I'm not saying never, just seldom), and what is the error that the compiler gave you?

Hello. I'm writing an extendable game engine, with many different aspects that can be customized (i.e., Battle Type, Units, Scenery, Music, Race/Class, etc) by doing just a drag-and-drop into the plugins directory. Yes, some of the plain text data can just be stored in files in the same directory, but for the Classes that need to be extended, I'm working on this. Each object in the game engine will inherit GEObject - the base class for anything that can be extended and subclassed (Battle Styles, Game Classes, Maps, etc). These will be interfaces or abstract classes that need to be loaded independently at runtime, and then stored into an internal library that can be accessed by the game engines' core, and used as needed.
Here's the error:

G:\Projects\Java\Game Engine 2\src\com\engine\loader\GEClassLoader.java:87: unexpected type
found   : E
required: class or array
                    if(o instanceof E){//o instanceof E){

I dont know if this is the right way to do this, but it got me working with generics and ClassLoaders, lol.

You seem to be confused as to the way generics work in Java. Here E is a type-parameter which is used during compile time checks; there is no `E' when it comes to your generated .class files. Search for "type erasure" in java generics for clarification.

Comments
Bingo

hmm, s.o.s, is there a way to get around that? Or should I just code a specific loader for each group of objects? Because that's starting to look like a cleaner, easier option.

http://java.sun.com/docs/books/tutorial/java/generics/erasure.html

There is no way around it. If you want to "load specific classes" as you're saying, then you are going to have to explicitly name an interface, class, or abstract class in order to do so. But I'm pretty sure you probably don't need to do what you are trying to do, there is probably an easier way. To accomplish "loading something at runtime that is used by your game engine" you could just create a new Object of the specified class type. I'm not trying to frustrate you but I find it likely that you are heading down the wrong path. Maybe I'm wrong, if you think so feel free to ignore me.

Edited 6 Years Ago by BestJewSinceJC: n/a

hmm, s.o.s, is there a way to get around that? Or should I just code a specific loader for each group of objects? Because that's starting to look like a cleaner, easier option.

You might want to clarify your requirements here since the original snippet posted is confusing. Why are you instantiating objects inside your classloader? What exactly are you trying to do here and why?

You might want to clarify your requirements here since the original snippet posted is confusing. Why are you instantiating objects inside your classloader? What exactly are you trying to do here and why?

I've never messed with ClassLoaders before, so I don't really know how to do it correctly. If I don't instantiate the objects, how am i supposed to access them later?

I guess my requirements are:
Load classes at runtime based on a default type (apparently I can't do this).
Store the name/object into an ArrayList of the correct type to access later.
Make loaded classes easy to access and use throughout the program.

Just make an ArrayList<E> then add the Objects you need into the ArrayList at runtime. Create the Objects the normal way using the new keyword. Why doesn't that approach work for you?

I've never messed with ClassLoaders before, so I don't really know how to do it correctly. If I don't instantiate the objects, how am i supposed to access them later?

Classloaders are used for loading classes. Typical scenarios wherein you would require a custom classloader is:

  • When you are writing a framework which hosts managed components written by users and configured in a declarative manner (think servlets)
  • When you want to add pre/post processing operations to the loaded resources. E.g. loading encrypted classes and images, caching frequently loaded images etc.

In any case, if you need access to your loaded classes, you can use the findClass(String) method of the classloader to do so. E.g.

Class klass = Thread.currentThread().
     getContextClassLoader().findClass("my.game.pkg.Klass");

This would give you the reference to the loaded class based on the class named specified.

Also, you can gain complete control over your instantiated components by using a dependency injection framework like Spring but I guess that would be too enterprisy for a hobby project. :)

This article has been dead for over six months. Start a new discussion instead.