我想知道是否有办法通过将Class类型与对象一起存储来自动将对象转换为某种类型?我认为这可能是Java,但也许不是。
例如:
class StorageItem
{
private int itemcount;
StorageItem(int itemcount)
{
this.itemcount = itemcount;
}
int getItemCount()
{
return itemcount;
}
}
class Storage
{
private Class clazz;
private Object value;
public Storage(Class clazz, Object value)
{
this.clazz = clazz;
this.value = value;
}
//Is there a way such a call can be created to automatically cast
//the object to the class type and return that cast type in a
//generic way. The idea being that Storage knows what it should
//already be cast to. Is this possible?
public T getValue()
{
return clazz.cast(value);
}
}
用法示例:
public static void main(String[] args)
{
//Create storage item
Storage storage = new Storage(StorageItem.class, new StorageItem(1234));
//The call to getValue() will automatically cast to the Class passed
//into Storage.
int itemcount = storage.getValue().getItemCount(); //returns 1234
}
显然,Storage中的getValue()调用是伪代码调用,但它只是提供了我想做什么的想法。
无论如何都有一个getValue()调用,它会自动转换为存储在Storage类中的Class类型。同样,这个想法是Storage类知道它应该被强制转换为什么。或者,无论如何这可以完成吗?
StorageItem只是一个简单的例子。在这里,它只是存储一个int用于讨论目的。但是,它可能会更复杂。
另一个用法示例是将存储对象存储在列表中。
List<Storage> row = new ArrayList<Storage>();
row.add(new Storage(StorageItem.class, 1234));
row.add(new Storage(String.class, "Jason"));
row.add(new Storage(Integer.class, 30));
row.add(new Storage(Double.class, 12.7));
然后,可以通过以下方式访问这些内容。
//calls StorageItem's getItemCount() method
row.get(0).getValue().getItemCount(); //returns 1234
//calls String's length() method
row.get(1).getValue().length(); //returns 5
//calls Integer's intValue() method
row.get(2).getValue().intValue();
//calls Integer's doubleValue() method
row.get(3).getValue().doubleValue();
如果getValue()只返回一个Object,我必须总是手动转换为特定的Object。相反,如果我可以将转换类存储在Storage对象中,那么Storage有足够的信息来知道在getValue()调用中自动将Object转换为什么。
如果在Java中这是可行的,那就是我正在寻求的问题的答案。如果是这样,怎么样?
答案 0 :(得分:6)
这可以解决这个问题吗?需要更少的黑客攻击:
class Storage<T> {
private T value;
public Storage(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
答案 1 :(得分:1)
我真的没有看到你在这里试图解决的问题。 @ bali182的答案确实为您提供了存储引用的“通用”方法 - 但存储引用本身更容易。
考虑如果将包含不同类型引用的两个Storage
实例放入集合中会发生什么:
List<Storage<SOMETHING>> storages = new ArrayList<>();
storages.add(new Storage<String>("Hello"));
storages.add(new Storage<Integer>(1));
那么:SOMETHING
是什么?好吧,它必须是?
,因为这是唯一满足两个元素的类型。
现在,当您遍历列表以检索它们时,您必须将它们作为Object
处理:
for (Storage<?> storage : storages) {
Object object = storage.getValue();
// ...
}
因为您通常不知道任何给定元素的存储引用的类型。对于上面的列表,object
的具体类型将是元素的具体类型 - String
和Integer
- 但是如果不使用某些方法,则无法使用这些不同的类型检测该类型(例如if (object instanceof String)
)。
如果引用直接存储在列表中,那会更容易:
List<Object> objects = new ArrayList<>();
storages.add("Hello");
storages.add(1;
for (Object object : objects) {
// ...
}
你仍然需要做一些事情来检测对象的具体类型;你只是在没有额外的间接层的情况下这样做。
虽然上面的示例适用于不相关的类型,但如果它们是相同的类型,使用直接引用仍然更容易:
List<String> objects = Arrays.asList("Hello", "World");
for (String object : objects) {
// ...
}
现在你不需要做任何事情来了解具体类型(如果元素属于非final类,你想可能,并且你想特别处理一些子类),但是您仍然需要取消引用Storage.getValue()
以获得您可以直接获得的值。