From this post onwards, I will spend few days in sharing some little known (if not unknown) features of java language, which we either don’t knew before or didn’t care to think differently. I will really appreciate if all you guys participate in discussion with your thoughts. And for being updated about next discussion point in this series, I will suggest to subscribe through email. You will not be disappointed.
We all know about access modifiers in java. They are four public, protected, default and private. You can read more about them in official java docs.
This official doc and most of reference variables talk about using these access modifiers for controlling the access level “when used in some other class”. Most of us misinterpret this information wrongly, and start thinking in terms of instances of separate class.
Remember, access control is compile time feature and checked when you compile your program. It is applied at class level and not at instance level.
To establish this fact, let’s create two instances of a class and try to access the private members of each other.
package com.howtodoinjava.demo; public class AccessControlDemo { //Private member variable private String privateMemberVariable = null; //Private member method private String privateMethod(){ return privateMemberVariable; } public AccessControlDemo(String str) { privateMemberVariable = str; } public void demoAccessOtherClass(AccessControlDemo otherInstance) { //Access private members of second instance System.out.println("Private member variable :" + otherInstance.privateMemberVariable); System.out.println("Private member method :" + otherInstance.privateMethod()); } public static void main(String[] args) { AccessControlDemo firstInstance = new AccessControlDemo("first instance"); AccessControlDemo secondInstance = new AccessControlDemo("second instance"); firstInstance.demoAccessOtherClass(secondInstance); } } Output: Private member variable :second instance Private member method :second instance
As you can see, we are able to access the private members of another instance from same class.
Happy Learning !!
I just was wondering why overriding the “equals” method of a class I could access the private instance variables of the compared Object from “this” class without using getters. Had to google it and arrived to this page that explain it! Thank you!
Lokesh , Then we can say that there may be security problem arrives in this scenario and if yes, then how to overcome?
good one
Can be done if you write the main method in another class as well, even ur variables are private methods are public and can be done from any where.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author HARSHIT
*/
class AccessControlDemo {
//Private member variable
private String privateMemberVariable = null;
//Private member method
private String privateMethod() {
return privateMemberVariable;
}
public AccessControlDemo(String str) {
privateMemberVariable = str;
}
public void demoAccessOtherClass(AccessControlDemo otherInstance) {
//Access private members of second instance
System.out.println(“Private member variable :” + otherInstance.privateMemberVariable);
System.out.println(“Private member method :” + otherInstance.privateMethod());
}
}
class Access {
public static void main(String[] args) {
AccessControlDemo firstInstance = new AccessControlDemo(“first instance”);
AccessControlDemo secondInstance = new AccessControlDemo(“second instance”);
firstInstance.demoAccessOtherClass(secondInstance);
}
}
This way it can be accessed. But it cannot be this waySanath firstInstance.privateMenberVariable;
Hi Lokesh, I don’t see any strange behavior here. You are just invoking the method and accessing the private variable from Object instance.You can do that in any class irrespective of whether that class is of the same type as the Object ( on which you are invoking private methods) or not, nothing fancy here.
I am pretty sure that even you must have known this minor thing before, but if someone ask you to explain “Access control is compile time feature and checked when you compile your program. It is applied at class level and not at instance level.”, you would have struggled… 🙂
awesome stuff.
Interesting..
Is this concept being used anywhere in some libraries?
Very good observation
i think what JVM did here was, it checked the type of argument of method “demoAccessOtherClass” which is “AccessControlDemo” and since it is the same type as the class in which the method is being written and also the private variable “privateMemberVariable” is written in the same class so it allowed the access of private variable in this method. In a way it’s behaving in the same way as if accessing the member variable in a member function.
I am using .(dot) operator in a method parameter. JVM cannot be just so innocent. 🙂
Interesting observation!
great sharing…It is applied at class level and not at instance level……If we will pass some different reference(the reference to other class instance ) to the following method instead of “AccessControlDemo”
public void demoAccessOtherClass(AccessControlDemo otherInstance)
Then we will not be able to access the “privateMemberVariable” using “otherInstance.privateMemberVariable” inside this method.
Correct.
I like this–Remember, access control is compile time feature and checked when you compile your program. It is applied at class level and not at instance level.
but from where you got refrenced, because in java API , I have not seen this.
this could be a good concept.
“Compile time feature”: because it is checked at compile time.
“At class level”: Read linked java docs carefully. You will understand.
HI,
Private acsees variable says that-Methods, Variables and Constructors that are declared private can only be accessed within the declared class itself.
In your exapmle — it accessing the method and variable in same class.
You can access the private varibale by–
1- Variables that are declared private can be accessed outside the class if public getter methods are present in the class
2- By using reflextion API..
Yes, I am accessing private members in same class, but from another instance passed as parameter. I created two instances, and I am able to access the private members of second instance, inside first instance. That’s whole discussion.
Regarding, getter/ setters and reflextion, they are well known techniques.
What is new in this concept…..
I never said it is new. I said it’s little known (maybe you knew it already).. 🙂
Hi Lokesh, I am not sure why you termed it as little known. Don’t we do this sometime when we write equals method? using accessor method is the right way to do this even in equals method.