Java 使用对象参数调用具有泛型参数的方法

Java 使用对象参数调用具有泛型参数的方法,java,generics,Java,Generics,我正在尝试在一个轻型2D游戏引擎中制作一些资源管理器。我想要一个像这样的ResourceManager: package com.Arsleust.DayumCorp.DayumEngine.Ressource; import java.awt.Graphics2D; import java.util.HashMap; public class RessourceManager { private HashMap<Class<?>, Renderer<?&g

我正在尝试在一个轻型2D游戏引擎中制作一些资源管理器。我想要一个像这样的ResourceManager:

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); 
        }
    }

}
package com.Arsleust.DayumCorp.DayumEngine.Ressource;
导入java.awt.Graphics2D;
导入java.util.HashMap;
公共类资源管理器{
私有HashMap>渲染器;
public void registerRenderer(类objclass,渲染器){
this.renderers.put(对象类,渲染器);
}
公共void渲染(Graphics2D g,对象){
类objclass=object.getClass();
if(this.renderers.get(objclass)!=null){
get(objclass).render(g,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);

}
package com.Arsleust.DayumCorp.DayumEngine.Ressource;
导入java.awt.Graphics2D;
公共抽象类渲染器{
公共抽象void init();
公共抽象无效渲染(Graphics2D g,T对象);
}
但是
this.renderers.get(objclass.render)(g,object)
出错,Eclipse要求我创建一个新方法或更改
渲染器。render
方法的参数类型
T
对象

不知何故,我不得不将
T
泛型转换为
对象
,而不知道它是什么类型。。。
我真的很困惑,所以我请求你帮助我看得更清楚。

该死的泛型,全速前进

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

将通用的
渲染器
强制转换为一个
渲染器
。它破坏了泛型类型系统,但应该是安全的。您已经确保了这一点。

您使用的是
渲染器
,这意味着您有一个类型未知的
渲染器
。i、 e.您可以获取此类型的元素,因为它将是
对象
,但您无法传递此类型的元素,因为您不知道它是什么。i、 编译器不能确定它是否正确

你需要做的是自己处理类型检查,编译器会对此抱怨,因为它不能在这里为你检查

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 void registerRenderer(类objclass,渲染器){
this.renderers.put(对象类,渲染器);
}
@抑制警告(“未选中”)
公共void渲染(Graphics2D g,对象){
类objclass=object.getClass();
if(this.renderers.get(objclass)!=null){
get(objclass).render(g,object);
}
}
}
公共类资源管理器{
私有HashMap>渲染器;
public void registerRenderer(类objclass,渲染器){
this.renderers.put(对象类,渲染器);
}
公共void渲染(Graphics2D g,V对象){
类objclass=object.getClass();
if(this.renderers.get(objclass)!=null){
((Renderer)this.renderers.get(objclass)).render(g,object);
}
}
}

它会抑制错误,但我会取消选中并显示警告。。。应该考虑够了,谢谢!您不能直接从
渲染器
渲染器
进行强制转换,您需要在两者之间强制转换
(渲染器)
:P@PeterLawrey:为什么这样认为?编译器不允许您从一个泛型类型强制转换为不兼容的泛型类型。您必须使用类型擦除来愚弄编译器。但是这些类型是兼容的,您首先检查
呈现程序
是否已为
V
类型的对象注册。试着运行这段代码,它工作得很好。你是对的!它报告一个警告,而不是一个错误。工作完美!我得到了未检查和警告,但它应该是好的。谢谢@Arsleust尝试将@
SuppressWarnings
注释移动到类的开头。Eclipse是99%的标准,但有一些怪癖初始化渲染贴图first@jw23我更愿意删除该部分,因为它对您不重要,但不用担心,我初始化了我的变量;)
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);
        }
    }
}