简体   繁体   中英

Invoke method with generic argument using Object argument

I am trying to make some RessourceManager in a light 2D game engine. I want to have a RessourceManager like this :

package com.Arsleust.DayumCorp.DayumEngine.Ressource;

import java.awt.Graphics2D;
import java.util.HashMap;

public class RessourceManager {

    private HashMap<Class<?>, Renderer<?>> renderers;

    public void registerRenderer(Class<?> objclass, Renderer<?> renderer) {
        this.renderers.put(objclass, renderer);
    }

    public void render(Graphics2D g, Object object) {
        Class<?> objclass = object.getClass();
        if(this.renderers.get(objclass) != null) {
            this.renderers.get(objclass).render(g, object); 
        }
    }

}

using this object :

package com.Arsleust.DayumCorp.DayumEngine.Ressource;

import java.awt.Graphics2D;

public abstract class Renderer<T> {

    public abstract void init();

    public abstract void render(Graphics2D g, T object);

}

but this.renderers.get(objclass).render(g, object); makes an error, and Eclipse asks me to create a new method or to change the Renderer.render method's argument type T to Object .

Somehow I have to cast to that T generic type the object without know what type it is... I'm getting really confused so i'm asking your help to see it more clearly.

Damn the generics, full speed ahead!

((Renderer) renderers.get(objclass)).render(g, object);

Cast the generic Renderer<?> to just a Renderer . It's breaking the generic type system, but it should be safe. You've made sure of that.

You are using a Renderer<?> which means you have a Renderer of an unknown type. ie you can get an element of this type as it will be an Object but you cannot pass an element of this type because you don't know what it is. ie the compiler cannot be sure it is right.

What you need to do is handle the type checking yourself and the compiler will complain about this because it can't check for you here.

public class RessourceManager {

    private final Map<Class, Renderer> renderers;

    public <T> void registerRenderer(Class<T> objclass, Renderer<T> renderer) {
        this.renderers.put(objclass, renderer);
    }

    @SuppressWarnings("unchecked")
    public void render(Graphics2D g, Object object) {
        Class objclass = object.getClass();
        if(this.renderers.get(objclass) != null) {
            this.renderers.get(objclass).render(g, object); 
        }
    }

}
public class RessourceManager {

    private HashMap<Class<?>, Renderer<?>> renderers;

    public <V> void registerRenderer(Class<V> objclass, Renderer<V> renderer) {
        this.renderers.put(objclass, renderer);
    }

    public <V> void render(Graphics2D g, V object) {
        Class<?> objclass = object.getClass();
        if(this.renderers.get(objclass) != null) {
            ((Renderer<V>)this.renderers.get(objclass)).render(g, object);
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM