Pergunta

I know the concept of String pool in PermGen area of heap. So when we do something like

String firstString = "Stack";
String secondString = "Stack";

both references firstString and secondString point to the same object in the pool. But I tried the same for a variable of type int.

    int firstInt = 5;
    int secondInt = 5;

    if(firstInt == secondInt) {
        System.out.println("Both point to same allocated memory");
    } else {
        System.out.println("Both point to different allocated memory");
    }

and the result is Both point to same object and when i tried

Integer firstInteger = new Integer(2);
Integer secondInteger = new Integer(2);

    if(firstInteger == secondInteger) {
        System.out.println("Both point to same object");
    } else {
        System.out.println("Both point to different object");
    }

output is Both point to different object

I tried the same for char and the result is similar. So my question do we have pools for all primitive types like int, char? And when we actually create objects with same content using new () as in the second case mentioned above is the object cloned and stored in same pool area or is it outside the pool?

Foi útil?

Solução

There is so much misconception in your post, it is hard even to start explaining. Get some decent book. For now, some facts that might help you:

  • String is not a primitive type,
  • there are no pools of primitive types, because there cannot be a reference to a primitive type (the answer saying that they are only kept on the stack is plain wrong!)
  • if you use new, you bypass pools anyway; so executing new String("ala") will always create a new String object; you cannot change the semantics of new;
  • if you want to use available pools, use factory methods on objects (like Integer.valueOf), they will - to some extent - pool instances (it is not viable or beneficial to pool all possible values of Integers, Floats etc.).

Outras dicas

Primitives are not objects. They can be stored directly in the generated code.

In your second code block, you're testing equality of value, not that two objects are the same.

int firstInt = 5;
int secondInt = 5;

if(firstInt == secondInt)
{
    System.out.println("Both point to same object");
    // NO - neither point to an object -- their alues are the same.
}

You can share the same Integer object among multiple references by explicitly using Integer.valueOf(int), which may return the same object for multiple calls.

If you try

if (Integer.valueOf(2) ==Integer.valueOf(2))

you will get true.

With the Integer firstInt = new Integer(2) you create a new local variable that is != to another local variable created with Integer secondInt = new Integer(2). Same goes for String type.

The reason behind this is that == checks equality of the variables. Variables could be different (== results in false) even though they point to two objects that are "the same". The same in this context means obj1.equals(obj2) returns true.

If you want object representation of primitve types and also StringS to be stored in PermGen then do not use new keyword, i.e. Integer firstInt = 2;, String firstString= "whatevs"; beacause the keyword new creates an object on the heap.

Sometimes, to answer advanced questions it is enough to look through source code. For instance, here is the code of Integer#valueOf(int i) method:

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

Values IntegerCache#low and IntegerCache#high could be changed via vm options:

The size of the cache may be controlled by the -XX:AutoBoxCacheMax=<size> option.

I believe this is a very valid question that needs to be answered. For any future readers, the way the == operation works for Object types and primitive types are different.

Primitive types(int, char, double, long....) are evaluated by their values. Whereas Primitive Wrappers (Integer, Double, String ....) are actually objects and not just values.

So when we use Integer class as

Integer number = new Integer(10)

A new Object is created in the memory which is not the case for primitive data types.

The == evaluation checks the memory, as well as the value for the Object types and for primitive types, checks the value only.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top