简体   繁体   English

子类化泛型类型,从另一个类中的方法返回子类的实例

[英]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.

相关问题 子类化(通用)构建器的子类 - Subclassing a subclass of a (generic) builder 根据Java中的子类Type定义泛型类父类方法 - Define generic Type of parent class method depending on subclass Type in Java Java Generics:对一个通用超类进行子类化 - 是一个可再生类型的子类? - Java Generics: Subclassing a generic superclass - is subclass a reifiable type? Java方法返回的类的泛型类型 - Java method returning type of generic type of generic used at class 从另一个类调用子类方法时出错 - Error calling a subclass method from another class 在另一个函数中创建子类的实例时,为什么不能从子类类型的 Abstact 类调用方法(公共或静态)? - Why can't I call a method (public or static) from an Abstact class of type subclass when creating an instance of the subclass in another function? 在超类方法中返回泛型超类的子类 - Returning Subclass of generic superclass in a superclass method 返回通用类类型的方法的Java VM类型签名是什么? - What is the Java VM type signature for a method returning a generic class type? 如何覆盖将包含子类实例的 List 返回到原始方法 List 包含的类的方法? - How can I override a method returning a List containing instances of subclass to the class the original methods List contained? 从一个 class 返回到另一个 class 的方法 - Method returning from one class to another class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM