我正在为Android应用程序构建一个java单元转换器。我正在为用户提供大量不同的单位转换,最终可能会有220次转换,如果您只计算一个方向,则为110次。 I.E.米 - >脚和脚 - >米将是两种不同的转换。
截至目前,我正在计划为每次转换编写小方法,总共220个(我认为这可能是最简单的方法,甚至认为需要一些时间)。现在我的问题是,一旦我设置了2个变量(convertFrom和convertTo),我想知道是否可以动态调用正确的方法?我可以创建if / else if块,但这最终会成为疯狂的代码量,并且希望有更好的方法来调用基于上述2个变量的正确方法。有什么建议吗?
P.S。很抱歉这里没有代码,我只是刚刚开始在这里,我刚刚进入这个阶段的计划阶段。
答案 0 :(得分:0)
总的来说,你可以这样做:
//invoking a static method (no instance is required)
public Object invoke(final Class<?> clazz, final String name, final Class<?>[] paramTypes, final Object[] args){
return invoke(null, name, paramTypes, args);
}
//invoking a method on an object (instance is required)
public Object invoke(final Object instance, final Class<?> clazz, final String name, final Class<?>[] paramTypes, final Object[] args) throws Exception{
assert clazz != null && name != null : "clazz || method == null";
assert paramTypes.length == args.length : "paramTypes.length != args.length";
Method method;
try{
//to check if the method has been overridden or not
method = clazz.getDeclaredMethod(name, paramTypes);
}catch(NoSuchMethodException | SecurityException ex){
//if method doesn't exist, exception is thrown
method = clazz.getMethod(name, paramTypes);
}
//if method is protected or private
if(!method.isAccessible())
method.setAccessible(true);
return method.invoke(instance, args);
}
如果您尝试调用的方法没有任何参数,请传入一个空的Class<?>[]
(除了空Object[]
之外的参数也是如此)。从此方法返回的对象是刚刚调用的方法的结果。如果方法没有返回类型(void
),则返回null
。我们的想法是将结果基本上转化为您期望的结果。
答案 1 :(得分:0)
听起来你最好使用带有枚举类型的开关块。
你会创建一个这样的枚举:
public enum Units {
METERS_TO_FEET("meters", "feet"), FEET_TO_METERS("feet", "meters") /**, etc...*/;
private final String from;
private final String to;
public Units(final String from, final String to) {
this.from = from;
this.to = to;
}
public static Units fromStrings(String from, String to) {
if (from != null && to !=null) {
for (Unit u : Unit.values()) {
if (from.equalsIgnoreCase(u.from) && to.equalsIgnoreCase(u.to)) {
return u;
}
}
}
return null;
}
}
并在您的转换方法中使用开关块:`
public int convert(String convertFrom, String convertTo, float fromVal, float toVal) {
Units u = Units.fromStrings(convertFrom, convertTo);
if(u == null) {
throw new IllegalArgumentException("Bad input");
}
switch(u) {
case METERS_TO_FEET :
/** return meters to feet method on fromVal, toVal */
break;
case FEET_TO_METERS :
/** return feet to meters method on fromVal, toVal */
break;
/** etc. */
}
}
答案 2 :(得分:0)
如何使用将每个单元转换为一个标准测量单位的枚举。然后你可以调用转换将这个标准的测量单位变成你的新单位!
public enum UnitOfMeasure {
// look at the constructor for the meaning
// of the parameter
UNIT1 (1.01),
UNIT2 (1.02),
// ...
UNITX (2.00);
// conversionFactor will convert each UNIT
// type to your favorite UnitOfMeasure
private final double conversionFactor;
UnitOfMeasure(double conversionFactor) {
this.conversionFactor = conversionFactor;
}
// have a constant for every unit type
// to choose which unit to convert to
public static final int UNIT_X = 0;
public static final int UNIT_Y = 1;
// ... etc.
double convert(double value, int convertTo) {
// a newUnitConversionFactor to convert
// from our favorite unit of measurement
// to our desired unit
double newUnitConversionFactor = -1;
switch (convertTo) {
case UNIT_X:
newUnitConversionFactor = 1.00;
break;
case UNIT_Y:
newUnitConversionFactor = 1.01;
break;
// ... etc.
}
return value*conversionFactor*newUnitConversionFactor;
}
}
然后您可以通过选择要转换的单位和要转换为的单位进行转换。例如,如果我想将UNIT1的5.00转换为UNITX,我可以简单地使用它:
UnitOfMeasure.UNIT1.convert(5.00, UnitOfMeasure.UNIT_X);
这样,你也会知道是否会调用转换为你不支持的类型的请求,因为交换机什么都不做,结果是否定的。