How to avoid forgetting about recycling 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 some time, we modify the class to add the string 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 there any known approach to avoid this kind of error?

thanks

+4
source share
7 answers

You can use annotations to have a more structured way of using reflection, where it is better to control which fields are available for printing:

 @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); } } } } } 
+1
source

A code review should catch this problem. In addition to reviewing the code, unit testing or debugging will usually tell you if your code works, how to do it. If you haven’t processed certain properties, your tests will not work, because at some point the method / property / result will be incorrect. Besides the things that, I think, using reflection is overboard.

+3
source

I'm not sure if it recommended, but you can get the fields of the object as follows:

 import java.lang.reflect.Field; Field[] fields = object.getClass().getDeclaredFields(); for (int i = 0 ; i < fields.length ; i++) System.out.println(fields[i]); 
+1
source

You have code that adds, deletes or changes in place, affects others. In this particular case, your function calls all the properties.

You may need something like C ++, where classes do not have explicit properties, such as Java, and are emulated using a macro or 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 the misuse of reflection, due to the fact that not all fields are treated as properties, and not all properties are treated as fields.

+1
source

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()); } 
+1
source

Sometimes the best strategy is to simply add comments above the property list:

 // Remember to include any new properties in the printAll method! String A; String B; 

In addition, I agree with KyleM that a code review is necessary to find such problems.

0
source

I'm not sure that I would qualify forgetfulness as a mistake. I think the best way to deal with something like this is to use a version control program so you can keep track of changes in your files.

http://tortoisesvn.net/ : this is a good one

-2
source

All Articles