Why are protected variables not allowed by default in Checkstyle? - java

I get a lot of warnings in eclipse like these:
Variable 'myVariable' must be private and have accessor methods.
I think I get them because I didn't set protectedAllowed manually to true in eclipse. But why is it set to false by default? Shouldn't I use protected attributes?

Theoretically, protected attributes (variables) are an anti-pattern in object-oriented languages. If only subclasses need to access member attributes of its superclass, define the attributes themselves as private and create protected accessor methods (getter and setter). This approach applies the concept of 'information hiding'. There is an alternative solution: define protected immutable (final) member attributes.
Further readings:
Should you ever use protected member variables?
http://www.codinghorror.com/blog/2006/08/properties-vs-public-variables.html

I guess, making everything private is an anti-pattern. Often classes are used in a bunch and as a whole represent encapsulated entity placed in separate package. They do not need to hide something from each other, but this rule enforces hiding for no good reason, increasing clutter and effectively making style (as I understand it) worse. Meanwhile, we often see that every class in package is public. I guess this is much worse, but checkstyle doesn't check that.
Encapsulation exists not only on class level, put also on package, system and so on. And I think that these levels are even more important.

Allowing package access simplifies programming within a package, and reduces boilerplate code. Often times, access is only needed from within the package. Private access forces you to create a lot of nearly useless accessor methods. This actually has the effect of reducing encapsulation and information hiding because a class has to expose internal data/structure application wide instead of just package wide through public accessor methods. The default package visibility also makes testing easier because test classes live in the same package as well (in test dir/tree).

Related

How to make a member of a class to be accessible only in subclasses in any packages?

How to make a member of a class to be accessible only in subclasses in any packages? Protected is not a solution since it will open the member to other non subclasses classes.
Java does not provide absolute encapsulation. Some amount of discipline is required on the part of the programmer - both the original designer and anyone that uses a published API - to abide by some rules that are outside of the language. Regarding member access, you have identified one such case. What you want is not possible in Java.
Just to put this in broader perspective, I'd point out that even private members can be accessed by other classes if a programmer is willing to go far enough to do it. Calls made via JNI do not have to respect any of the access modifiers. See, e.g., Can a native method call a private method?
Other examples of out-of-language norms include the contract for equals/hashCode, which must be met for classes to behave well with respect to collections but is not enforced at the level of the language.
I understand why you want to do this; however, Java simply does not provide that capability.
You could do abstract class with protected member, and implement it in another packages. Consider you created some lib and design extensability for certain things. Later users of your lib will implement realizations of your class and has access to protected member and in same time not able to create implementation classes in your package. In example FilterReader class, it design for extensibility, after you implement it in somewhere in your code outside java.io package that protected fields and methods will be private to other classes in your package.
What you are trying to achieve ist not possible during to acces control:
https://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
You may rethink your software design, since yout problem is caused by architecture.
please be more specific in your question for getting further answer.
Solving your problem may cause sideeffects and is not in a OOD manner.
The only way to acces the private member is using an getter method with same visibilty issuses.

Java classes with very limited use, but not limited to one class. External or inner?

Say I have an abstract class AbstractBarrelComponent that extends the Component class. The class uses a class named Barrel for some imaginary purpose.
Where should my Barrel class reside, if the only classes that would/can/should ever use it are the AbstractBarrelComponent and its subclasses?
By "reside" I mean should the class be in its own file, Barrel.java, or should it be a package-protected class in AbstractBarrelComponent.java? Is there a common convention for this kind of situation?
Different programmers and organisations use different standards for this and I don't think there is one right answer. The important thing is to pick a standard and stick to it.
My personal standard is that inner classes are always private. If a subclass needs access to it then it either should be in a outer protected class or access to its methods should be made available via delegation. The only downside to this is that you end up with more small classes. But, frankly, modern clean coding style relies on good IDEs that make it easy to navigate around your code so the need to group classes for navigation has mostly gone away.
As an aside, I feel it's unfortunate that the designers of Java did not make a distinction between protected for access by subclasses and protected for access by all classes in the same namespace. These are really quite separate use cases. In your situation there's a tendancy to make it an inner protected classes rather than an outer protected classes to restrict access to subclasses. It would have been better if there was a separate keyword for these two uses.

