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 Keywords (Part XIII): Import Keyword and the Concept of Java Packages

We are up to 36 keywords covered in previous articles! That's 75% keywords covered. We have only 12 keywords to cover and I will be covering 2 of those in this article. I am so excited about getting to nearly the end of the series. As I mentioned before, knowing the Java keywords and being able to explain their usage correctly, is something that you will most likely need in an entry level Java programmer job interview. If this ever helps one of you, I would love to hear from you! This article will illustrate the use of the keywords import and package. This is going to be a very short article. I promise. I suggest you start with Java Keywords (Part I) before proceeding further, if you have not read any of the previous articles in the Java Keyword series. Also, go back and read the one about Data Types. All of these articles are from September 2018. That should help you find them quickly. You can also use the "search" option at the top of this page. The series was written with natural progression in mind. Therefore, some of the keywords already covered may be used in code examples illustrated here.

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.

Packages

The purpose of the keyword package, is to define the namespace for the classes contained in it.

The simplest way to think of a package is as a folder; mainly because it is indeed a folder. We use folders primarily to keep things organized in a logical way. Most computer Operating Systems offer a series of folders out of the box, to help us stayed organized: Photos, Videos, Music, Documents, Desktop. When we want to store photos, it makes sense to store them in the "Photos" folder. We can also create our own subfolders to further organize the contents of a folder. For instance, you may want to store last year's vacation photos in "Vacation 2019" insde the Photos folder. Likewise, we can use packages and sub-packages to compartmentalize our classes in groups that make some logical sense. This partitioning provides a namespace for our classes. Namespaces help with avoiding collisions with other classes that may have the same name; just like you cannot have two files with the same name in the same folder. So, if you need to tell the operating system that you need a certain file, providing the full path and name of the file guarantees that you will get precisely the file you need. In Java, the combination of the package (path) and class name is known as the Canonical Name. For more information on packages, please visit my article on this very topic.

Package view in Eclipse
Going back to the original point, defining a namespace means that classes inside a package have a specific definition that is different than classes with similar name elsewhere. Suppose you have two table classes: package1.Table and package2.Table. Even if these classes do the exact same work, you have to assume they are different from one another for the simple fact that they are defined in different packages. Therefore, instances of one "Table" class are not necessarily compatible with instances of the other "Table" class. More about this "conflict" on the Importing Classes section.

Another benefit of packages, is that serves as a way to encapsulate features of a program or library. For example, there might be classes inside a package that may not be suitable for direct access by external entities. Thefore, declaring these classes with default access modification (see Part I of this series for a refresher) "hides" these classes from the outside. This information hiding helps in keeping your API simpler, by only making visible those classes suitable for external access.

Importing classes

Importing classes mean that you want to bring in (use) functionality that exist in another namespace without having to use the canonical name of a class (or fully qualified name). Obviously, if two classes share the same name that are used in a single class file, you have no choice but to resolve at least one with its fully qualified name. In the previous example of "Table" classes in two different packages:

package package3;

import package1.Table;

public class MyApp {
	
	public static void main (String[] args) {
		Table t1 = new Table();
		package2.Table t2 = new package2.Table();
	}
}

When you import, it is considered a good practice to import only the classes you need from any given package. However, Java supports the use of the asterisk symbol (*) to import all classes inside the named package. It will not import classes in subpackages. In the example above, you cannot import two classes with the same name, even if they are defined in different packages. On the surface, this might not make sense to you. But, if you really think about it, this is necessary because you won't be able to differentiate in the body of a class one type of object from the other. Consider this example:

package package3;

import package1.Table;
import package2.Table; // This import will cause a compiling error

public class MyApp {
	
	public static void main (String[] args) {
		Table t1 = new Table();
		Table t2 = new Table();
	}
}
How will the program know which "Table" class you want to use for objects t1 and t2? If you think you can get around this issue by using import all wildcard on one of the import statements, the code will assume that you want to use the class type that is explicitly declared. If you use the wildcard on both import statements, both t1 and t2 declarations will result in a compiling error until one is explicitly imported and the other one declared with its fully qualified name, just like in the orgininal code snippet.

You may be asking yourself "when do I need to "import"? You need to import classes when they reside outside the declaring class (namespace) package.

Notice on the image above how the IDE is indicating an error with the use of the "MyClass" class. This is because "MyClass" and "MyOtherClass" exist in two different packages. Therefore, if not using "MyOtherClass" fully qualified (canonical) name, I must include an import statement to use it.

/*
 * Programming Corner
 * Professor Fontanez
 * www.professorfontanez.com
 * May 9, 2020: 10:58:09 AM
 */
package package1.subpackage;

import package1.*; // import all classes in package1 (assume MyClass resides in that package)

public class MyOtherClass {
 
 public MyClass myAttrib;
}
An exception to the rule mentioned above, classes from the Java library that reside inside the java.lang package do not need to be imported. The JVM import those classes for you. These classes are essential to the Java language, and by extension, to all programs; being the most noticeable the Object and String classes.

Next up, Part XIV: Using instanceof Operator

Comments

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