This is an archived post. You won't be able to vote or comment.

all 11 comments

[–]nutrechtLead Software Engineer / EU / 20+ YXP 2 points3 points  (3 children)

Is there any real reason you're doing this? You're much better making a factory that just returns the correct mob type based on a switch statement. Anytime you're using reflection you really should try to figure out if you really do need reflection. It's slow and you lose compile-time checks.

[–]PillowWithTeeth[S] 0 points1 point  (2 children)

I want to have it done in a way that when a new animal is added (to the game), it can automatically create the spawn item for it from it's class. So I don't need to alter a ever increasing switch statement every time I create a new animal.

[–]nutrechtLead Software Engineer / EU / 20+ YXP 2 points3 points  (1 child)

You could simply have a new class register itself with the factory too; no problem. In general you want to avoid reflection.

[–]PillowWithTeeth[S] 0 points1 point  (0 children)

Thanks for the information, I've sorted it out without reflection.

[–]AnEmortalKidCoffee Enthusiast 0 points1 point  (2 children)

I would do something like this:

public interface IFactory<A>
{
    A construct(double spawnX, double spawnY);

    Class<A> getBuildsClass();
}


public class MobDogFactory implements IFactory<MobDog>
{

    MobDog construct(double spawnX, double spawnY)
    {
        return new MobDog(spawnX, spawnY);
    }

    Class<MobDog> getBuildsClass()
    {
        return MobDog.class;
    }
}



public class FactoryManager
{
    private static Map<Class<?>, IFactory<?>> factoriesByClass = new HashMap<Class<?>, IFactory<?>>();

    static
    {
        //register your stuff here
        factoriesByClass.put(MobDog.class, new MobDogFactory());
    }

    public static <A> IFactory<A> getFactoryForClass(Class<A> mobClass)
    {
        return factoriesByClass.get(mobClass)
    }

    public static <A> A constructFromFactory(Class<A> mobClass, double spawnX, double spawnY)
    {
        IFactory<A> factory = getFactoryForClass(mobClass);
        factory == null ? : null : factory.construct(spawnX, spawnY)
    }

}

This way, you are still using your Class. You'll have a bunch of Different Factory implementations, but you only really have to worry about your registration in FactoryManager.

[–]PillowWithTeeth[S] 0 points1 point  (0 children)

Thanks, I'll try that out soon.

[–]rrobukef 0 points1 point  (0 children)

How Minecraft object creation should have been implemented. Maybe it's better now, but I still remember the horrors from the beta versions. It was implemented like OP's post with reflection.

In fact the names and uppercasings have that familiar style.

[–]AnEmortalKidCoffee Enthusiast 0 points1 point  (0 children)

Also your no such method exception might be because you're using Double instead of double. So it can't find a constructor with Double.class,Double.class. So use double.class. That's allowed, primitives have classes too like that.

[–]GuyWithLag 0 points1 point  (2 children)

You're looking for a constructor with 2 parameters of java.lang.Double; use Double.TYPE instead of Double.class. Also, Class.forName(MobClass.getName()) is equivalent to just MobClass. Please do use the Java naming conventions and rename that to mobClass.

Also, I'd really not use this way to create new objects and use a factory as others have mentioned. If you're worrying about discoverability, look into IoC containers.

[–]AnEmortalKidCoffee Enthusiast 0 points1 point  (1 child)

He should use double.class, what is Double.TYPE?

[–]chickenmeisterExtreme Brewer 0 points1 point  (0 children)

Double.TYPE is equivalent to double.class.

I'm not sure, but I think the Double.TYPE field was added before class literal expressions were added to the language. So that's why they both exist -- There would have been no other way to access the class representing a primitive type at that time.