让一个类在java中实现一个未指定的泛型接口
我有以下“一般”问题 这是我的通用消息接口让一个类在java中实现一个未指定的泛型接口,java,generics,Java,Generics,我有以下“一般”问题 这是我的通用消息接口 public interface Message<P,R> { void setParams(P Params); // and the corresponding getter void setResults(R results); } 公共接口消息{ void setParams(P Params);//和相应的getter 无效设置结果(R结果); } 为了简单起见,我想通过预定义参数和结果类型
public interface Message<P,R> {
void setParams(P Params); // and the corresponding getter
void setResults(R results);
}
公共接口消息{
void setParams(P Params);//和相应的getter
无效设置结果(R结果);
}
为了简单起见,我想通过预定义参数和结果类型来指定大量(接口)消息。因此,如果您使用消息X,您就知道参数和结果类型是什么
比如
public interface MyMessage extends Message<String,String> {}
公共接口MyMessage扩展消息{}
这很好,现在我想要一个通用的基类,它可以实现任何消息
public class BaseMessage<P,R> implements Message<P,R> {
P param;
R results;
// base implementation
}
公共类BaseMessage实现消息{
P参数;
R结果;
//基本实现
}
上面的问题是我不能有一个实现MyMessage的BaseMessage
多次尝试,如
public class BaseMessage<T extends BaseMessage<P,R>> implements Message<P,R>
公共类BaseMessage实现消息
或
public-class-BaseMessage恐怕这样的泛型工厂是不可能的,因为您不能实例化像这样的泛型类型
T a = new BaseMessage<T>();
ta=newbasemessage();
您必须告诉编译器确切的泛型类型参数
您可以做的是创建每个具体消息类型的实例,并将它们存储在一个映射中,对应的类标记作为键。然后,factory方法可以查找正确的消息并直接返回它,或者(如果需要单独的实例)使用message对象创建要返回的实例
在我们当前的项目中,我们有一个类似的设计,不同的是,具体的子类是每个现有的类,具有不同的名称和(不幸的是,大部分(但不是完全)重复的)实现。因此,我们可以使用标准类加载和Spring来实例化它们。您还没有指定工厂如何决定使用哪个实现类,或者实现类是否需要任何自定义初始化逻辑或参数。假设仅使用默认构造函数实例化已注册的实现类就足够了,您可以执行以下操作:
interface Message<P, R> {
void setParams(P Params); // and the corresponding getter
void setResults(R results);
}
interface StringMessage extends Message<String, String> {
}
abstract class MessageImpl<P, R> implements Message<P, R> {
P param;
R results;
}
abstract class StringMessageImpl extends MessageImpl<String, String> implements
StringMessage {
}
class ImplementationMap {
private Map<Class<?>, Class<?>> map = new HashMap<Class<?>, Class<?>>();
public <T> void register(Class<T> interfaceClass, Class<? extends T> implementationClass) {
map.put(interfaceClass, implementationClass);
}
public <T> Class<? extends T> get(Class<T> interfaceClass) {
return map.get(interfaceClass).asSubclass(interfaceClass);
}
}
public class Test {
static final ImplementationMap messageImplementors = new ImplementationMap() {{
register(StringMessage.class, StringMessageImpl.class);
}};
static <P, R, M extends Message<P, R>> M create(Class<M> clazz, P p, R r)
throws Exception {
M m = messageImplementors.get(clazz).newInstance();
m.setParams(p);
m.setResults(r);
return m;
}
public static void main(String[] args) throws Exception {
StringMessage m = create(StringMessageImpl.class, "p", "r");
}
}
接口消息{
void setParams(P Params);//和相应的getter
无效设置结果(R结果);
}
接口StringMessage扩展消息{
}
抽象类MessageImpl实现消息{
P参数;
R结果;
}
抽象类StringMessageImpl扩展了MessageImpl实现
StringMessage{
}
类实现映射{
私有映射>映射=新HashMap>();
公共无效寄存器(类interfaceClass,类给定接口接口消息
和接口MyMessage扩展消息
,类类BaseMessage实现消息
,我看到以下选项:
不要使用MyMessage
并将所有实例替换为Message
。您的工厂将
public <P,R> Message<P, R> newMessage() {
return new BaseMessage<P,R>();
}
public <M extends Message> M newMessage(Class<M> m) {
if (m.isAssignableFrom(MyBaseMessage.class)) {
return (M) new MyBaseMessage();
}
if (m.isAssignableFrom(BaseMessage.class)) {
return (M) new BaseMessage();
}
return null;
}
公共消息newMessage(){
返回新的BaseMessage();
}
上课
class MyBaseMessage extends BaseMessage<String, String> implemens MyMessage
类MyBaseMessage扩展BaseMessage实现MyMessage
工厂将被关闭
public <P,R> Message<P, R> newMessage() {
return new BaseMessage<P,R>();
}
public <M extends Message> M newMessage(Class<M> m) {
if (m.isAssignableFrom(MyBaseMessage.class)) {
return (M) new MyBaseMessage();
}
if (m.isAssignableFrom(BaseMessage.class)) {
return (M) new BaseMessage();
}
return null;
}
publicmnewmessage(类M){
if(m.isAssignableFrom(MyBaseMessage.class)){
返回(M)新的MyBaseMessage();
}
if(m.isAssignableFrom(BaseMessage.class)){
返回(M)新的BaseMessage();
}
返回null;
}
不要使用接口
不要使用工厂
(如果其他一切都坏了)让你的工厂
public <M extends Message> M newMessage(Class<M> m) {
try {
return getImplClass(m).newInstance();
} catch (Exception ex) { /* do proper error handling */ }
}
publicmnewmessage(类M){
试一试{
返回getImplClass(m).newInstance();
}catch(异常ex){/*执行正确的错误处理*/}
}
getImplClass()
:使用javassist在运行时创建一个实现类,该实现类实现接口M并扩展BaseMessage
公共接口MyMessage extends BaseMessage
这无法工作,在您的示例中,BaseMessage是一个类。感谢您的评论,它确实应该读取公共接口MyMessage extends Message{}。我猜M=clazz.newInstance();
将无法工作,因为M应该是一个接口。是吗?(OP写道)“它将被赋予消息类”)好吧,它应该是接口,正如Arian指出的,被赋予工厂,并且应该返回一个实现类……假设你指的是实现类的对象,我已经更新了我的答案。
public <M extends Message> M newMessage(Class<M> m) {
try {
return getImplClass(m).newInstance();
} catch (Exception ex) { /* do proper error handling */ }
}