执行时的通用参数确定实例字段类型

时间:2015-01-28 08:00:47

标签: java generics reflection

情况说明:

我想实现一个基本上有2个参数的对象。一组'元参数'和一个值。值的类型由'元参数'确定。

示例:

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);

我怀疑的是如何确定'价值'的类型(实际上用'#'表示)。 我认为泛型或反射可以解决我的问题,但我无法弄清楚构造函数中的参数如何影响另一个参数的类型。

我想避免在实现记录时使用通用符号(这就是为什么我在Meta类中放置这个'通用'信息的原因)。

任何人都有想法如何解决这个问题? (随意提出其他方法)

注意:稍后我也可以使用setter初始化记录值。

1 个答案:

答案 0 :(得分:1)

为了进行编译,您必须使Record类具有通用性(通过值的类型进行参数化):

public class Record<T> {
    private T value;

    public Record(Meta meta, T value) {
        //Initialization
    }
}

但是,我没有看到您拥有Meta课程的原因,因为除了Class类型value之外,它什么也没做}。为了简化层次结构并确保Meta value类型兼容,我会删除Meta类并保留{{1在Class<T>中,它将代表Record

的元数据
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(); 类通用(我不建议您,但......),您可以在那里引入三个构造函数并 copy < / em>已通过Recordvalue成员。不幸的是,这会强制你在提取值时强制转换:

Object