0

Here is a piece of code:

@FunctionalInterface
interface NumericFunc<T>{
       int fact(T[] a,T b);
}
class MyStringOps{
       static <T> int counter(T[] a,T b){
              int count=0;
              for(int i=0;i<a.length;i++)
                     if (a[i]==b)
                           count++;
              return count;
       }
}

public class Numeric {

    static<T> void stringOp(NumericFunc<T> ref,T[] a,T b){
        System.out.println(ref.fact(a,b));
 } 
    public static void main(String[] args) {
        Integer ing[]={1,2,3,4,5,4,4,4,8};
        String str[]={"one","two","three","two","four"};
        stringOp(MyStringOps::<Integer>counter,ing,new Integer(4));
        stringOp(MyStringOps::<String>counter,str,new String("two"));

    }

}

Output for the following code is: 0 0

Here is the same code with a bit of difference:

@FunctionalInterface
interface NumericFunc<T>{
       int fact(T[] a,T b);
}
class MyStringOps{
       static <T> int counter(T[] a,T b){
              int count=0;
              for(int i=0;i<a.length;i++)
                     if (a[i]==b)
                           count++;
              return count;
       }
}

public class Numeric {

    static<T> void stringOp(NumericFunc<T> ref,T[] a,T b){
        System.out.println(ref.fact(a,b));
 } 
    public static void main(String[] args) {
        Integer ing[]={1,2,3,4,5,4,4,4,8};
        String str[]={"one","two","three","two","four"};
        //Deviation from the previous code.Instead of Wrapper classes
        //primitive type are used for argument to b.
        stringOp(MyStringOps::<Integer>counter,ing,4);
        stringOp(MyStringOps::<String>counter,str,"two");

    }

}

Output: 4 2

My question is that when we pass new Integer(4) as an argument, when NumericFunc is executed with implementation of counter or in lucid terms when counter is executed shouldn't new Integer(4) be unboxed to 4 and compared with the array and output for the both the code pieces should remain same.

    if(new Integer(4)==4)
        System.out.println(true);

For this piece Output is true. But if there is an array of type Integer which contains elements of primitive type i.e. int in this case(which according to me should be auto boxed to Integer type and then should be stored in array) and then if you compare it with a Wrapper type it returns false. For e.g. in the above code there is an array ing[] which contains 4 at 3rd index.

if(ing[3]==new Integer(4))
    System.out.println(true);
else
    System.out.println(false);

Output: false

In this case auto boxing or unboxing doesn't takes place.

Can anyone answer why this happens?

Sotirios Delimanolis
  • 274,122
  • 60
  • 696
  • 724
  • In all your examples, `==` is reference equality. There's no boxing or unboxing involved in that statement. Your issue is that `new Integer(..)` and `new String(..)` create new instances whereas `4` gets boxed to a cached value, the same as one that appears in your array, and the literal `"two"` also appears in your array. – Sotirios Delimanolis Aug 22 '17 at 20:14
  • System.out.println(new Integer(4)==4);returns true. Equality operator compares reference. So new Integer(4) is an object having some memory allocated in heap to which reference is returned while 4 is a literal. So how does references of these are equal? Even if literal 4 gets boxed to a cached value shouldn't its reference be different that of new Integer(4)? – SHREY MOHAN Aug 22 '17 at 21:17
  • In `new Integer(4)==4`, the `new Integer(4)` get unboxed to the `int` value 4 before the comparison. This example has nothing to do with your larger snippets. – Sotirios Delimanolis Aug 22 '17 at 21:23
  • One more thing, in an expression how it is decided that whether boxing will take place or unboxing ? For e.g. if one operand is literal and other is Wrapper and they both are compared using some relational operator then will the wrapper be unboxed or literal be boxed for comparison? – SHREY MOHAN Aug 22 '17 at 21:26
  • If one of the operands of `==` is of a primitive type, the other operand will be unboxed, and then the comparison will be made. In your `counter` method's use of `==`, it makes no difference where the values came from though. All that method knows is that it has values of type `T`. `==` can only ever be reference equality with values of type `T`. – Sotirios Delimanolis Aug 22 '17 at 21:29

0 Answers0