如何最好地编码以下内容?它可行吗?请参阅说明

时间:2012-08-15 09:30:09

标签: java coding-style

正如您将在下面看到的那样。我正在编写一个名为Property的类,它可以绑定到任何Serializable类型,从类描述中可以看出。

现在,在编译期间,属性中的值自动绑定为T类型。

我想实现一个Class getType()方法,该方法应该在运行时返回值的Class对象,即

Property<String> p = new Property<String>();

Class<String> cl = p.getType(); 

这里我希望cl是String.class。当然有一种方法是:

return value == null ? null : value.getClass();

问题是它不会反映在返回的类型中并返回原始类型的Class对象。 理想情况下,我希望它是Class<String>

类型
public class Property<T extends Serializable> implements Serializable {

    private T value = null ;
    private String name = null ;
    private boolean dirty = false ;
    private Entity parent = null ;

    public Class getType() {
        // Here I want to determine the type of T that this object is bound to ?
        return class; 
    }

    public T getValue() {
        return value;
    }

    public void setValue(T value) {
        this.value = value; 
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isDirty() {
        return dirty;
    }

    public void setDirty(boolean dirty) {
        this.dirty = dirty;
    }

    public Entity getParent() {
        return parent;
    }

    public void setParent(Entity parent) {
        this.parent = parent;
    }
}

3 个答案:

答案 0 :(得分:6)

简而言之,您不能,因为在运行时类型为erased

但是,你可以这样做(缩写为相关代码):

public class Property<T extends Serializable> implements Serializable {

    private T value = null;
    private final Class<T> clazz;

    // The constructor requires an instance of the Class<T>
    public Property(Class<T> clazz) { 
        this.clazz = clazz;
    }

    // Return a typed Class object
    public Class<T> getType() {     
         return clazz;  // echo back a typed Class object pass to the constructor
    }

传递给构造函数的Class<T>对象通常称为“类型标记”。

答案 1 :(得分:1)

你可以写一个方法

public Class<? extends T> getType() {
    return value == null ? null : value.getClass();
}

这将返回{em>运行时类型value,并在编译时提供尽可能多的有关返回类的信息:它将是T或任何子类T

如果你想总是返回Class<T>,那么你必须提供类作为运行时参数,就像@Bohemian describes一样。由于类型擦除,泛型类的类型参数在运行时不可用。

答案 2 :(得分:1)

由于type erasure,你不可能这样做。一个结果是,用于实例化类型参数的类型不能在运行时直接确定。

以下是两种选择:

1)使用getClass()获取属性的的类型。

    public Class getType() {
        return value.getClass();
    }

2)明确地将实际类型为T的Class对象作为构造函数参数传递。请注意,泛型键入意味着您不会意外地传递错误的Class对象

    private T value = null;
    private Class<T> type;

    public Property(Class<T> type) { this.type = type; }

    public Class<T> getType() { this.type; }

还有另一种方法(从设计的角度来看,这可能不会起作用),你可以在这里修改Property类; e.g。

    public class IntegerProperty extends Property<Integer> {
        public Class getType() {
            returns Integer.class;
        }
    }

这里有一些聪明的变体,其中匿名类中泛型类的子类,和/或您通过getClass().getTypeParameters()访问类型参数。但请注意,如果您为类型参数扩展了具有特定类型的泛型类,则getTypeParameters()方法可用。