Saturday, May 30, 2009

Choosing a suitable access control modifier in Java


How to choose a suitable access control specifier of a method or a field?

Access Control Modifiers available for classes and members in Java

Top-level classes in Java can have only two access control modifiers - public and default (package-private) whereas the members have four access control modifiers - public, protected, default (package-private), and private. Nested Classes are treated as members of the top-level classes so all four access control modifiers are applicable to them.

Choosing suitable access control modifier for methods in Java?

Here I'm assuming that your top-level (i.e., a class which is not nested) class is 'public' as otherwise if it's having the default access control modifier then you would probably never make any member public or protected owning to the fact the class itself can't be used outside the package.

When to pick 'public' as the access control modifier?

How do you normally go about choosing the access specifier/modifier of a method in your class definition - whether you start from 'public' and move on to 'private' to see which specifier would actually suit the requirements or do you go about the other way round? It probably makes more sense to go the other way - starting from 'private' and moving onto 'public'. There should be a very strong reason why you would need a method to make 'public' as it would then become a part of the public interface of the class - a commitment from the class designer to all (those who are already consuming or those who would be consuming in future).

Therefore, choosing 'public' as the access specifier should be given a thorough review as consumers of the class can (which they normally do) use them in their implementation and hence once you make something public you got to support that for the consumers of your class till eternity (making a 'public' member deprecated and subsequently getting rid of it will be a difficult and time consuming exercise). A big ask especially in a professional environment where your class is being consumed by many critical applications. So as a thumb rule make only those members 'public', which you can't make either 'private', 'package-private (default)' or 'protected'.

When to pick 'protected' as the access control specifier?

A 'protected' modifier specifies that the member can be accessed from within the same package as well as by a sub-class in some other package.

Let's pick the suitable access modifier for a member which you want any of your sub-classes to have access to. Of course you can't choose 'private' here as the access will then be limited to your class only. Next up the ladder is 'package-private (default)' which will restrict the access limited to all the classes (either a sub class or not) in the same package only. But, if you want any sub class of your class to access the member then the default access modifier won't do it for you. Next up the ladder is 'protected' which suits fine here so no need to go further up. Quite simple to pick the suitable access modifier, isn't it?


Making something 'protected' also puts you in some sort of commitment in case you are not making your class as 'final' as otherwise the sub-classes of your class may write their implementation based on the availability of your 'protected' member. You have to be careful with the fact that the 'protected' members can be used by any class in the same package, so even if you have made your class as 'final' the commitment to make the 'protected' members available to all the classes in the same package still remains.
But, why would you come up with such a design? If you want the member to be accessible only from within the same package, better make it package-private (default). Making a class 'final' which is having 'protected' members would certainly draw attention as to why would anyone like to do it. You would better need to review the class design in such a case.

When to pick default access control modifier?

'package-private' or the default access control modifier puts you under only one commitment. This is towards all the classes in the same package as they will have access to all your package-private members and hence they can have their implementation dependent on those members.

When to pick 'private' access control modifier?

'private' is something private to your class and hence you have no commitment towards others. You can change them anytime you want as long as it doesn't hurt the functioning of any public/protected/default member.


How to pick access control modifier for fields in Java?

For fields, the thumb rule is quite simple - make all instance fields 'private' and have getters/setters to access/modify them. However, you would probably like to make most of your static fields as 'public' as they are class variables and meant to be accessed from outside either on the class name (preferred way) or on any instance.


Liked the article? Subscribe to this blog for regular updates. Wanna follow it to tell the world that you enjoy GeekExplains? Please find the 'Followers' widget in the rightmost sidebar.



Share/Save/Bookmark


2 comments:

Ranvijay said...

hi,geek
such a nice article it is(access control)
i have a problem.i want to open a excel file in place of any jsp for
user inputs and put them back to my action class.(i am using struts) it require some kind of form submit functionality i guess.

plz help me

Geek said...

Opening an Excel sheet in place of a JSP is quite plain and simple I believe (any problem here?). But, getting the data entered in the sheet back to your application might require you to do some VBA coding - maybe you can have a button, which on click can call a Web Service which will send the data back to your middle-tier. If your application requires, you can probably send some response (maybe some text message having some ID, etc... in case the data submitted was for a registration kinda stuff).

Does this make sense? Otherwise email me your actual problem in some more detail and then I might be of some help. Thanks for your visit. Keep posting!