Skip to main content

Java Keywords (Part XXIV): native

Java keyword list abstract continue for new switch assert default goto * package synchronized boolean do if private this break double implements protected throw byte else import public throws case enum instanceof return transient catch extends int short try char final interface static void class finally long strictfp volatile const * float native super while Keyword marked with an asterisk (*) are keywords that, although valid, are not used by programmers. This is the last chapter of the Java Keyword series. This is probably the keyword I have used the least. In my 20 year career as a software developer, I have used this keyword once, and that was to make some addition to legacy code. The keyword native is a method modifier . Basically, it is a keyword that can only be applied to methods. According to the Java Language Specification (JLS), A method that is native is implemented i...

Java Packages

I was watching a video today where this topic was brought up and I was kind of surprised at how some people categorize the importance of packages in Java. I will go over two main reasons why packages are important. Before I got into details, let start by enumerating the two reasons I am discussing in this blog. The first, and most common reason, is for organization purposes. I am sure you have heard this many times. The second reason, and the one I believe is badly overlooked, is protection to restrict access to your classes and features.

Use packages to organize your classes and features

The first point you should know about packages is that packages are basically the folders where your classes reside. This concept should not be foreign to anyone. If you have used a computer at least once in your life, you should already be aware why folders are helpful in keeping your files organized.

If you are like me, you love to create folders to keep your files organized and to quickly navigate to the files you are looking for. So, in your computer you might find folders named "Pictures" or "My Documents" or even sub-folders like "Resumes" or "Camping Trip 2017". People do this to create a logical separation of files. Like folders in your Operating System, Java packages allow you to create logical compartments for your classes and the features they provide. This benefit really needs little to no explanation.

You should also know that, like naming of folders and directory structures, there is not really a strict rule when it comes to package creation. In theory, you can have as many packages and sub-packages as your system will allow. Unlike folders, there are stricter naming conventions imposed by the Java language. For instance, a package name cannot start with a number; even though packages are basically folders. There are, however, a number of industry-wide best practices when it comes to package names and structure. You can search the web for this topic and you will find a variety of suggestions. My personal preference is to break down your packages by features and sub-features. In my opinion, this is the most commonly accepted practice. At the end of the day, your organization or team (or even you) will decide what makes the most sense for what you are doing. That said, you should consider sticking with widely adopted practices. Why? Consider the directory structures of Operating Systems such as Windows. If I was to ask any Windows user what folder contains the installed programs on a PC or laptop, they will answer "Program Files" or "Program Files (x86)" without hesitation. Likewise, adopting a widely used convention will allow any person outside your project to have an idea where to go to access certain functions of your system. To summarize, commonly used package naming and structure helps keeping your code organized in a way that does not require intimate knowledge of the system in order to quickly find the desired set of classes and features.

Use packages to restrict access to your classes and features

This is, to me, the most important reason why to use packages. However, placing classes in packages alone does not provide any access restriction to the classes and features in a package. In order for such protection to be turned on, it must be used in conjunction with Java's default access modifier (no access modifier in the class or method declaration). The default access modifier in Java is also known as "package private." This means that a class, method, or data member with this level of protection is only visible internally to the other members of that package. There are some who believe that Java got it wrong by now allowing sub-packages to also be allowed access. I am not going to debate that point on this blog because it will be pointless because I sometimes feel that way and sometimes I do not. But, what it important is for me to explain to you why using packages in conjunction with the default access modifier is important.

Consider your typical ATM system. An ATM, from the external user perspective, has a very simple interface. When a card is inserted and the correct Personal Identification Number is provided, the user is presented a limited set of features. Typically, these features are limited to withdrawal, transfer funds, deposit, check balance, and exit. Each of these main menu functions have a strict workflow. For example, if the user select to withdraw money, most likely the user must provide first the type of account to withdraw from (for example savings or checking account) and then the amount. Assuming there are funds available, money is dispensed and eventually the transaction is over. But, is the process really that simple? We all know the answer is no.

In an ATM system, it is likely that there are dozens or even hundreds of functions that are not accessible by the user because are only meant to be for internal system use. For example, when the card is inserted in the card reader, the magnetic strip or chip is read, and this information is stored somewhere. Then, the user provides his or her Personal Identification Number which is used in conjunction with with the card information to authenticate the user. The user authentication process requires for a synchronous transaction to occur where the information is sent to the bank. Once the bank receives the information it validates the user and the validation message is sent back to the ATM. Again, when the type of account is selected and and amount, this information is again sent to the bank for verification of funds. Once the bank confirms that funds are available, the processor inside the ATM machine messages the vault to dispense the entered amount (which requires the mechanization of a lot of mechanical parts). The point is that the user does not have access to any of these functions nor the user cares to have access to them. Therefore, what would be the point of making these accessible the user? Imagine how complicated and error prone would be the process of getting money from an ATM if that was the case.

