执行时确定实例字段类型的通用参数
Generic parameter determining instance field type at execution
情况说明:
我想实例化一个基本上有 2 个参数的对象。一组 'meta-parameters' 和一个值。值的类型由 'meta-parameters'.
决定
示例:
public class Meta
{
public static final Meta META_FIRST = new Meta(String.class, new byte[] {0x00, 0x01});
public static final Meta META_SECOND = new Meta(Float.class, new byte[] {0x00, 0x02});
public static final Meta META_THIRD = new Meta(Double.class, new byte[] {0x00, 0x03});
private Class<?> type;
private byte[] prelude;
private Meta(Class<?> type, byte[] prelude)
{
this.type = type;
this.prelude = prelude;
}
public Class<?> getType()
{
return this.type;
}
public byte[] getPrelude()
{
return this.prelude;
}
}
public class Record
{
private # value;
private byte[] prelude;
public Record(Meta meta, # value)
{
this.prelude = meta.getPrelude();
}
public void doSomeWork()
{
//Do some work with prelude and value
}
}
预期用途:
Record recordString = new Record(Meta.META_FIRST, "hello");
Record recordDouble = new Record(Meta.META_THIRD, 12.8);
我的疑问是如何确定'value'的类型(实际上用'#'表示)。
我认为泛型或反射可以解决我的问题,但我无法弄清楚构造函数中的参数如何影响另一个参数的类型。
我想在实例化记录时避免使用通用符号(这就是为什么我将此 'generic' 信息放在 Meta-class 中的原因)。
谁能知道如何解决这个问题? (随意提出其他方法)
注意:我后面用一个setter初始化记录值也是可以接受的。
为了让它编译,你必须使 Record
class 通用(由值的类型参数化):
public class Record<T> {
private T value;
public Record(Meta meta, T value) {
//Initialization
}
}
但是,我看不出你有一个 Meta
class 的原因,因为它除了保持 Class
什么都不做value
的类型。为了简化层次结构并确保 Meta
与 value
类型兼容,我将删除 Meta
class 并在 Record
中保留一个 Class<T>
,这将代表关于 value
.
的元数据
public class Record<T> {
private T value;
private Class<T> meta;
public Record(T value, Class<T> meta) {
//Initialization
}
public Class<T> getMeta() {
return meta;
}
}
并将像这样使用它:
Record recordString = new Record("hello", String.class);
Class<String> recordStringMeta = recordString.getMeta();
Record recordDouble = new Record(12.8, Double.class);
Class<Double> recordDoubleMeta = recordDouble.getMeta();
更新:
因为你不想要 Record
class 泛型(我不建议你,但是......),你可以在那里引入三个构造函数和 将传递的 value
复制 给 Object
成员。不幸的是,这将迫使您在提取值时进行转换:
public class Record {
private Object value;
public Record(Meta meta, String value) { ... }
public Record(Meta meta, Double value) { ... }
public Record(Meta meta, Float value) { ... }
}
情况说明:
我想实例化一个基本上有 2 个参数的对象。一组 'meta-parameters' 和一个值。值的类型由 'meta-parameters'.
决定示例:
public class Meta
{
public static final Meta META_FIRST = new Meta(String.class, new byte[] {0x00, 0x01});
public static final Meta META_SECOND = new Meta(Float.class, new byte[] {0x00, 0x02});
public static final Meta META_THIRD = new Meta(Double.class, new byte[] {0x00, 0x03});
private Class<?> type;
private byte[] prelude;
private Meta(Class<?> type, byte[] prelude)
{
this.type = type;
this.prelude = prelude;
}
public Class<?> getType()
{
return this.type;
}
public byte[] getPrelude()
{
return this.prelude;
}
}
public class Record
{
private # value;
private byte[] prelude;
public Record(Meta meta, # value)
{
this.prelude = meta.getPrelude();
}
public void doSomeWork()
{
//Do some work with prelude and value
}
}
预期用途:
Record recordString = new Record(Meta.META_FIRST, "hello");
Record recordDouble = new Record(Meta.META_THIRD, 12.8);
我的疑问是如何确定'value'的类型(实际上用'#'表示)。 我认为泛型或反射可以解决我的问题,但我无法弄清楚构造函数中的参数如何影响另一个参数的类型。
我想在实例化记录时避免使用通用符号(这就是为什么我将此 'generic' 信息放在 Meta-class 中的原因)。
谁能知道如何解决这个问题? (随意提出其他方法)
注意:我后面用一个setter初始化记录值也是可以接受的。
为了让它编译,你必须使 Record
class 通用(由值的类型参数化):
public class Record<T> {
private T value;
public Record(Meta meta, T value) {
//Initialization
}
}
但是,我看不出你有一个 Meta
class 的原因,因为它除了保持 Class
什么都不做value
的类型。为了简化层次结构并确保 Meta
与 value
类型兼容,我将删除 Meta
class 并在 Record
中保留一个 Class<T>
,这将代表关于 value
.
public class Record<T> {
private T value;
private Class<T> meta;
public Record(T value, Class<T> meta) {
//Initialization
}
public Class<T> getMeta() {
return meta;
}
}
并将像这样使用它:
Record recordString = new Record("hello", String.class);
Class<String> recordStringMeta = recordString.getMeta();
Record recordDouble = new Record(12.8, Double.class);
Class<Double> recordDoubleMeta = recordDouble.getMeta();
更新:
因为你不想要 Record
class 泛型(我不建议你,但是......),你可以在那里引入三个构造函数和 将传递的 value
复制 给 Object
成员。不幸的是,这将迫使您在提取值时进行转换:
public class Record {
private Object value;
public Record(Meta meta, String value) { ... }
public Record(Meta meta, Double value) { ... }
public Record(Meta meta, Float value) { ... }
}