• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Can we modify a private variable outside a class?

 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If a private string array is defined in the class. A getter method is defined. Outside the class we can change the elements of the string.

public class Person{
private String name[];
public Person(){
name=new String[2];
name[0]="First";
name[1]="Last";
}
public String[] getName(){
return name;
}
}
class Demo{
public static void main(String args[]){
Person p =new Person();
String name[];
name=p.getName();
name[0]="Srilatha";
name[1]="Reddy"
System.out.println(p.getName()[0]+" "+p.getName()[1]);
//The above prints Srilatha Reddy
}
}
Is this not a violation? How can we stop this?
 
Ranch Hand
Posts: 31
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Declaring a class member private prevents the member to be accessed directly
outside the declaring class.
 
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
It gives compilation error.
 
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Srilatha:

In this example, you are NOT modifying the private "name" variable, in your main method you are declaring a new variable "name", this is a local variable and it has no notice about other variable "name" exists (because it is private), so you are modifying the local "name" variable, but, how you can modify the private "name" variable's value? I think it's because there is a String pool, so, if you already have a String in the pool, and you intent to create a new instance variable of that String, the JVM don't create a new String, it just make your new variable to reference to the existing String, in addition, remember that arrays aren't simple variables, they are objects, so you have two variables refering to the same object, the access modifiers just apply to the modified variable or method.

I hope this will help you to understand your output, if I'm wrong, please correct me.

Thanks,

Alejandro Galvan
 
Alejandro Galvan
Ranch Hand
Posts: 48
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Also you can check it without an array. You'll see how it works normally. So, be careful when you are using instance variables inside other objects, or you will have a security problem.

Thanks,

Alejandro Galvan
 
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi Srilatha,
Nice find. I couldnt understand either. I got the same result. I could modify the private String array name defined in Person from Demo...

Alejandro, you said " if you already have a String in the pool, and you intent to create a new instance variable of that String, the JVM don't create a new String, it just make your new variable to reference to the existing String".
But it is the case only when we try to initialize the another String instance variable with same value as existing one.
like this:
String s1 = "Hello";
String s2 = "Hello";

In this case, JVM doesnt create a new string object but returns reference to existing s1.

In Srilatha's example, she initialized with different values.

Still, it doesnt answer how come you are able to modify a "private" string array from another class???
[ January 02, 2008: Message edited by: srinadh penugonda ]
 
srinadh penugonda
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
One more interesting thing is if I define private int in Person and try to do the same as name, it doesnt behave the same way - "works as expected".
class Person {
private int i;

public int getNum() {
return i;
}

public Person() {
i = 9;
}
}

public class Demo{
public static void main(String[] args) {
Person p= new Person();
int j = p.getNum();
j = 0;
System.out.println(p.getNum());
}
}

It gives 9 as expected.

May be in the case of String[], we got reference and we can make merry out of it.
[ January 02, 2008: Message edited by: srinadh penugonda ]
 
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Still, it doesnt answer how come you are able to modify a "private" string array from another class???



I think you need to understand the distinction between a reference and a instance. The reference is private and can't be accessed outside of the class. It doesn't mean that the instance that the reference is referring to is private to the class -- it can reference an instance that is shared with other references.

Henry
 
Henry Wong
author
Posts: 23951
142
jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

One more interesting thing is if I define private int in Person and try to do the same as name, it doesnt behave the same way - "works as expected".



The string array versions "works as expected" too -- just not what you expected...

Seriously, change the string array example to point to a different array -- you will see that the private class is still pointing to the original array.

Henry
 
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi:

Yes, you�re right Srinadh, I was wrong in that, but, as I said and henry confirmed, in this case you have two distincts reference variables to the same array, I also said that the access modifier "private" just work in the private "name" on Person class, but in Demo class. Remember that arrays are objects, they don�t behave in the same way as primitives. Also, as Henry confirmed, if we try the same with a primitive variable, it works as expected.

Thanks,

Alejandro
 
srinadh penugonda
Greenhorn
Posts: 13
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks Henry. That was really helpful.

So how do I avoid the name array being changed by classes outside to my Person class?

One option could be create private String instance members; and no one can change them outside of the Person class. But I guess this is what can be called a lousy solution..
 
Srilatha Reddy
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks everyone!

Another solution could be copy the private array in local String array variable and return the local variable

public String[] getName(){
String n[] =new String[2];
n[0]=name[0];
n[1]=name[1];
return n;
}
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic