具有多个接口的Java通用对象

具有多个接口的Java通用对象,java,generics,Java,Generics,假设我使用了一个泛型类,声明如下: public class ConfigurableRuleKey<R extends Configurable & Rule> extends Key<R> { private final R rule public ConfigurableRuleKey(R rule) { this.rule = rule; } /* Additional methods are decl

假设我使用了一个泛型类,声明如下:

public class ConfigurableRuleKey<R extends Configurable & Rule> extends Key<R> {

    private final R rule

    public ConfigurableRuleKey(R rule) {
        this.rule = rule;
    }

    /* Additional methods are declared here */

}

问题是,在我的工厂方法中,我无法将规则传递给
ConfigurableRuleKey
的构造函数,因为它不符合声明的泛型约束(如果我明确检查它是否实现了
ConfigurableRuleKey
,则会发生此事件)。问题是如何强制转换规则实例,使其符合
ConfigurableRuleKey
中的构造函数限制?

这应该满足您的需要:

@SuppressWarnings({ "rawtypes", "unchecked" })
public static <R extends Rule> Key<R> create(R rule) {
    if (rule instanceof Configurable) {
        return new ConfigurableRuleKey((Configurable) rule);
    } else {
        return new RuleKey<>(rule);
    }
}
@SuppressWarnings({“rawtypes”,“unchecked”})
公共静态密钥创建(R规则){
if(可配置的规则实例){
返回新的ConfigurableRuleKey((可配置)规则);
}否则{
返回新的RuleKey(规则);
}
}

您手动检查了
规则
是否可配置,因此强制转换是安全的。

我确实找到了一种不使用原始类型执行您要求的操作的方法,但它仍然涉及一对未经检查的强制转换:

@SuppressWarnings("unchecked")
public static <R extends Rule, T extends Rule & Configurable> Key<R> create(R rule) {
    if (rule instanceof Configurable) {
        return (Key<R>)new ConfigurableRuleKey<>((T)rule);
    } else {
        return new RuleKey<>(rule);
    }
}

您正在使用原始类型并抑制所有警告,我认为这不是OP想要的。@WilQu:我怀疑在不破坏泛型的情况下执行OP想要的操作是否可能,因为为了直接实例化
ConfigurableRuleKey
,一个既可配置又可规则的具体类型是必需的,
create
函数无权访问任何此类具体类型。@WilQu我并没有抑制所有警告,只有
rawtypes
,这样编译器就不会检查泛型(我不确定是否可以进行其他检查),未选中的
,因为编译器无法知道强制转换是否安全(当然,由于
instanceof
,它是手动检查的)。@sp00m如果不使用泛型,则强制转换甚至是不必要的。您也可以在强制转换中尝试
(可配置和规则)
。至少在Java 8中,这是一种合法的构造。我的IDE告诉我,这段代码甚至不会编译,但事实上似乎确实编译了。:)谢谢我想我会向IDE的支持团队报告这个问题。@SimY4:只是出于好奇,IDE抱怨什么?我正在使用IntelliJ Idea 14早期访问预览
@SuppressWarnings("unchecked")
public static <R extends Rule, T extends Rule & Configurable> Key<R> create(R rule) {
    if (rule instanceof Configurable) {
        return (Key<R>)new ConfigurableRuleKey<>((T)rule);
    } else {
        return new RuleKey<>(rule);
    }
}
@SuppressWarnings("unchecked")
public static <R extends Rule> Key<R> create(R rule) {
    if (rule instanceof Configurable) {
        return (Key<R>)new ConfigurableRuleKey<>((Configurable & Rule)rule);
    } else {
        return new RuleKey<>(rule);
    }
}