import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
// @UserPreference marks a field that should be exported.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface UserPreference {
}
// @HasUserPreferences marks a field that should be recursively scanned.
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@interface HasUserPreferences {
}
// Your example Login class, with added annotations.
class Login {
@UserPreference
public String token
; // <= a preference @UserPreference
public String customerid
; // <= a preference @HasUserPreferences public Class1 class1; // <= contains preferences
public class Class1 {
@HasUserPreferences public Class2 class2; // <= contains preferences
@UserPreference
public String string1
; // <= a preference
public class Class2 {
public int int1; // <= not a preference
@UserPreference
public String string2
; // <= a preference @UserPreference
public String string3
; // <= a preference }
}
// Construct example:
public Login () {
token = "token1";
customerid = "586969";
class1 = new Class1();
class1.string1 = "string1Value";
class1.class2 = class1.new Class2();
class1.class2.string2 = "string2Value";
class1.class2.string3 = "string3Value";
}
}
public class Main {
// Recursively print user preferences.
// Fields tagged with @UserPreference are printed.
// Fields tagged with @HasUserPreferences are recursively scanned.
for (Field field
: obj.
getClass().
getDeclaredFields()) { // Is it a @UserPreference?
if (field.getAnnotation(UserPreference.class) != null) {
String name
= field.
getName(); Class<?> type = field.getType();
Object value
= field.
get(obj
); System.
out.
println(name
+ " - " + type
+ " - " + value
); }
// Is it tagged with @HasUserPreferences?
if (field.getAnnotation(HasUserPreferences.class) != null) {
printUserPreferences(field.get(obj)); // <= note: no casts
}
}
}
printUserPreferences(new Login());
}
}