[英]Subclassing a generic type, returning instances of the subclass from a method in another class
It was such a simple, brilliant idea. 这是一个简单,绝妙的主意。 Use the power of Java 5.0 enumerated types to encode details of a data dictionary (attribute name, type, range, units, etc.) and create a type-safe system for setting and reading attribute values (i,.e., attribute AAH is short, ACC is enumerated and should only accept the values ACC001, ACC002, ACC003, etc.).
使用Java 5.0枚举类型的功能来编码数据字典的详细信息(属性名称,类型,范围,单位等),并创建用于设置和读取属性值(即属性AAH)的类型安全的系统是简短的,将枚举ACC,并且应仅接受值ACC001,ACC002,ACC003等。
The hitch is that different attributes have different types (integer, float, text, enumerated), and the behaviors for each type are different. 困难在于不同的属性具有不同的类型(整数,浮点数,文本,枚举),并且每种类型的行为都不同。 So I create a base class with a type parameter and some abstract methods:
因此,我创建了一个带有类型参数和一些抽象方法的基类:
public abstract class GsAttributeValueBase<T extends Comparable<T>> {
protected T m_value;
...
public GsAttributeValueBase(...) {..}
...
public abstract void SetValue(T value) throws IllegalArgumentException;
public T GetValue() { return m_value; }
// etc., etc., etc
}
I then subclass this for each type (basically, I'm trying to fake partial specialization): 然后,我为每种类型将此子类化(基本上,我试图伪造部分专门化的代码):
public class GsAttributeValueShort extends GsAttributeValueBase<Short> {...}
public class GsAttributeValueLong extends GsAttributeValueBase<Long> {...}
public class GsAttributeValueEncoded extends GsAttributeValueBase<GsAttributeEncodedValueEnum> {...}
...
So far so good. 到现在为止还挺好。 Now I want to basically create a factory method in the attribute enumeration type to return an instance of one of the above subtypes (since each attribute knows its type and range), something like
现在,我想基本上在属性枚举类型中创建一个工厂方法以返回上述子类型之一的实例(因为每个属性都知道其类型和范围),例如
public GsAttributeValueBase<? extends Comparable<?>> CreateInstance()
{
switch(m_format)
{
case SHORT: return new GsAttributeValueShort(...);
case LONG: return new GsAttributeValueLong(...);
case ENCODED: return new GsAttributeValueEncoded(...);
...
}
}
and call the method as: 并按以下方式调用方法:
GsAttributeValueShort = GsAttributeEnum.AAH.CreateInstance();
This is where I hit a brick wall; 这是我撞砖墙的地方。 I get an incompatible types error on the order of
我收到一个不兼容的类型错误,顺序为
found : GsAttributeValueBase<capture of ? extends java.lang.Comparable<?>>
required: GsAttributeValueShort
I've tried roughly a dozen permutations on the declaration of CreateInstance() so far (it can't be static, since it relies on information specific to the enumeration instance). 到目前为止,我已经对CreateInstance()的声明进行了大约十二种排列(它不能是静态的,因为它依赖于枚举实例的特定信息)。 I'm about to tear my hair out at this point;
我现在要把头发扯掉。 I've wasted several days going down this rabbit hole, and need to either get this working today or punt altogether.
我已经浪费了几天的时间在这个兔子洞里,需要今天就使它工作或完全平移。
I really want to make this work; 我真的很想完成这项工作; I think it would be valuable to not just this project but other projects going forward.
我认为这不仅对这个项目而且对将来的其他项目都是有价值的。 But Java generics don't behave like C++ templates (something that's been driven home with a vengeance over the past week), and I know I'm missing something vital here, but I can't see what it is.
但是Java泛型的行为不像C ++模板(在过去的一周里被报复了),我知道我在这里缺少了一些重要的东西,但是我看不到它是什么。
EDIT 编辑
I can't make this work the way I'm envisioning in my head and I've burned too much time on it. 我无法按照我脑海中所想的方式进行这项工作,我为此花费了太多时间。 Thanks for the suggestions, but I'm going to go ahead and close this down.
感谢您的建议,但我将继续进行下去。
EDIT 2 编辑2
Oh. 哦。 I can't close my own question.
我无法回答自己的问题。 Oh well.
那好吧。
What about: 关于什么:
public <T extends Comparable<T>> GsAttributeValueBase<? super T> CreateInstance() {
...
}
Just use a map and my TypeSafeMap pattern . 只需使用地图和我的TypeSafeMap模式即可 。
Some thoughts on Generics: Generics are meant to make collections type safe. 关于泛型的一些想法:泛型用于使集合类型安全。 They aren't really intended for complex things like building type-safe classes at runtime.
它们并不是真正用于复杂的事情,例如在运行时构建类型安全的类。 So be mindful and use your tools so that they don't become a burden.
因此,请注意并使用您的工具,以免它们成为负担。 If a cast works and you don't understand how the generic construct works (even if you just wrote it), use the cast.
如果强制转换有效, 并且您不了解泛型构造的工作原理(即使您刚刚编写过),也可以使用强制转换。 Just imagine coming back to this code in half a year and having to fix it.
试想一下,半年后会回到此代码并必须对其进行修复。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.