• Post Reply Bookmark Topic Watch Topic
  • New Topic

Object's scope in page including JSP

 
Adam Nagy
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
http://stackoverflow.com/questions/18448760/objects-scope-in-page-including-jsp
I'm working on a JSP project, and got a very interesting problem: I have a "main" jsp page, let's call it Adam.jsp . I will include another jsp page called AdamIn.jsp .

Adam.jsp:


AdamIn.jsp:


Than here is the output of Adam.jsp:

key before including: value
key after including: value

So it didn't change. BUT! If I'm setting one of my own class's object (let's call it AdamClass, which has one public String variable: xxx="adam") like this:
Adam.jsp:


AdamIn.jsp


Than the output of Adam.jsp will be this:

adam.xxx before including: adam
adam.xxx after including: changed!

So the question is: why has it changed with AdamClass object and not with a String?

P.S.: I also tried it with HashMap, and the same like AdamClass: it did change the HashMap's key-value pair.
 
Bear Bibeault
Author and ninkuma
Marshal
Posts: 65530
108
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In the first example, you create a String reference to the session "attribute" (properly called a scoped variable). Then you replace the value pointed to by the reference. That doesn't do anything to change what's in the session -- only what's referenced to by the scripting variable. This is basic Java. The fact that the Java is in a JSP doesn't change the rules.

By the way, you do know that Java in a JSP has been obsolete for 12 years, right? And this is just test code? Java code should never be placed in a JSP. You should be using the JSTL and EL in real code.

In the second example, you obtain a reference to the scoped variable, in this case an object with properties, then change a property of the scoped variable. So of course, the value of the property is changed.

The big difference between the two is that in the first example you are replacing the obejct referenced by the scripting variable with a new one, but in the second example you are not.

It's all rather moot as code like this should never be used in modern JSP.
 
Adam Nagy
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
First of all, thanks for your answer!
Probably I don't understand properly your reply, so I am going to give another example:
Main.jsp:

Included.jsp:

And the output HTML is:


So the changed variables are the instances of the HashMap and the AdamClass, not the Integer's or String's. Why is this happening?
What I don't understand: why do I get (probably) only a reference for the variable, if I'm getting a HashMap or my own class using the session.getAttribute(..) function? And why is this not happening with String and Integer?
 
Ravi Khadgi
Greenhorn
Posts: 20
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's because String objects are immutable. You can try running following code snippet.

And the output would be:

key before : value
key after : value
adam.xxx before : originalAdam
adam.xxx after : changedAdam
 
Bear Bibeault
Author and ninkuma
Marshal
Posts: 65530
108
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
No, it has nothing at all to do with String immutability. It has to do with when objects are created and how references are handled. The first example could use any class and the result would be the same.

Once again in the longer (which I didn't look at closely) you are replacing the objects with new one, while in the second you are not creating new objects but changing the properties of the existing object.

Taking this out of JSP (again, Java code in a JSP is huge no-no), the same behavior would be observed calling Java methods.
 
Bear Bibeault
Author and ninkuma
Marshal
Posts: 65530
108
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Let's take this out of the realm of JSP -- which is just adding a lot of complexity to the issue -- and bring into normal Java. The situation you describe is exactly the same as this class:

First, look at the code without running it. What do you expect lines 14 and 15 to print?

Now run it. Were you right?

If not, how did you go wrong?
 
Adam Nagy
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My thought are now: (before running it, and I'm pretty sure, I'm wrong :) ):
14: Adam
15: 0

And I ran it, and I was wrong at line 15. It's 1 :) This is apparently my problem. Could you explain me, why is this happening?
 
Bear Bibeault
Author and ninkuma
Marshal
Posts: 65530
108
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Look at lines 20 and 21. There's a distinct difference between them.

On line 20, the local reference to aString is replaced with a new object; the string "Bear". This reference is in the scope of the doSomething() method and has nothing whatsoever to do with the version of aString in the main() method. So why would line 20 have any effect whatsoever on the main() method. It can't.

Now look at line 21. It adds an item to the existing List object pointed to by aList in doSomething(). This object is the same List object that's referenced by aList in main. We didn't replace the List object with a new List object, the way that did with the string.

So when line 21 adds an item to the List, it's adding it to the single List object that both versions of aList are referencing.

Let's rewrite the code using different parameter names. This doesn't change what happens one iota, but may make it clearer what's going on:
Here, at line 19, aString and p1 share a reference to the String object "Adam". But on line 20 we replace the value of p1 with a new object, string "Bear". It's much clearer that changing what object p1 points to has nothing at all to do with the main() method. All line 20 does is to create a new string object and assign it to the local variable p1. It has no effect on aString in main().

The p2 variable (and yes, parameters are variables) shares a reference to the List object with aList. We never do anything to change that. p2 and aList point to the same List. When we call .add(), it's called on the single List object that's been created in our program.

