Java Annotations

  • + 5 comments

    The description is so bad, no where to find why senior should have 100 and junior should have 50 as limits. But these values somehow work. Solution below passes all testcases.

    import java.lang.annotation.*;
    import java.lang.reflect.*;
    import java.util.*;
    
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @interface FamilyBudget {
       String userRole() default "GUEST";
       int budgetLimit() default 0;
        
    }
    
    class FamilyMember {
       @FamilyBudget(userRole = "SENIOR", budgetLimit = 100)
       public void seniorMember(int budget, int moneySpend) {
          System.out.println("Senior Member");
          System.out.println("Spend: " + moneySpend);
          System.out.println("Budget Left: " + (budget - moneySpend));
       }
     
       @FamilyBudget(userRole = "JUNIOR", budgetLimit = 50)
       public void juniorUser(int budget, int moneySpend) {
          System.out.println("Junior Member");
          System.out.println("Spend: " + moneySpend);
          System.out.println("Budget Left: " + (budget - moneySpend));
       }
    }
    
    public class Solution {
       public static void main(String[] args) {
          Scanner in = new Scanner(System.in);
          int testCases = Integer.parseInt(in.nextLine());
          while (testCases > 0) {
             String role = in.next();
             int spend = in.nextInt();
             try {
                Class annotatedClass = FamilyMember.class;
                Method[] methods = annotatedClass.getMethods();
                for (Method method : methods) {
                   if (method.isAnnotationPresent(FamilyBudget.class)) {
                      FamilyBudget family = method
                            .getAnnotation(FamilyBudget.class);
                      String userRole = family.userRole();
                      int budgetLimit = family.budgetLimit();
                      if (userRole.equals(role)) {
                         if(budgetLimit >= spend){
                            method.invoke(FamilyMember.class.newInstance(),
                                  budgetLimit, spend);
                         }else{
                            System.out.println("Budget Limit Over");
                         }
                      }
                   }
                }
             } catch (Exception e) {
                e.printStackTrace();
             }
             testCases--;
          }
       }
    }
    
    • + 2 comments

      Although, I read tutorials and implemented the code, I dont know how it works. I mean, the family by default doesn't have senior or junior user. Which means, the familymember class don't know which method to invoke, when two parameters are passed.

      I dont see any line that sets the userRole in the class as SENIOR or JUNIOR. I see the below line.

      String userRole = family.userRole();
      int budgetLimit = family.budgetLimit();
      

      This is infact, setting userRole from family. the default in family is guest, so it should set userRole as Guest which will never be equal to the inputs passed.

      Am I understanding something different?

      • + 1 comment

        basically you need to pass value inside annotation. e.g @FamilyBudget(userRole = "SENIOR", budgetLimit = 100)

        • + 3 comments

          How can we figure out that budget limit is 50&100. Nowhere it is mentioned.

          • + 0 comments

            You just had to guess from the test case they provided. The challenge was poorly written.

          • + 0 comments

            when you look to sample input and sample output and the differnence between budget spent and left u will figure out that sunior must have 100 as budget limit and junior must have 50.

          • + 0 comments

            Yes this was just a little trick. We had to calculate from their Sample Output.

            Spend: 75 Budget Left: 25 => budgetLimit 100 Spend: 45 Budget Left: 5 => budgetLimit 50

      • + 0 comments

        The code loops through all of the methods in the FamilyMember class (seniorMember(...) and juniorUser(...)) for each test. For each method, it gets the annotations and checks to see if it's a valid method to call for the current role; if it is, it calls it with the method.invoke(...) line.

        In other words, this is very obviously tutorial code, not something you would (I hope!) write in the real world. It's not going to be very performant; it would perform weirdly if there were multiple methods for the same role; and if the methods have different footprints, it throws an "IllegalArgumentException" at run (not compile) time.

        This test shows you how annotations can be used, but not how they should be.

    • + 0 comments

      Ya so true !! I was also get confused!! but finally found ;)

    • + 0 comments

      The values of 100 and 50 can be found by reverse engineering it (look at the input and output, you will see that the initial budget must be so). In addition, my test cases appear to fail even when the input/output matches exactly. They do not mention how to set the cardinality of the userRole, a.k.a. |userRole|.

    • + 0 comments

      you saved my 2 hr, I was stuck at the output, output was correct but still failing, poor explanation of question, these questions forced programmers to loose interest as lot of time get wasted.

      Thanks, Atishay

    • + 0 comments

      What is the purpose of the @FamilyBudget annotation?