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.
    static void printUserPreferences (Object obj) throws Exception {
        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
            }
        }
    }
    
    public static void main (String[] args) throws Exception {
        printUserPreferences(new Login());
    }
    
}