For the sake of the user, it is best to provide the user with the bare minimum set of features that he or she will need to do the job required. Following the ATM example, the only public methods required are "enter personal identification number", "withdrawal", "transfer funds", "deposit", "check balance", and "cancel transaction". There are other functions needed for navigation like "main menu", "back", and maybe "forward". Since functions like "authenticate user" and "check funds availability" should be made package private to restrict access. Likewise, any classes and data members that are not needed by the user should also be made package private.

Lastly, there could be good reasons to apply similar restrictions internally within the system. Listing examples to illustrate this point is not important. What is important is that just like you would want for the public Application Interface (API) to be as simple as possible, you would also want your internal API to be as simple as possible. To conclude, I will use a real life example where I took advantage of this approach. Many years ago, I was given the task of adding a status bar for an application. There was a status bar already in use in certain windows within the application. When I examined the code with hopes of reusing existing functionality, I found it to be incomprehensible. So, I decided to create my own status bar. Once I was done, I generated Javadoc for the status bar "widget" I created. The API consisted of something like 6 public methods or less. I created a new package called "widgets.statusbar" with many other sub-packages inside. The new status bar was so simple to use that anyone could have gone to the Javadoc or even the code itself and figure out how to use it and customize it as needed. Restricted visibility from outside the package made my widget more reusable than the alternative.

Comments

  1. Really show how important package is, especially when working with others. I'm curious on the sub-package debate, that the default access modifier doesn't grant access to the sub-package. Is it because protected or public already grant access to the sub-package, and thus default has no need to do so? Or that private is already restricted enough that default is not needed?

    ReplyDelete
    Replies
    1. Let me first apologize for taking so long to reply. I hope you have the answer to this question already. But, if not, I hope my explanation helps clarify why this is the case. While packages can be seen as simply folders, they are certainly much more than that. Packages provide a namespace for the classes it contains. So, if you were to allow for default access modification to subfolders, then you will have to ensure that subpackages cannot contain duplicate names. That provision violates how operating systems manage files and folders. There are other complications, but this is the one, in my opinion, the main one.

      Delete

Post a Comment

Popular posts from this blog

Implementing Interfaces with Java Records

If you have not read my article on Java records and do not know about this topic, please read my blog titled " Customizing Java Records " first and then come back to this one. Now that you know how to customize Java records, implementing an interface using Java records should be very easy to understand. If you don't know about interfaces in Java, you can read more on my article about interfaces. The recipe for implementing an interface is simply an expansion of what you learned in my previous blog on how to customize a Java record. Following our Rectangle example, let's create an interface with the same two methods we used before. public interface Shape { double area(); double perimeter(); } Now, let's further customize the previous example by doing two things: Add implements Shape at the end of the record declaration (after the record constructor), and Add @Override to the existing methods to ensure these methods com...

Customizing Java Records

If you have not read my article on Java records and do not know about this topic, please read my blog titled " Java Keywords Addendum: The Java Record " first and then come back to this one. What is a customization of a record? A customization of a record is simply the addition of code inside the body of the class. Before proceeding further, let's recap important aspects of a Java Record: Java records are immutable Because of item 1 above, you cannot add new fields unless defined in the record constructor Java records already override: Object#equals(Object) and Object#hashCode() , and then override Object#toString() You could redefine overridden methods as part of your customization if you would like. For example, if you want a fancier implementation of the Object#toString() method, you could do so. Let's look at our first customization example. Using the example from my previous blog, public record Student(...

Object-Oriented Programming Basics: What is in a Class?

EDITORIAL NOTE : This article was published briefly back in 2016 and quickly set back to draft because I wasn't happy with its contents. It is a shame that it was taking me three years to revisit this topic and work on a new and improved version. At least, I'm hoping it will be to the liking you the reader. Keep in mind that the opening paragraph will still read as if I just wrote it for my (former) students at Texas Wesleyan. I started working on lecture on the topic of Object-Oriented (OO) Programming by gathering some material, old and new, when I realized this might be good and simple post for my second attempt at blogging. To be completely honest, in the 8 hours I spent collecting information and preparing material for this week's lecture, I realized I still made some of the mistakes I am about to blog about. I am actually hoping I can write a series of postings regarding Object-Oriented Programming (OOP). But to do so, I must start from the very beginning. ...