2

In Java, consider the declaration and initialization

Object obj = new Object();

In the process, we have created an object called Object in some memory location, and we bind the memory location to the variable obj.

Now consider the declaration and initialization of a primitive type in java:

int num1Java = 5;
int num2Java = num1Java;

We again bind each of them to the memory locations of 5; yes, I said memory locations because Java seems to treat primitive types differently, it creates another instance of 5 at another memory location and then binds num2Java to that new location containing the same information, namely 5. Am I right here?

Consider the similar code in Python, which prints out true:

num1Py = 5
num2Py = num1Py
print id(num1Py)==id(num2Py)

The lesson seems to be that in Python, "primitive types" like integers are treated as objects in Java sense, in other words, in python, we do not have the concept of "primitive type". Am I right?

I browsed a lot of web on related topics, but none seem to give a completely satisfactory answer. Help is greatly appreciated.

Kun
  • 186
  • 2
  • 12
  • Depends where those declarations are. – Savior Apr 12 '16 at 01:26
  • iirc there's no guarentee that primitive data like `5` only exists once in memory in python. There is only a guarantee that the value will be immutable. – flakes Apr 12 '16 at 01:50

3 Answers3

1

We again bind each of them to the memory locations of 5; yes, I said memory locations because Java seems to treat primitive types differently, it creates another instance of 5 at another memory location and then binds num2Java to that new location containing the same information, namely 5. Am I right here?

No. If these

int num1Java = 5;
int num2Java = num1Java;

are local variables, then they are on the stack. Each stack frame contains a local variable table, basically an array with an element for each variable (it's a little smarter than that).

An int value is represented with 4 bytes. So your local variable table would contain a region of 4 bytes reserved for your variable num1Java. When the following executed

int num1Java = 5;

four bytes representing the value 5 are pushed onto the stack, then copied into the local variable table at the offset that's attributed to num1Java. When you then do

int num2Java = num1Java;

the local variable table is read at the offset for num1Java and the corresponding bytes stored are pushed onto the stack. Those same bytes are then copied into the local variable table at the offset for num2Java.

If these were instance variables, then something similar happens, but instead of a local variable table, you have the object they belong to. Each field will have its own offset within the memory allocated for that object.

As for reference types, the same concepts apply for local variables and fields as described above, except the value stored in a variable is a reference (more or less the memory location) to the object. An in-depth explanation with quotes from the JLS can be found here.

Community
  • 1
  • 1
Savior
  • 3,225
  • 4
  • 24
  • 48
0

In Python you bind names to memory locations, never to other names, which explains the somewhat unexpected behavior you pointed out. The fact that id(num1)==id(num2) is a consequence of this rule. Now, since primitive types are immutable, you can write things as:

    num1 = 1
    num2 = num1
    num1 = num1 + 1
    print num1, num2
    1 2

However, if the name refers to a mutable object, you may be in trouble:

    lis1 = [1, 2, 3]
    lis2 = lis1
    lis1.append(4)
    print lis2
    [1, 2, 3, 4]

A good explanation can be found in this video.

Cyb3rFly3r
  • 1,321
  • 7
  • 12
  • Things like that are never properly introduced in introductory courses.. and the web always say different things on different sites. tricky to learn. Thanks! – Kun Apr 12 '16 at 02:01
0

Java is a pass-by-value language. Consider the following example.

public class Test {

    public static void main(String[] args) {
        String name = "Kun";
        printMe(name);

    }

    public void printMe(String message){
        System.out.println(message);
    }

}

When "name" is passed in as a string to the printMe method, a copy of what "name" is equal to is passed into the mthod.. The "message" string inside the printMe method is not related back to the "name" variable. So if you were to change the print me method to...

public void printMe(String message) {
    message = message + "Hello";
    System.out.println(message);
}

...then the value of "name" in the main method will remain unchanged.

Relating this back to your example of:

public static void main(String[]args){
    int num1Java = 5;
    int num2Java = num1Java;

    num1Java = 7;
}

"num1Java" and "num2Java" are two variables which point towards the same locations in memory which equal the same number, but after the "num1Java = 7" line is run, if you were to print out num2Java, it would be equal to 5 and now 7.

Here's another post with another explanation of the same concept

Community
  • 1
  • 1
James
  • 787
  • 1
  • 7
  • 15