[英]Java dynamic casting for overloaded methods
我正在嘗試創建一個函數,我可以傳遞將放入ContentValues的名稱和值。 我遇到的問題是我試圖允許一次傳遞更多的一個鍵/值對,因此鍵可以是一個字符串數組,但值必須是對象,而ContentValues.put()不是允許對象,需要將它們轉換為String,Double,Float等。有沒有辦法可以確定對象的類型並將其強制轉換,以便調用正確的put()? 下面是一個有效的方法,但它要求我為每種可能的值添加一個if。
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);
}
您的方法是正確的,但您應該使用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.");
}
另一個選擇是使用反射,但我認為反射是最后的手段。
如果ContentValues
不是final
另一個選項是擴展它並添加一個接受Object
的方法。
您有兩種選擇:
要考慮的一件事是空值。 如果傳入的值為null,則沒有類,因此您無法確定類型,如果這與您的使用相關。
IMO,這就像你可以做到的那樣整潔,高效和正確。 編譯器可能可以優化類型轉換,但這並不重要。
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);
}
一些說明:
instanceof
。 Double.class.getName()
實際上給出了"java/lang/Double"
而不是"java.lang.Double"
。 instanceof
更慢之外,比較類名並不總能給出正確的答案。 如果某些東西正在進行類加載器技巧,則不同的類可以具有與getName()
和getCanonicalName()
報告的相同的名稱。 可以說,ContentValues應該提供一個putObject()方法,就像你要編寫的那樣。 我可能傾向於使用提供該方法的類來擴展或以其他方式包裝ContentValue,從而使代碼可重用。
您正在使用的if / else方法可能會令人煩惱地平淡無奇,但會明確說出您的意思,並且生成簡單,可維護的代碼是我的優先事項。 使用反射也是可能的,但實施起來會更復雜。 我會堅持你正在做的事情。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.