How to avoid forgetting to process properties?
Having this class
Class Test
{
static int version=1;
String A;
String B;
//constructor
//setters, getters, etc...
public void printAll(void)
{
System.out.println(A);
System.out.println(B);
}
}
After a while, we modify the Class to add a Strin开发者_开发技巧g C :
Class Test
{
static int version=2;
String A;
String B;
String C;
//constructor
//setters, getters, etc...
public void printAll(void)
{
System.out.println(A);
System.out.println(B);
//it seems somebody has forgotten to print C!!!!!!!!!
}
}
Is here some known approach to avoid this kind of bug?
Thanks
A code review should catch this issue. Aside from a code review, unit testing or debugging would normally tell you if your code is behaving how it should. If you didn't process certain properties your tests should fail because at some point a method/property/result would not be correct. Other than those things I think using reflection is way overboard.
You can use annotations to have a more structured way to use reflection, where you better control which fields will be printable:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
@interface Printable { }
class Test {
@Printable String A;
@Printable String B;
@Printable String C;
public void printAll() {
for (Field field : getClass().getDeclaredFields()) {
if (field.isAnnotationPresent(Printable.class)) {
try {
System.out.println(field.get(this));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
}
I'm not sure if it's recommended, but you could get the fields of an object in the following way:
import java.lang.reflect.Field;
Field[] fields = object.getClass().getDeclaredFields();
for (int i = 0 ; i < fields.length ; i++)
System.out.println(fields[i]);
You have some code that adding, deleting or modifying in a place, affects in other. In this particular case, your function calls all properties.
You may want to something like C++, where classes doesn't have explicit properties like Java, and are emulated using either a macro or a collection.
package mycompany.myapp;
import propertiesgenerics;
Class Test
{
static int version=1;
public property<String> A;
public property<String> B;
public list< property<string> > Properties;
public Bicycle() {
public property<String> A = new property<String>();
public property<String> B = new property<String>();
Properties.add(A);
Properties.add(B);
}
//constructor
//setters, getters, etc...
public void printAll(void)
{
// iterating thru this.properties
for loop {
System.out.println(eachProperty);
} // for loop
}
}
If not a fan of misusing reflection, due to the fact that not all fields are treated like properties, and not all properties are treated like fields.
You can use org.apache.commons.lang.builder.ToStringBuilder:
public void printAll() {
System.out.println(ToStringBuilder.reflectionToString(this));
}
or
public void printAll() {
System.out.println(new ToStringBuilder(this).
append("name", name).
append("age", age).
append("smoker", smoker).
toString());
}
Sometimes the best strategy is just to put comments above your property list:
// Remember to include any new properties in the printAll method!
String A;
String B;
Apart from that, I agree with KyleM, that a code review is essential for catching issues like this.
I'm not sure I'd qualify forgetfulness as a bug. I think the best way to handle something like this is to use a source control program, so you can track changes to your files.
http://tortoisesvn.net/: this is a good one
精彩评论