开发者

Why widening beats both Boxing and var-args in Overloading of a method?

开发者 https://www.devze.com 2022-12-18 03:46 出处:网络
I am preparing for a SCJP exam and when studying widening part it\'s given that widening beats both Boxing and Var-args in overloading but there is no clear explanation. Tried searching but didnt get

I am preparing for a SCJP exam and when studying widening part it's given that widening beats both Boxing and Var-args in overloading but there is no clear explanation. Tried searching but didnt get an开发者_运维知识库y better answer.

One answer i got is because the compiler chooses the older style before it chooses the newer style. But I am not convinced.

Edit: I know widening is preferrd than boxing and var-args. but WHY is my question. of which i know one. any other reasons.


Yes, the compiler "chooses the older style over the newer style", because of compatibility requirements. Imagine some code, written before Java 5 came out, that suddenly had a change of behaviour when compiled under Java 5! That would be bad.

Widening conversions have been around since the dawn of Java, but autoboxing and varargs are new to Java 5.


Here is an example of it:

class Widen {

    private static void widen(long k) {
        System.out.println("Converted to long: " + k);
    }

    private static void widen(int ... k) {
        System.out.println("Converted to varargs: " + k);
    }

    private static void widen(Integer k) {
        System.out.println("Converted to Integer: " + k);
    }

    public static void main(String ... args) {
        int value = 3;
        widen(value);  // Output: Converted to long: 3
    }
}    

So all this means is that it will widen before autoboxing and using varargs. If we took out the method of widen with the long parameter, it would have chosen the autoboxing before the varargs.


The compiler has to keep compatibility with previous versions of Java. On top of that the compiler chooses the most performant / smallest change to the argument. Promoting to another primitive beats creating wrapper object and that beats creating an array with regards to memory usage and performance.


widening beats boxing, boxing beats generics, generics beat varargs


The reason that widening performs better is because it is a simple operation to sign extend, a single instruction for most CPUs. Boxing requires a heap allocation, and boxed objects are more expensive to access, requiring at least an additional memory access.

Even without the compatibility issue, it seems to me that you'd want the language to prefer the fastest overload first, as long as this behavior doesn't create any worse issues.


I don't know about you, but I'd much rather that the compiler passed my byte as an int than as a Byte. Consider the overhead. And varargs also requires boxing.

In other words, the reason is efficiency. The language design prefers the more efficient calling mechanism that does not require it to allocated a boxed item.

'Requires', you ask? The varargs functions expect to get an array of Object, and that can't include a primitive type.

Compatibility is not a bad reason, either.


class Widen {
    private static widen(long k) {
        System.out.println("Converted to long: " + k);
    }
    private static widen(int ... k) {
        System.out.println("Converted to varargs: " + k);
    }
    private static widen(Integer k) {
        System.out.println("Converted to Integer: " + k);
    }
    public static void main(String ... args) {
        int value = 3;
        widen(value);  // Output: Converted to long: 3
    }
} 

to solve above mind this:

widening beats boxing, boxing beats varargs

the out put will be Converted to long:3

0

精彩评论

暂无评论...
验证码 换一张
取 消