Is there a way in Java to express that an attribute x of an object o can be accessed (I mean by dot notation o.x) only by o itself? To be clear: I'm talking about object-level access as in Smalltalk, not class-level access (thus private is not private enough)?
I'm sorry - I'm sure this has been asked many times before, but I seem to pick the wrong keywords when searching.
It is not possible in Java (nothing is more private than the fields marked as "private"), but if you think about it, it is also logical: you can modify private fields of other objects only in the common class source code, and if you control the class source code, you could do any bad or good things anyway.
BTW, you can access even private variables of other classes via reflection, if there is no security manager installed, or the policy of the security manager allows it, see this: Why is it allowed to access Java private fields via reflection?
What you want to do is not possible. Every object has its own set of instance variables and can be accessed through that object only as long as they aren't static. So in short, if you want an attribute of Java object accessible by that object only, keep that object alive :).
Related
I know this applies to many languages, and not just Java, but that is the language I'm most familiar with.
I understand what the modifiers do, and how to use them. I just want to know, why do we need them? Why can't every object be accessible, whether or not it needs to be?
The reason becomes more apparent when you have to maintain a larger project. When a method or variable is public, you have to be careful when you make changes to it, because you never know which parts of the codebase rely on its exact behavior.
But when a variable or method is private, you know that it is not used outside of the class. That means there is a lot less code you have to pay attention to when you make changes.
By making class features private and public, you clearly separate the interface to the outside world from the internals. The less you exposes to the outside world, the more freedom you have with what the internal implementation does.
When you, for example, always make variables private and accessed them through getters and setters, you can later change them from a variable to a computed value, and then even later add caching to the computation for performance reasons. When it would be a public variable, you would have to change code everywhere the variable is used. But when you expose it to the outside world through getters and setters, all other code can keep using the class as if nothing had changed.
Making fields and methods private keeps other classes from improperly depending on the specific details of how a class works. The public interface (and the best case of all, an actual interface) describes how client code should interact with a library based on the semantics of the work being done. The implementer is then free to use whatever appropriate techniques to implement that interface and can make significant behind-the-scenes changes knowing that the client code will keep working.
An everyday example is the Collections group of interfaces. Most of the time, it's not important logically for code to know what particular kind of Set is in use, just that it's a collection that supports certain operations and doesn't have duplicates. This means that a method that accepts a Set<Integer> will work with any Set, including HashSet and ImmutableSet, because the person who wrote the interface wasn't poking around in the implementation's internals.
An example where this breaks down is the unfortunate tendency of some programmers to use packages in the com.sun namespace, especially when using cryptography. Upgrading to a new version of the JRE routinely breaks this code, which would have worked fine if the programmer had used the proper javax.crypto interfaces and factory methods instead of poking around in the JVM internals.
More or less they are used to control who can access your member variables and functions. It's the broader concept of encapsulation at work in Java(http://en.wikipedia.org/wiki/Encapsulation_(object-oriented_programming)).
From the Oracle Docs:
Access level modifiers determine whether other classes can use a
particular field or invoke a particular method. There are two levels
of access control:
At the top level—public, or package-private (no explicit modifier).
At the member level—public, private, protected, or package-private (no
explicit modifier).
http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
As to why you should do this:
It has to do with intent of use. It would probably be best described as a design choice that helps guide usage through-out the code-base. By marking something private you are telling other developers that this field or method should not be used outside it's current purpose. It really becomes important on large projects that shuffle developers over time. It helps communicate the purpose & intended uses of classes.
To avoid other classes having direct access to internal members of the class.
This is most useful for avoiding that member variables are mutated in an uncontrolled way (e.g. without proper validation, without notifying listeners, ...).
Another reason to avoid this is that the internal implementation may change at any time but you don't want to break code that uses it.
As others have noted, the concept is called Encapsulation.
Access modifiers are there to set access levels for classes, variables, methods and constructors. This provides an individual with the chance of controlling better the privacy of the application. There are 4 access modifiers.
Modifier | Class | Package | Subclass | World
no modifier:--|----yes----|------yes--------|--------no--------|-----no----|
private:-------|----yes----|-------no--------|--------no--------|-----no----|
public:--------|----yes----|------yes--------|-------yes-------|----yes----|
protected:---|----yes----|------yes--------|-------yes-------|-----no-----|
Regarding your question, we do need and use access modifiers because we need to restrict whom can call our program and in what way.
Also, when it comes to variables if you make something public, that means that I have direct access to it. Therefore, I am allowed to do whatever I want without following your guidelines through your methods.
For example:
public int maxUsers;
public void setMaxUsers(int users) throws IllegalArgumentException{
if(users > 0 && users <= 1000){
maxUsers = users;
}else{
throw new IllegalArgumentException("The users can not be less than 0 or greater than 1000")"
}
}
Imagine your whole program being based on its maxUsers. Since, you give me the right to access that variable directly, I could do this: maxUsers = -15; and not use the setMaxUsers method, which will simply make your program behave in an abnormal way (in the best case).
Explanations
A private member is only accessible within the same class as it is declared.
A member with no access modifier is only accessible within classes in the same package.
or
If a variable is set to protected inside a Class, it will be accessible from its sub classes defined in the same classes or different package only via Inheritance.
A protected member is accessible within all classes in the same package and within subclasses in other packages.
A public member is accessible to all classes (unless it resides in a module that does not export the package it is declared in
Here's a better version of the table. (Future proof with a column for modules.)
Let's say I have a separate GUI class that has a public boolean called "guiWait" and also has a boolean method that returns guiWait.
What's the difference between:
while(gui.guiWait)...
and
while(gui.getGuiWait())...
The difference is visibility. When you make guiWait public to be used like the first example, outside callers can modify the value. If you use a method and make the variable private, callers cannot modify the guiWait variable (although they can modify the object it references if it's mutable). Furthermore, if you make a habit of using getters and setters, then later on if you need to add logic to the getting or setting process (such as you need to make the value derived from some other new field), you already have the methods and won't break any caller's code by making the variable private. So it's considered "best practice" to always use getters and setters in Java.
If guiWait is a public boolean, there is no point in having a "getter" method for it. If it were private or protected, then it'd be a different story. The private-getter method is more flexible because you can change the implementation of the "getting" of that variable, and add checks or whatever inside the method. Private getters/setters also make things clearer and establish which things should be seen by other classes and which are only meant to be used inside a single class they are apart of. If you find you do need a getter for a specific member variable (need some kind of verification or checking), which is very common, then it would be inconsistent to do it just for that variable.
The core concept of OOP is encapsulation. The getter and setter methods (eg. your getguiWait() method) are used so that nobody is able to access the internal fields of an object. This way no one else is able to set the internal fields to an inconsistent/abnormal value. By using the "getter" and "setter" methods (and hiding the inner fields by using private), you ensure that anyone willing to set or get a field will have to go through the checks that you have put up. Example Class Cat can have age as its field. In the setter method you would check that the user input value is not negative. If you allow the age field to be public, someone could potentially set it to negative which would make no sense.
Its the pure concept of Data Encapsulation in JAVA.
A language mechanism for restricting access to some of the object's components.
A language construct that facilitates the bundling of data with the methods (or other functions) operating on that data.
http://www.tutorialspoint.com/java/java_encapsulation.htm
I am building an API for my application as a middle layer between model and the controller.
The model contains all data and low-level function. I have created a new class for API which uses the model but makes things easier for the user and does not let the user to access the data directly.
Now, I would like to prevent the user from accessing the model and let him to use only the functions from API.
How do I do that?
As far as I believe, this can be simply done by specifying whether the method or variable is private or public. The problem is that I have many static fields for global data. Can I restrict access to static fields so that only private functions of API can access them?
Creating a private static field in a class will ensure that ONLY functions in that class will have access to those fields. Also, if the class is re-instantiated (aka new myClass();), those fields will not be recreated; their values will remain intact and global to all instances of myClass.
In addition to the already posted answer:
It depends on what you mean by "restrict access to static fields":
If you want to prevent others from using them directly inadvertently, use the "private" modifier.
But remember that one can still access them via reflection if no other countermeasures have bin put into place.
This holds true also for the "static int foo" case if you don't seal the package since one can easily put another class into the same package which will have access again.
If you are building an API, maybe you want to read the book Practical API Design, Confessions of a Java Framework Architect.
A Method Is Better Than a Field It's better to use methods —typically getters and setters— to access fields than to expose them directly.
A Factory Is Better Than a Constructor You facilitate an API's future evolution when you expose a factory method rather than a constructor.
Make Everything Final For the sake of future evolution, it's better to disallow subclassing ... make your class final.
...
We have a getter method within a class.
Within the same JAR we want the variable to be accessible with the no-identifier access level, from the same package and subpackages.
Below the access levels from: http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
Our problem is, how do we stop someone from taking the compiled .JAR, creating a class with the same package namespace definition, and being able to access our variable through the getter?
We thought about getting rid of all getters for the specific variable, and giving the variable value to other classes with setters and constructors, when they pass a reference to themselves. Obviously, they will be final classes. This way all objects needing the variable value have their own private copy.
I'm wondering though if there is a better way?
Access control modifiers (public, private, protected) are not meant as a security tool, but as an OO design tool. They're used to implement OO patterns like encapsulation, inheritance.
Even with no getter whatsoever and a private variable, any Java developer can use reflection to access the variable.
If you want to keep something secret, don't ever put it in a variable of a program executed by anyone. Keep it on your own machines.
- Reflection seems to be the evil here, using which any variable even with private access modifier can be accessed.
- Four access controls like private, default, protected, and public are introduced in Java more as a tool to support the Core Object Oriented Concept like Inheritance, Encapsulation etc...
I have read from literature that a variable shouldn't be declared protected just so it could remain visible in the inheritance tree.
Why is so?
Fields are implementation details - they should not generally be regarded as part of the API - that way you get to change exactly how things are stored later on. If you make a field protected, it will be available to subclasses, rather than the subclass only getting to see an API which they can rely on.
What if you want to restrict which values are valid on that field at a later date? When it's protected, you don't get any validation or anything similar. Subclasses could put any old rubbish in there. If you keep it private and give a protected setter method, you can apply appropriate validation.
In short: regard your clients-through-subclassing as clients in much the same way as your clients-through-calling. Give them an API to work with, and keep your implementation details private.
Most of the times, when I create inheritance, I make sure that all variables are private. Whenever the inherited class wants to have something from the super class, he can get the values with the getter methods.
If everyone could get and set a variable in the hardcore way, there is no way to rely on extra code that should be run when you set that variable. The super class is giving away his own responsibilities.
Its the concept of Inheritance. If class A inherits from class B, then it has access to Protected variables and functions. so, if you don't want to give an access to any other class, then go ahead and declare it as Private.