重载方法的Java动态转换
我试图创建一个函数,在这个函数中,我可以传递名称和值,这些名称和值将被放入一个函数中。我遇到的问题是,我试图允许一次传递多个键/值对,因此键可以是字符串数组,但值必须是对象和ContentValue。put()不允许对象,它们需要转换为String、Double、Float、,等等。是否有一种方法可以确定对象的类型并强制转换它,以便它调用正确的put()?下面是一个有效的方法,但它要求我为每种可能的值类型添加一个if重载方法的Java动态转换,java,Java,我试图创建一个函数,在这个函数中,我可以传递名称和值,这些名称和值将被放入一个函数中。我遇到的问题是,我试图允许一次传递多个键/值对,因此键可以是字符串数组,但值必须是对象和ContentValue。put()不允许对象,它们需要转换为String、Double、Float、,等等。是否有一种方法可以确定对象的类型并强制转换它,以便它调用正确的put()?下面是一个有效的方法,但它要求我为每种可能的值类型添加一个if public long create(String[] names, Obj
public long create(String[] names, Object[] values) {
ContentValues initialValues = new ContentValues();
for (int i = 0; i < names.length; i++)
{
String type = values[i].getClass().getName();
if (type.equals("java.lang.Double"))
{
initialValues.put(names[i], (Double)values[i]);
}
else if (type.equals("java.lang.String")) {
initialValues.put(names[i], (String)values[i]);
}
else
{
throw new InvalidParameterException("Unable to convert type:"+type);
}
}
return mDb.insert(this.getTableName(), null, initialValues);
}
public长创建(字符串[]名称,对象[]值){
ContentValues initialValues=新的ContentValues();
for(int i=0;i
您有两个选择:
一个要考虑的是空值。如果传入的值为null,则没有类,因此您无法确定类型(如果该类型与您的使用相关)。
ContentValues应该按照您将要编写的内容提供一个putObject()方法。我可能倾向于使用提供该方法的类来扩展或包装ContentValue,从而使代码可重用您正在使用的if/else方法可能会让人觉得乏味,但会明确地说出您的意思,而生成简单、可维护的代码是我的首要任务。使用反射也是可能的,但实现起来更复杂。我会坚持你所做的 您的方法是正确的,尽管您应该使用
instanceof
而不是getClass().getName()
。即:
if (values[i] == null) {
initialValues.putNull(names[i]);
} else if (values[i] instanceof Boolean) {
initialValues.put(names[i], (Boolean)values[i]);
} else if (values[i] instanceof Byte) {
initialValues.put(names[i], (Byte)values[i]);
} else if (values[i] instanceof Double) {
initialValues.put(names[i], (Double)values[i]);
} else if (values[i] instanceof Float) {
initialValues.put(names[i], (Float)values[i]);
} else if (values[i] instanceof Integer) {
initialValues.put(names[i], (Integer)values[i]);
} else if (values[i] instanceof Long) {
initialValues.put(names[i], (Long)values[i]);
} else if (values[i] instanceof Short) {
initialValues.put(names[i], (Short)values[i]);
} else if (values[i] instanceof String) {
initialValues.put(names[i], (String)values[i]);
} else if (values[i] instanceof byte[]) {
initialValues.put(names[i], (byte[])values[i]);
} else if (values[i] instanceof ContentValues) {
initialValues.putAll(names[i], (ContentValues)values[i]);
} else {
throw new IllegalArgumentException(
"can't put " + values[i].getClass().getName() + " in ContentValues.");
}
另一个选择是使用反射,但我认为反射是一种最后的方法。< /P>
如果
ContentValues
不是final
的话,另一个选择是对其进行扩展,并添加一个方法,该方法采用对象
这是尽可能简洁、高效和正确的,依我看。编译器可以优化类型转换,但这并不重要
public long create(String[] names, Object[] values) {
ContentValues initialValues = new ContentValues();
for (int i = 0; i < names.length; i++) {
Object v = values[i];
if (v instanceof Double) {
initialValues.put(names[i], (Double) v);
} else if (v instanceof String) {
initialValues.put(names[i], (String) v);
} else {
// You could test for v == null here ... otherwise you'll
// get an NPE
throw new InvalidParameterException(
"Unable to convert type: " + v.getClass());
}
}
return mDb.insert(this.getTableName(), null, initialValues);
}
public长创建(字符串[]名称,对象[]值){
ContentValues initialValues=新的ContentValues();
for(int i=0;i
一些注意事项:
instanceof
Double.class.getName()
实际上给出了“java/lang/Double”
而不是“java.lang.Double”
的instanceof
慢,而且并不总能给出正确的答案。如果某个类正在使用类加载器技巧,则不同的类可以具有由getName()
和getCanonicalName()
报告的相同名称为什么你认为反思是一种最后的方法?在我看来这是个好方法。为什么要使用instanceof?primitive的包装始终是最终的。。不需要检查子类dfa:instanceof更一般、更简洁。为什么不使用instanceof?@Asa:除了成本高昂之外,反射通常会导致代码更难维护,并且会破坏静态分析(包括编译时类型检查、重构工具等)。一般来说,如果不使用反射就可以完成同样的事情,那么不要使用反射。为什么要使用instanceof?primitive的包装始终是最终的。。不需要检查子类在这种情况下,instanceof应该比String.equals()调用快。一般来说,我们不能假设所有类型都是最终的。事实上,如果涉及类加载器,比较类名可能不足以区分类。您也可以对原语而不是instanceof执行(object.getClass()==String.class)。这可能是被暗示的,而不是.equals()。我是为android编写的,据我所知它使用Java5,但我对Java是新手,我不知道如何验证这一点。