Java unpacking argument lists

后端 未结 2 1768
灰色年华
灰色年华 2021-02-20 10:40

Here\'s another question of \"How would I do this in Java?\" In Python, I can use the \'*\' symbol to unpack arguments like so:

>>> range(3, 6)                  


        
相关标签:
2条回答
  • 2021-02-20 10:52

    If the function you're calling is not a varargs function (declared with ...) then you do need to use reflection. Method.invoke() takes an array Object[] of arguments.

    The tough part via reflection is finding the right method (well, it's easy if there's only one method with the same name, otherwise it's very difficult).

    The cost is the extra time to lookup/invoke the method.


    Of course, if you know the specific method at compile-time, then you can deal with this manually, e.g. here for a 3-argument function:

    Object[] args = /* get args from somewhere */
    callSomeNonVarargsFunction((Cast1)args[0], (Cast1)args[1], (Cast1)args[2]);
    
    0 讨论(0)
  • 2021-02-20 11:14
    public void printStrings(String... strings)
    {
       // the strings parameter is really a String[].
       // You could do anything to it that you normally
       // do with an array.
       for(String s : strings){
          System.out.println(s);
       }
    }
    

    Can be called like this:

    String[] stringArray = new String[10];
    for(int i=0; i < stringArray.length; i++){
       stringArray[i] = "String number " + (i+1);
    }
    
    printStrings(stringArray);
    

    The ... syntax is really syntactic sugar for arrays.

    Java doesn't have the facility that you describe, but you could fake it several ways.

    I think the closest approximation means overloading any function that you want to use in that fashion using varargs.

    If you have some method:

    public void foo(int a, String b, Widget c) { ... }
    

    You can overload it:

    public void foo(Object... args) {
        foo((Integer)args[0], (String)args[1], (Widget)args[2]);
    }
    

    But this is really clumsy and error prone and hard to maintain.

    More generically, you could use reflection to call any method using any arguments, but it's got a ton of pitfalls, too. Here's a buggy, incomplete example of how it gets ugly really fast:

    public void call(Object targetInstance, String methodName, Object... args) {
        Class<?>[] pTypes = new Class<?>[args.length];
        for(int i=0; i < args.length; i++) {
            pTypes[i] = args[i].getClass();
        }
        Method targetMethod = targetInstance.getClass()
                  .getMethod(methodName, pTypes);
        targetMethod.invoke(targetInstance, args);
    }
    
    0 讨论(0)
提交回复
热议问题