4
import java.util.Stack;

public class StackIntro {
    public static void main(String[] args){
        Stack clapper = new Stack();

        for( int i=0; i<11; i++){
            clapper.push(i);
        }

        while(!clapper.isEmpty()){
            System.out.print ( clapper.pop() );     //FILO
            System.out.print ( ',' );
            if(clapper.size()==1){
                System.out.print(clapper.pop());    //FILO
                System.out.println("...");
            }
        }
        System.out.println("Lift-off.");
        clapper.removeAllElements();
    }
}

So basically I just wanted to see how numbers go in and out of a stack. The FILO comment shows this. I was told that I should actually change line 8 :

clapper.push(i); //previous

clapper.push(new Integer(i)); //new

I don't understand what this would accomplish, or the difference between the two.

  • 2
    Have you ever heard about `Autoboxing`? – user2004685 Oct 18 '16 at 19:44
  • @user2004685 What is that? – Chuck B Ihekwaba Oct 18 '16 at 19:45
  • @ChuckBIhekwaba As you have asked, here is a great answer on the topic: *http://stackoverflow.com/questions/27647407/why-do-we-use-autoboxing-and-unboxing-in-java* – user2004685 Oct 18 '16 at 19:49
  • 2
    the better advice would have been to use `Integer.valueOf(i)` which may save some memory when numbers get repeated. This is not the case in your example, but can happen IRL. – Timothy Truckle Oct 18 '16 at 19:50
  • 1
    The only slight difference is that `new Integer(i)` always creates a new Integer, whereas the autoboxed approach compiles to `Integer.valueOf(i)`, which caches values at least the values in [-128, 127]. – yshavit Oct 18 '16 at 19:55

2 Answers2

5

Although due to autoboxing both lines of code result in an Integer object with value 1 being pushed on the stack, the two lines do not have exctly the same effect.

Autoboxing uses the Integer cache, which is required by the JLS for values from -128 to 127, such that the resulting Integer instance is the same instance for any value in that range.

However, invoking the int constructor creates a new Integer instance every time it's called.

Consider:

Integer a = 1; // autoboxing
Integer b = 1; // autoboxing
System.out.println(a == b); // true
Integer c = new Integer(1);
Integer d = new Integer(1);
System.out.println(c == d); // false

This distinction may cause different behaviour in your program if you use == (object identity) when comparing values pushed and popped to/from the stack instead of equals().

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • 1
    You are technically right, but your answer ends up also being problematic, quite possibly more problematic than my answer: if he uses object identity when comparing values, he is going to run into serious trouble as soon as he uses a value outside of the cached range. So, the right answer is that there is a slight difference which will only be noticed if he makes the mistake of using object identity equality comparisons. I can delete my answer and you can fix yours, or you can delete yours and I can fix mine, I leave it up to you. – Mike Nakis Oct 18 '16 at 20:11
  • 1
    @Mike the question is not about what's "right" or "better". It was about "what is the *difference*". Both answers have value to readers btw. – Bohemian Oct 18 '16 at 20:15
  • Yes, and that's why as I said you are technically correct. You pinpointed the difference, which I forgot. But at the same time you are *possibly* exposing the OP to a world of pain. – Mike Nakis Oct 18 '16 at 20:16
  • 1
    OK, I agree both answers are useful, especially if read together with the comments. I am not going to do anything. – Mike Nakis Oct 18 '16 at 20:18
4

This would not accomplish much, very possibly not anything at all.

The idea is that clapper.push(T) accepts an object, but i is not an object, it is a primitive, so the compiler will automatically box it into an Integer object before passing it to clapper.push().

Auto-boxing was not a feature of java from the beginning, so there may still exist some old-timers who are uncomfortable with it. But that should be entirely their own problem. Java has come a long way since then. Auto-boxing is taken for granted, we do not even give it any thought anymore.

Passing i and having the compiler auto-box it is exactly the same as as passing new Integer(i).

Mike Nakis
  • 56,297
  • 11
  • 110
  • 142
  • 1
    Actually, this answer is wrong, especially the last sentence. Yes it autoboxes, but **no** the two lines are **not** "exactly the same" - see [here](http://stackoverflow.com/a/40117000/256196) – Bohemian Oct 18 '16 at 20:00
  • @Bohemian you are right, but see my comment on your answer. – Mike Nakis Oct 18 '16 at 20:12