Consider this change:
Now, because we create a new List and replace p2 with its reference, the List acts like the String, and the original list in main() is undisturbed.
 
Ravi Khadgi
Greenhorn
Posts: 20
Java
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Bear Bibeault wrote:No, it has nothing at all to do with String immutability. It has to do with when objects are created and how references are handled. The first example could use any class and the result would be the same.

Once again in the longer (which I didn't look at closely) you are replacing the objects with new one, while in the second you are not creating new objects but changing the properties of the existing object.

Taking this out of JSP (again, Java code in a JSP is huge no-no), the same behavior would be observed calling Java methods.


Agree with you. However, being an immutable class, String objects are created and handled differently than other mutable objects. Same is true with the primitive wrapper classes.

If you do String oneString = anotherString , it would create a new object referenced by oneString variable. As a result, changing object referred by variable anotherString would not make any impact on the object referred by variable oneString.

However, if you do AdamClass oneAdam = anotherAdam , it would not create a new AdamClass object. Rather, variable oneAdam would refer to the object referred by anotherAdam variable. Hence, if you make change to the property of the object using one variable and look up for the same property using another variable, the change would be visible.
 
Bear Bibeault
Author and ninkuma
Marshal
Posts: 65530
108
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ravi Khadgi wrote:
Bear Bibeault wrote:No, it has nothing at all to do with String immutability.


Agree with you. However, being an immutable class, String objects are created and handled differently than other mutable objects.

Only in that it easy to create new strings via literals rather than using the new operator. Other than that, the immutability has little to do with this question, and strings are handled just like any other object.

If you do String oneString = anotherString , it would create a new object referenced by oneString variable.

Absolutely incorrect. oneString will have a reference to the exact same object that anotherString references. A new object will not be created.

if you do AdamClass oneAdam = anotherAdam , it would not create a new AdamClass object.

This is true. It is also true of strings. String objects are not handled any differently in this respect.

 
Adam Nagy
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks all of you for the replys, I've made a post to my blog, if you have time, please read it, and if something's wrong, reply to this message!
Thanks again for both of you!
Here is the link for the blog:
http://nagyadam2092.blogspot.hu/
 
Ivan Jozsef Balazs
Rancher
Posts: 992
5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Adam Nagy wrote:
Here is the link for the blog:
http://nagyadam2092.blogspot.hu/


Now in the blog you write:

Basically every time you are making expression's like this:

blabla = "blabla";
x = 10;

every time a new object is created. So it's like you are using the new String(".."); expression, but it's not showed.
So when you're about to pass a String or an Integer object to a function , you could get the value of it,
but if you want to change it, it will be not changed, because the "=" expression is making a new object.


x = 10; has no business with creating a new Object.
It is not like using the new String(".."); expression.

There is a distinction between a variable (containing a primitive value or a reference) and the object itself.

When a method is called, the arguments (either primitive values or object references) are copied onto the stack.

If you reassign an argument variable, you reassign this value (the copy) not the original.
"blabla" as a compile time constant got into the string pool, so executing

does not make a new object.

 
Bear Bibeault
Author and ninkuma
Marshal
Posts: 65530
108
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ivan Jozsef Balazs wrote: got into the string pool, so executing

does not make a new object.


Only because of the existence of the string pool. For the purposes of illustrating the concept from the original question the string pool has been ignored as an unnecessary distraction. It acts like it is creating a new object from the viewpoint that the original reference of blabla is replaced with a reference to a different object (whether that object is newly created or comes from the string pool is irrelevant to the point).

Primitives, of course, are an entirely different ballgame as they are not objects.
 
Ivan Jozsef Balazs
Rancher
Posts: 992
5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Basically every time you are making expression's like this:

blabla = "blabla";
x = 10;

every time a new object is created.



This is simply false and I was not willing to let it stand.
 
Bear Bibeault
Author and ninkuma
Marshal
Posts: 65530
108
IntelliJ IDE Java jQuery Mac Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ivan Jozsef Balazs wrote:
Basically every time you are making expression's like this:

blabla = "blabla";
x = 10;

every time a new object is created.

This is simply false and I was not willing to let it stand.


Understood. I haven't read the blog post (nor am I likely to), but yes, that's false.

To the OP, what's true to say about the statements:
The first replaces the blabla variable with a reference to a different object than it had before (except for the case where you are assigning the exact same value, but that'd be a silly thing to do), and the second probably doesn't involve objects at all (unless x is defined as an Integer, and then auto-boxing takes over).

But to brush aside the forest and see the trees, are you understanding the concepts behind the original question?
 
Adam Nagy
Greenhorn
Posts: 5
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, thanks all of you, especially you, Bear! ;)
The problem was very basic JAVA, but people with years behind them with JAVA were wrong, so thanks again!
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!