我有几个(超过20个)方法(getXXX()
)可能会在调用它们时引发异常(NotCalculatedException
)。
在另一种方法中,我需要访问这些方法给出的结果。目前,我有一个可怕的代码,看起来像:
public void myMethod() {
StringBuffer sb = new StringBuffer();
// Get 'foo' result...
sb.append("foo = ");
try {
sb.append(getFoo());
} catch (NotCalculatedException nce) {
sb.append("not calculated.");
}
// Get 'bar' result...
sb.append("\nbar = ");
try {
sb.append(getBar());
} catch (NotCalculatedException nce) {
sb.append("not calculated.");
}
...
}
不修改getXXX
方法(因此他们必须保留throws NotCalculatedException
),您如何重构/简化myMethod()
以使其看起来更好?< / p>
请注意,此项目仍在使用Java 1.4 :(
修改
我无法将所有getXXX()
方法放在try { ... }
块中,因为如果一个方法抛出NotCalculatedException
,StringBuffer将不完整。
public void myMethod() {
StringBuffer sb = new StringBuffer();
try {
sb.append("foo = ");
sb.append(getFoo());
sb.append("\nbar = ");
sb.append(getBar());
} catch (NotCalculatedException nce) {
sb.append("not calculated.");
}
...
}
换句话说,如果getFoo()
抛出NotCalculatedException
,我希望有这种输出:
foo = not calculated
bar = xxx
...
如果我把所有内容放在一个try { ... }
中,我会得到那个我不想得到的输出:
foo = not calculated
答案 0 :(得分:2)
我认为你不应该使用NotCalculatedException来控制逻辑。
但我对此有一些了解。
您需要另一个getter方法
sb.append(this.getFoo(“not calculated”));
创建hasValue方法
sb.append(hasFoo()?this.getFoo():“not calculated”);
创建一个通用的getter方法
sb.append(this.getValueByName( “富”));
答案 1 :(得分:1)
对于每个getXXX
,您可以添加包裹异常的getXXXOrDefault()
,并返回getXXX
或“未计算”的值。
public void myMethod() {
StringBuffer sb = new StringBuffer();
// Get 'foo' result...
sb.append("foo = ");
sb.append(getFooOrDefault());
// Get 'bar' result...
sb.append("\nbar = ");
sb.append(getBarOrDefault());
// ...
}
public Object getFooOrDefault() {
try {
return getFoo();
} catch() {
return "not calculated.";
}
}
或者......使用反思
public Object getValueOrDefault(String methodName) {
try {
// 1 . Find methodName
// 2 . Invoke methodName
} catch() {
return "not calculated.";
}
}
但我认为我仍然更喜欢第一种选择。
答案 2 :(得分:1)
我的建议是更多代码,但改进了myMethod的可读性:
public void myMethod() {
StringBuilder resultBilder = new StringBuilder();
resultBuilder.append("foo=");
appendFooResult(resultBuilder);
resultBuilder.append("\nbar=");
appendBarResult(resultBuilder);
...
}
private void appendFooResult(StringBuilder builder) {
String fooResult = null;
try {
fooResult = getFoo();
} catch (NotCalculatedException nce) {
fooResult = "not calculated.";
}
builder.append(fooResult);
}
private void appendBarResult(StringBuilder builder) {
String barResult = null;
try {
barResult = getBar();
} catch (NotCalculatedException nce) {
barResult = "not calculated.";
}
builder.append(barResult);
}
答案 3 :(得分:1)
我认为你应该保留你的代码。它很冗长,但很容易分辨出它的作用,而且行为正确。
答案 4 :(得分:0)
您可以在数组中存储“foo”,“bar”等。围绕这些循环,打印出每个,然后使用反射来查找/调用相应的getFoo(),getBar()。不好,我承认。
有关详细信息,请参阅Method对象。
编辑:或者,利用AspectJ围绕该对象的每个getXXX()方法调用并捕获异常。
答案 5 :(得分:0)
你可以使用Execute Around成语。不幸的是,Java语法很冗长,所以在简单的情况下它并不是一个好的结果。假设NotCalculatedException
是一个unchekd异常。
appendThing(sb, "foo = ", new GetValue() { public Object get() {
return getFoo();
}});
appendThing(sb, "bar = ", new GetValue() { public Object get() {
return getBar();
}});
另一个丑陋的方法是结合循环和开关:
int property = 0;
lp: for (;;) {
String name = null; // Ugh.
try {
final Object value;
switch (property) {
case 0: name= "foo"; value = getFoo(); break;
case 1: name= "bar"; value = getBar(); break;
default: break lp;
}
++property;
sb.append(name).append(" = ").append(value).append('\n');
} catch (NotCalculatedException exc) {
sb.append(name).append(" = ").append("not calculated.\n");
}
}
或者,为每个参数设置枚举和开关。只是不要使用反射!
答案 6 :(得分:0)
似乎Java没有C#开箱即用的代表 - 但谷歌向我展示了ways to roll your own。所以以下内容可能会尝试......
public static PrintProperty(JavaDelegateWithAName del, StringBuilder collector)
{
try
{
collector.append( del.Name+ " = " );
collector.append( del.Target.Invoke() );
}
catch(NotCalculatedException nce)
{ collector.append("NotCalculated"); }
}
...主要
foreach(JavaDelegateWithAName entry in collectionOfNamedJavaDelegates)
SomeUtilityClass.PrintProperty(entry, sb);