Java中的复杂泛型

Java中的复杂泛型,java,generics,Java,Generics,我有一个超类型定义为: public abstract class AType<T> { .... private T value; private T mask; public T getValue() { if (isMasking()) return null; return this.value; } public void setValue(T value

我有一个超类型定义为:

public abstract class AType<T> {
        ....

    private T value;
    private T mask;

    public T getValue() {
        if (isMasking())
            return null;

        return this.value;
    }

    public void setValue(T value) {
        if (value == null)
            throw new IllegalArgumentException("Value is mandatory.");

        this.value = value;
    }

    protected T getMask() {
        if (!isMasking())
            return null;

        return this.mask;
    }

    protected void setMask(T mask) {
        if (mask == null)
            throw new IllegalArgumentException("Mask is mandatory.");

        this.setMasking(true);
        this.mask = mask;
    }
        ...
}
一切都正常,但此模块的用户不希望每次都在enum中查找并手动强制转换。这可能会出错,并花费大量时间进行调试:/

我的问题是我如何重构它,或者我如何定义继承结构以允许用户动态转换?可能吗

编辑:
我正在解析来自网络的数据包。有很多类型在供应商类型标识符和值/掩码类型上有所不同-这些字段对于每个组合都是常量,所以我将其定义为枚举常量。F.e.20仅具有不同的TypeID,但具有相同的VendorID,并且它们都可以表示为整数,接下来的10具有不同的VendorID和TypeID,但它们都可以表示为Short,以此类推

可能使用如下设置值方法:

public enum Type {
    SOME_TYPE(new TypeID(0, (short) 0), OFMU16.class,
            new Instantiable<AType<?>>() {
                @Override
                public SpecType instantiate() {
                    return new SpecType(new OFMatchTypeIdentifier(0, (short) 0));
                }
            }),...;

    ...

    public Class<? extends AType<?>> toClass() {
    return this.clazz;
}

    ...

}
public void setValue(Object value) {
    if (value == null)
        throw new IllegalArgumentException("Value is mandatory.");
    this.value = (T)value;
}
虽然你将有一个未经检查的演员阵容


希望这能有所帮助

现在还不清楚你为什么要选演员。只要
SOME_TYPE
被写入源代码中,set
setValue
方法的类型就被硬编码(在您的示例中是
int
Integer
),您不需要运行时检查-您需要编译时检查

因此,我认为以下代码片段是API用户应该如何编写代码的:

public class TypeTest {
    public static void main(String[] args) {
        AType<Integer> type0 = Types.SOME_TYPE_0.instantiate();
        type0.setValue(10);

        AType<String> type1 = Types.SOME_TYPE_1.instantiate();
        type1.setValue("foo");
    }
}
清理:您的用户必须查看界面:是的,他在任何情况下都必须查看,因为他必须知道哪个类型适合
setValue
1。没有任何解决办法可以绕过这一点。尽管Eclipse可能会对您和您的用户有所帮助:在
main
中,只需键入
Types.SOME_type_1.instantiate()然后转到行的开头,点击Ctrl2+L(“分配给loccal变量”),Eclipse将为您替换
AType instantiate=
部分



1如果您的用户不知道
setValue
方法的正确类型,则您提出的问题是错误的。在这种情况下,您应该询问类似“如何设计通用安全转换设施?”的问题。

我不明白,如果您可以这样做,为什么您要强制转换:
AType type=SOME_type.newInstance();类型。设置值(10)AType。setValue(T值)
已参数化。这是不可用的:-/user仍然必须在枚举中查看它是什么类型,而不是超过适当的值。它可以很容易地抛出运行时异常:-/。静态强制转换可能是最好的解决方案,因为它是在编译时选择的。虽然它不是用户友好的。
((SpecType) type).setValue(10);
public void setValue(Object value) {
    if (value == null)
        throw new IllegalArgumentException("Value is mandatory.");
    this.value = (T)value;
}
public class TypeTest {
    public static void main(String[] args) {
        AType<Integer> type0 = Types.SOME_TYPE_0.instantiate();
        type0.setValue(10);

        AType<String> type1 = Types.SOME_TYPE_1.instantiate();
        type1.setValue("foo");
    }
}
abstract class AType<T> {
    private T value;

    // standard getter/setter
    public T getValue() { return this.value; }
    public void setValue(T value) { this.value = value; }
}

class SpecTypeInt extends AType<Integer> {
}

class SpecTypeString extends AType<String> {
}

interface Instantiable<T> {
    T instantiate();
}
interface Types {
    Instantiable<? extends AType<Integer>> SOME_TYPE_0 = new Instantiable<SpecTypeInt>() {
        @Override
        public SpecTypeInt instantiate() {
            return new SpecTypeInt();
        }
    };

    Instantiable<? extends AType<String>> SOME_TYPE_1 = new Instantiable<SpecTypeString>() {
        @Override
        public SpecTypeString instantiate() {
            return new SpecTypeString();
        }
    }  ;
}