Best practice for returning multiple values in Java?

前端 未结 7 1176
走了就别回头了
走了就别回头了 2020-12-05 17:31

Today I\'ve added a extra security check behind my login forms, to slow down brute force attacks. I\'ve got multiple login forms and made a nice easy to call function that d

相关标签:
7条回答
  • 2020-12-05 18:13

    Not sure about "best practice" but a pragmatic option is to return a Map<String, String>? E.g.

    myMap.put("result", "success");
    myMap.put("usernameConfirmed", "bigTom");
    
    return myMap;
    

    Probably flies in the face of a million OO principles but I hear you re wanting to avoid a proliferation of result classes.

    You could alternatively use Map<String, Object> and be stricter with type checks on stored objects: Strings, Booleans, Dates, etc.

    0 讨论(0)
  • 2020-12-05 18:16

    No, this kind of structure doesn't exists nativily in Java, but you can look at JavaTuples library that may suit your need and provide a quite elegant solution. Using a Triplet<Boolean, String, Boolean>

    0 讨论(0)
  • 2020-12-05 18:20

    You can define a Pair<A, B> class, and a Triplet<A, B, C> class, and that would solve the problem of returning 2 and 3 values while ensuring type-safety. In this particular case, the signature could be

    public static boolean validateLogin(HttpServletRequest request,
                String email, String password, Pair<Message, Boolean> outputIfOk);
    

    Or even better, in a servlet context, it may make sense to set some well-documented request attributes.

    If you find yourself needing special classes to return results very often, you can most likely refactor those clases to share a common ancestor (say, have a RequestStatus which includes the 'ok' and 'message' fields).

    Other than that, yes, you are being lazy -- custom clases will always be more self-documenting than Pairs and Triplets.

    0 讨论(0)
  • 2020-12-05 18:20

    I'd probably just go the class route myself, but depending on what you want the function to return, you might be able to get away with returning some sort of container of values.

    0 讨论(0)
  • 2020-12-05 18:20

    Here is a possible solution I picked up from another discussion, and enhanced a bit. It uses a public inner class with a private constructor:

    public class Test {
        // Internal storage unit for the two values:
        // 'name' and 'age'.
        private Pair<String, Integer> info;
    
        public Test() {
            // Empty default constructor.
        }
    
        /**
         * The two values are stored in the Test class.
         *
         * @param name
         * @param age
         */
        public void setInfo(String name, int age) {
            info = new Pair<>(name, age);
        }
    
        /**
         * The 'name' and 'age' values are returned in a
         * single object.
         *
         * @return Both values in a Pair object.
         */
        public Pair<String, Integer> getInfo() {
            return info;
        }
    
        /**
         *  This is an Inner Class for providing pseudo 'tuplet'
         *  as a 'get' return value.
         *
         * @param <F> first internally stored value.
         * @param <S> second internally stored value.
         */
        public class Pair<F, S> {
    
            public final F first;
            public final S second;
    
            // This constructor is private to prevent
            // it being instantiated outside its
            // intended environment.
            private Pair(F first, S second) {
                this.first = first;
                this.second = second;
            }
    
            @Override
            public String toString(){
                return first + ", " + second;
            }
        }
    
        /**
         * main method for testing of the class only.
         *
         * @param args
         */
        public static void main(String args[]) {
            Test test = new Test();
    
            test.setInfo("Peter Smith", 35);
            Test.Pair<String, Integer> pair = test.getInfo();
    
            System.out.println("name: " + pair.first);
            System.out.println("age: " + pair.second);
            System.out.println(pair.toString());
        }
    }
    
    0 讨论(0)
  • 2020-12-05 18:27

    You can return an Object[] array, java autoboxes so its more easy to use. If it's just for a short distance handover, why not. Ofc its risky, possible class cast trouble, nullchecks etc

    but its easy to write and use.

    then again, a static inner class is quickly created and if you put it right next to the method returning it, you also know where to find it (usually near the origin)

    0 讨论(0)
提交回复
热议问题