Using abstract/super class for class's internal workings. Good practice wrt Access Modifiers

How do I change my mistakenly c#-ish design to work with sensible access protection in java?
Here is my super class
abstract class Parent {
protected parentVariable;
protected parentMethod() {
//These methods and variables contain internal workings of my sub-classes
//to avoid repetition
// I don't want classes elsewhere in the package (that don't inherit from class) to see these.
}
}
I have sub classes that have shared internal working, which I've stuck it in the super class. It's still hidden to the other classes and usable by sub classes. Wait, no: this isn't c#, this is java.
Protected(c#) != Protected(java) ≈≈ Internal(C#).
c# protected = Access is limited to the containing class or types derived from the containing class.
java protected = Access is limited to the current package
Everything in the package can see access these. That's far too permissive for these internal workings.
How do I solve this? Do I have to bring the shared code down to the sub-classes and use "private" at the cost of code repetition? Was my use of parent classes bad design in the first place? Do I have to squirrel these inheritance trees away in new packages?
There is no access modifier that allows visibility to subclasses but not to classes of the same package.
But that's not such a big problem because classes in a given package are supposed to be "friend", cooperate, and be released all at the same time.
Even if they see some fields and methods that they shouldn't use, the other classes of the package are not part of any external API that you have no control on, and the protected methods are not accessible to the external code.
So, just document that these methods and fields shouldn't be used so that you or your coworkers don't mistakenly use them. Or put this class in its own package if you're really concerned about same-package visibility.

What is the purpose of access modifiers?

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.)

How would i access Object properties an object method?

What is the "correct" way to access an object's properties from within an object method that is not a getter/setter method?
Getter/Setter is the recommended way of accessing properties of an object. Otherwise you to have to use public properties, but public properties are not recommended.
If a classes' properties don't have getters and they are not visible (e.g. not public), that means that the class is designed so that you can't access them. In that case, there is no proper way to access them.
Flipping this around, if you are designing a class and you intend that other classes can access its attributes, you ought to provide getters. You could alternatively declare the attributes to be public, protected or package private, but that makes your abstraction leaky and has a number of undesirable consequences.
If you are asking how one of an object's methods should access its own attributes, the simple answer is whichever way is most convenient. If the class has getters, you could call them. Alternatively, you could just access the attributes directly. The problems of leaky abstraction don't apply in this case because the method accessing the state is inside the abstraction boundary.
This is mostly a matter of preference.
I personally prefer not to use the getters and setters in my object. This increases readability, allows me to change my getters and settings to return copies (of lists mostly) without it changing my own object. If you do something special in your getter then you can make a helper method that is used by both your getter and your other functions. This will go wrong if your classes get too large though (so don't make large classes). I don't like how using a getter setter hides the side effects inside the object (unlike for external users, they should be hidden from any side effects inside the object), when you want to have the side effects, give the private method a clear name indiciting it has them.
First off I'll answer the question as is:
What is the "correct" way to access an object's properties from within an object method that is not a getter/setter method?
When you are within an object, you can reference the properties directly where the method is part of the object. For example:
public class testClass() {
public int x;
private someMethod() {
x = 4;
}
}
To answer the comment:
I think the question can be reformulated: Should I use getters and setters when implementing my object methods? Or should I access member variables directly?
You should always hide the internal data and other implementation details within a class as much as possible; seperating the API from the implementation (a.k.a encapsulation). Encapsulation decouples the modules thereby allowing them to be developed, tested and modified in isolation.
Generally, you should use the lowest access modifier possible (e.g. private, protected, package-private) whilst maintaining functionality for the application you're writing. The benefits of designing and devloping this way is that you can change implementation details without breaking code that uses the modules. If you make everything public, and other people are using your classes, you are forced to support it forever maintaining compatibility - or until they change their implementation that is using your modules.
Instance fields should never be public as you give up the ability to limit the values that can be stored in the field, and if it is a mutable object, you open your object up for misuse (see here). It is important to note too that classes with public mutable fields are not thread-safe. It is also important to note that instance fields that are declared public static final but are mutable objects can also be modified and can be a security risk.
Basically, in public classes - always use accessor methods, not public fields. It allows you to protect your mutable objects from modification outside of the class (be it intentionally or unintentionally) and allows you to change implementation detail later without harming your clients.

Categories